From 34b1ef04fc050d171e055f75d6a3384e1323bd38 Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Wed, 1 Jun 2011 00:33:22 +0000 Subject: be2net: Fallback to the older opcode if MCC_CREATE_EXT opcode is not supported on the card Instead of failing the init/probe code in the driver fallback to the older opcode to ensure the driver is loaded thereby enabling users to upgrade the f/w to whatever version is required. Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 65 +++++++++++++++++++++++++++++++++++++++++++-- drivers/net/benet/be_cmds.h | 8 ++++++ drivers/net/benet/be_main.c | 5 ++++ 3 files changed, 76 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 81654ae16c6..0c12c2d4532 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -799,12 +799,12 @@ static u32 be_encoded_q_len(int q_len) return len_encoded; } -int be_cmd_mccq_create(struct be_adapter *adapter, +int be_cmd_mccq_ext_create(struct be_adapter *adapter, struct be_queue_info *mccq, struct be_queue_info *cq) { struct be_mcc_wrb *wrb; - struct be_cmd_req_mcc_create *req; + struct be_cmd_req_mcc_ext_create *req; struct be_dma_mem *q_mem = &mccq->dma_mem; void *ctxt; int status; @@ -859,6 +859,67 @@ int be_cmd_mccq_create(struct be_adapter *adapter, return status; } +int be_cmd_mccq_org_create(struct be_adapter *adapter, + struct be_queue_info *mccq, + struct be_queue_info *cq) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_mcc_create *req; + struct be_dma_mem *q_mem = &mccq->dma_mem; + void *ctxt; + int status; + + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); + ctxt = &req->context; + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_COMMON_MCC_CREATE); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_MCC_CREATE, sizeof(*req)); + + req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); + + AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt, + be_encoded_q_len(mccq->len)); + AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id); + + be_dws_cpu_to_le(ctxt, sizeof(req->context)); + + be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); + + status = be_mbox_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb); + mccq->id = le16_to_cpu(resp->id); + mccq->created = true; + } + + mutex_unlock(&adapter->mbox_lock); + return status; +} + +int be_cmd_mccq_create(struct be_adapter *adapter, + struct be_queue_info *mccq, + struct be_queue_info *cq) +{ + int status; + + status = be_cmd_mccq_ext_create(adapter, mccq, cq); + if (status && !lancer_chip(adapter)) { + dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 " + "or newer to avoid conflicting priorities between NIC " + "and FCoE traffic"); + status = be_cmd_mccq_org_create(adapter, mccq, cq); + } + return status; +} + int be_cmd_txq_create(struct be_adapter *adapter, struct be_queue_info *txq, struct be_queue_info *cq) diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 8148cc66cbe..d08289e21f6 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -431,6 +431,14 @@ struct amap_mcc_context_lancer { } __packed; struct be_cmd_req_mcc_create { + struct be_cmd_req_hdr hdr; + u16 num_pages; + u16 cq_id; + u8 context[sizeof(struct amap_mcc_context_be) / 8]; + struct phys_addr pages[8]; +} __packed; + +struct be_cmd_req_mcc_ext_create { struct be_cmd_req_hdr hdr; u16 num_pages; u16 cq_id; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a485f7fdaf3..5824c95c784 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -3396,6 +3396,11 @@ static int __devinit be_probe(struct pci_dev *pdev, } dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); + /* By default all priorities are enabled. + * Needed in case of no GRP5 evt support + */ + adapter->vlan_prio_bmap = 0xff; + schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); return 0; -- cgit v1.2.3-70-g09d2 From aa63418aa72e4468838eea457a123057b1c7cd11 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:35 +0200 Subject: b43: rename ssb_device variable in ssb specific functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index eb415968698..1e81a0d6f54 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4982,26 +4982,27 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev) return wl; } -static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) +static +int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) { struct b43_wl *wl; int err; int first = 0; - wl = ssb_get_devtypedata(dev); + wl = ssb_get_devtypedata(sdev); if (!wl) { /* Probing the first core. Must setup common struct b43_wl */ first = 1; - b43_sprom_fixup(dev->bus); - wl = b43_wireless_init(dev); + b43_sprom_fixup(sdev->bus); + wl = b43_wireless_init(sdev); if (IS_ERR(wl)) { err = PTR_ERR(wl); goto out; } - ssb_set_devtypedata(dev, wl); - B43_WARN_ON(ssb_get_devtypedata(dev) != wl); + ssb_set_devtypedata(sdev, wl); + B43_WARN_ON(ssb_get_devtypedata(sdev) != wl); } - err = b43_one_core_attach(dev, wl); + err = b43_one_core_attach(sdev, wl); if (err) goto err_wireless_exit; @@ -5016,17 +5017,17 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) return err; err_one_core_detach: - b43_one_core_detach(dev); + b43_one_core_detach(sdev); err_wireless_exit: if (first) - b43_wireless_exit(dev, wl); + b43_wireless_exit(sdev, wl); return err; } -static void b43_ssb_remove(struct ssb_device *dev) +static void b43_ssb_remove(struct ssb_device *sdev) { - struct b43_wl *wl = ssb_get_devtypedata(dev); - struct b43_wldev *wldev = ssb_get_drvdata(dev); + struct b43_wl *wl = ssb_get_devtypedata(sdev); + struct b43_wldev *wldev = ssb_get_drvdata(sdev); /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ @@ -5042,14 +5043,14 @@ static void b43_ssb_remove(struct ssb_device *dev) ieee80211_unregister_hw(wl->hw); } - b43_one_core_detach(dev); + b43_one_core_detach(sdev); if (list_empty(&wl->devlist)) { b43_leds_unregister(wl); /* Last core on the chip unregistered. * We can destroy common struct b43_wl. */ - b43_wireless_exit(dev, wl); + b43_wireless_exit(sdev, wl); } } -- cgit v1.2.3-70-g09d2 From 482f05386218a028309a71ad36066ee64b7a820d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:36 +0200 Subject: b43: add bus device abstraction layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/b43.h | 4 +++- drivers/net/wireless/b43/bus.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/bus.h | 17 +++++++++++++++++ drivers/net/wireless/b43/main.c | 30 +++++++++++++++++------------- 5 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 drivers/net/wireless/b43/bus.c create mode 100644 drivers/net/wireless/b43/bus.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index cef334a8c66..95f7c001fda 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -1,4 +1,5 @@ b43-y += main.o +b43-y += bus.o b43-y += tables.o b43-$(CONFIG_B43_PHY_N) += tables_nphy.o b43-$(CONFIG_B43_PHY_N) += radio_2055.o diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 25a78cfb7d1..bb81ebcf512 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -11,6 +11,7 @@ #include "debugfs.h" #include "leds.h" #include "rfkill.h" +#include "bus.h" #include "lo.h" #include "phy_common.h" @@ -707,7 +708,8 @@ enum { /* Data structure for one wireless device (802.11 core) */ struct b43_wldev { - struct ssb_device *sdev; + struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */ + struct b43_bus_dev *dev; struct b43_wl *wl; /* The device initialization status. diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c new file mode 100644 index 00000000000..f8ccd2cea3f --- /dev/null +++ b/drivers/net/wireless/b43/bus.c @@ -0,0 +1,36 @@ +/* + + Broadcom B43 wireless driver + Bus abstraction layer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "bus.h" + + +/* SSB */ +struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) +{ + struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + + dev->bus_type = B43_BUS_SSB; + dev->sdev = sdev; + + return dev; +} diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h new file mode 100644 index 00000000000..68bc00a7458 --- /dev/null +++ b/drivers/net/wireless/b43/bus.h @@ -0,0 +1,17 @@ +#ifndef B43_BUS_H_ +#define B43_BUS_H_ + +enum b43_bus_type { + B43_BUS_SSB, +}; + +struct b43_bus_dev { + enum b43_bus_type bus_type; + union { + struct ssb_device *sdev; + }; +}; + +struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); + +#endif /* B43_BUS_H_ */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1e81a0d6f54..6356fbc8aec 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4845,7 +4845,7 @@ err_powerdown: return err; } -static void b43_one_core_detach(struct ssb_device *dev) +static void b43_one_core_detach(struct b43_bus_dev *dev) { struct b43_wldev *wldev; struct b43_wl *wl; @@ -4853,17 +4853,17 @@ static void b43_one_core_detach(struct ssb_device *dev) /* Do not cancel ieee80211-workqueue based work here. * See comment in b43_remove(). */ - wldev = ssb_get_drvdata(dev); + wldev = ssb_get_drvdata(dev->sdev); wl = wldev->wl; b43_debugfs_remove_device(wldev); b43_wireless_core_detach(wldev); list_del(&wldev->list); wl->nr_devs--; - ssb_set_drvdata(dev, NULL); + ssb_set_drvdata(dev->sdev, NULL); kfree(wldev); } -static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) +static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl) { struct b43_wldev *wldev; int err = -ENOMEM; @@ -4873,7 +4873,8 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) goto out; wldev->use_pio = b43_modparam_pio; - wldev->sdev = dev; + wldev->dev = dev; + wldev->sdev = dev->sdev; /* TODO: Remove when not needed */ wldev->wl = wl; b43_set_status(wldev, B43_STAT_UNINIT); wldev->bad_frames_preempt = modparam_bad_frames_preempt; @@ -4885,7 +4886,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) list_add(&wldev->list, &wl->devlist); wl->nr_devs++; - ssb_set_drvdata(dev, wldev); + ssb_set_drvdata(dev->sdev, wldev); b43_debugfs_add_device(wldev); out: @@ -4926,11 +4927,11 @@ static void b43_sprom_fixup(struct ssb_bus *bus) } } -static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) +static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl) { struct ieee80211_hw *hw = wl->hw; - ssb_set_devtypedata(dev, NULL); + ssb_set_devtypedata(dev->sdev, NULL); ieee80211_free_hw(hw); } @@ -4985,10 +4986,13 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev) static int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) { + struct b43_bus_dev *dev; struct b43_wl *wl; int err; int first = 0; + dev = b43_bus_dev_ssb_init(sdev); + wl = ssb_get_devtypedata(sdev); if (!wl) { /* Probing the first core. Must setup common struct b43_wl */ @@ -5002,7 +5006,7 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) ssb_set_devtypedata(sdev, wl); B43_WARN_ON(ssb_get_devtypedata(sdev) != wl); } - err = b43_one_core_attach(sdev, wl); + err = b43_one_core_attach(dev, wl); if (err) goto err_wireless_exit; @@ -5017,10 +5021,10 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) return err; err_one_core_detach: - b43_one_core_detach(sdev); + b43_one_core_detach(dev); err_wireless_exit: if (first) - b43_wireless_exit(sdev, wl); + b43_wireless_exit(dev, wl); return err; } @@ -5043,14 +5047,14 @@ static void b43_ssb_remove(struct ssb_device *sdev) ieee80211_unregister_hw(wl->hw); } - b43_one_core_detach(sdev); + b43_one_core_detach(wldev->dev); if (list_empty(&wl->devlist)) { b43_leds_unregister(wl); /* Last core on the chip unregistered. * We can destroy common struct b43_wl. */ - b43_wireless_exit(sdev, wl); + b43_wireless_exit(wldev->dev, wl); } } -- cgit v1.2.3-70-g09d2 From c0b4c00907c7f611ef328de73967d7913e137df8 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:37 +0200 Subject: b43: bus: abstract R/W operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 12 ++++++------ drivers/net/wireless/b43/bus.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/bus.h | 9 +++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index bb81ebcf512..3378d93cc33 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -883,34 +883,34 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) { - return ssb_read16(dev->sdev, offset); + return dev->dev->read16(dev->dev, offset); } static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) { - ssb_write16(dev->sdev, offset, value); + dev->dev->write16(dev->dev, offset, value); } static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) { - return ssb_read32(dev->sdev, offset); + return dev->dev->read32(dev->dev, offset); } static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) { - ssb_write32(dev->sdev, offset, value); + dev->dev->write32(dev->dev, offset, value); } static inline void b43_block_read(struct b43_wldev *dev, void *buffer, size_t count, u16 offset, u8 reg_width) { - ssb_block_read(dev->sdev, buffer, count, offset, reg_width); + dev->dev->block_read(dev->dev, buffer, count, offset, reg_width); } static inline void b43_block_write(struct b43_wldev *dev, const void *buffer, size_t count, u16 offset, u8 reg_width) { - ssb_block_write(dev->sdev, buffer, count, offset, reg_width); + dev->dev->block_write(dev->dev, buffer, count, offset, reg_width); } static inline bool b43_using_pio_transfers(struct b43_wldev *dev) diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index f8ccd2cea3f..fe5fa267bc5 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -25,6 +25,37 @@ /* SSB */ +static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset) +{ + return ssb_read16(dev->sdev, offset); +} +static inline u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset) +{ + return ssb_read32(dev->sdev, offset); +} +static inline +void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value) +{ + ssb_write16(dev->sdev, offset, value); +} +static inline +void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value) +{ + ssb_write32(dev->sdev, offset, value); +} +static inline +void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + ssb_block_read(dev->sdev, buffer, count, offset, reg_width); +} +static inline +void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + ssb_block_write(dev->sdev, buffer, count, offset, reg_width); +} + struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) { struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); @@ -32,5 +63,12 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->bus_type = B43_BUS_SSB; dev->sdev = sdev; + dev->read16 = b43_bus_ssb_read16; + dev->read32 = b43_bus_ssb_read32; + dev->write16 = b43_bus_ssb_write16; + dev->write32 = b43_bus_ssb_write32; + dev->block_read = b43_bus_ssb_block_read; + dev->block_write = b43_bus_ssb_block_write; + return dev; } diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index 68bc00a7458..9b390020fb5 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -10,6 +10,15 @@ struct b43_bus_dev { union { struct ssb_device *sdev; }; + + u16 (*read16)(struct b43_bus_dev *dev, u16 offset); + u32 (*read32)(struct b43_bus_dev *dev, u16 offset); + void (*write16)(struct b43_bus_dev *dev, u16 offset, u16 value); + void (*write32)(struct b43_bus_dev *dev, u16 offset, u32 value); + void (*block_read)(struct b43_bus_dev *dev, void *buffer, + size_t count, u16 offset, u8 reg_width); + void (*block_write)(struct b43_bus_dev *dev, const void *buffer, + size_t count, u16 offset, u8 reg_width); }; struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); -- cgit v1.2.3-70-g09d2 From 21d889d433eb962b70ad88d554a4a7658067596f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:38 +0200 Subject: b43: bus: abstract 80211 core info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 3 +++ drivers/net/wireless/b43/bus.h | 3 +++ drivers/net/wireless/b43/dma.c | 2 +- drivers/net/wireless/b43/main.c | 30 +++++++++++++++--------------- drivers/net/wireless/b43/phy_common.c | 4 ++-- drivers/net/wireless/b43/phy_n.c | 4 ++-- drivers/net/wireless/b43/pio.c | 10 +++++----- 7 files changed, 31 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index fe5fa267bc5..be3d206e356 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -70,5 +70,8 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->block_read = b43_bus_ssb_block_read; dev->block_write = b43_bus_ssb_block_write; + dev->core_id = sdev->id.coreid; + dev->core_rev = sdev->id.revision; + return dev; } diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index 9b390020fb5..742f0844194 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -19,6 +19,9 @@ struct b43_bus_dev { size_t count, u16 offset, u8 reg_width); void (*block_write)(struct b43_bus_dev *dev, const void *buffer, size_t count, u16 offset, u8 reg_width); + + u16 core_id; + u8 core_rev; }; struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 47d44bcff37..ee45ab9af23 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1085,7 +1085,7 @@ int b43_dma_init(struct b43_wldev *dev) goto err_destroy_mcast; /* No support for the TX status DMA ring. */ - B43_WARN_ON(dev->sdev->id.revision < 5); + B43_WARN_ON(dev->dev->core_rev < 5); b43dbg(dev->wl, "%u-bit DMA initialized\n", (unsigned int)type); diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6356fbc8aec..971ec1b56b0 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -548,7 +548,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) { u32 low, high; - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); /* The hardware guarantees us an atomic read, if we * read the low register first. */ @@ -586,7 +586,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) { u32 low, high; - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); low = tsf; high = (tsf >> 32); @@ -714,7 +714,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) b43_ram_write(dev, i * 4, buffer[i]); b43_write16(dev, 0x0568, 0x0000); - if (dev->sdev->id.revision < 11) + if (dev->dev->core_rev < 11) b43_write16(dev, 0x07C0, 0x0000); else b43_write16(dev, 0x07C0, 0x0100); @@ -1132,7 +1132,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) b43_write32(dev, B43_MMIO_MACCTL, macctl); /* Commit write */ b43_read32(dev, B43_MMIO_MACCTL); - if (awake && dev->sdev->id.revision >= 5) { + if (awake && dev->dev->core_rev >= 5) { /* Wait for the microcode to wake up. */ for (i = 0; i < 100; i++) { ucstat = b43_shm_read16(dev, B43_SHM_SHARED, @@ -1221,7 +1221,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev) { u32 dummy; - if (dev->sdev->id.revision < 5) + if (dev->dev->core_rev < 5) return; /* Read all entries from the microcode TXstatus FIFO * and throw them away. @@ -1689,7 +1689,7 @@ static void b43_update_templates(struct b43_wl *wl) static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) { b43_time_lock(dev); - if (dev->sdev->id.revision >= 3) { + if (dev->dev->core_rev >= 3) { b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); } else { @@ -2113,7 +2113,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) { struct b43_wldev *dev = ctx->dev; struct b43_firmware *fw = &ctx->dev->fw; - const u8 rev = ctx->dev->sdev->id.revision; + const u8 rev = ctx->dev->dev->core_rev; const char *filename; u32 tmshigh; int err; @@ -2448,7 +2448,7 @@ static int b43_upload_microcode(struct b43_wldev *dev) snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", dev->fw.rev, dev->fw.patch); - wiphy->hw_version = dev->sdev->id.coreid; + wiphy->hw_version = dev->dev->core_id; if (b43_is_old_txhdr_format(dev)) { /* We're over the deadline, but we keep support for old fw @@ -2606,7 +2606,7 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0200; set |= 0x0200; } - if (dev->sdev->id.revision >= 2) + if (dev->dev->core_rev >= 2) mask |= 0x0010; /* FIXME: This is redundant. */ gpiodev = b43_ssb_gpio_dev(dev); @@ -2741,7 +2741,7 @@ static void b43_adjust_opmode(struct b43_wldev *dev) /* Workaround: On old hardware the HW-MAC-address-filter * doesn't work properly, so always run promisc in filter * it in software. */ - if (dev->sdev->id.revision <= 4) + if (dev->dev->core_rev <= 4) ctl |= B43_MACCTL_PROMISC; b43_write32(dev, B43_MMIO_MACCTL, ctl); @@ -2907,7 +2907,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write16(dev, 0x005E, value16); } b43_write32(dev, 0x0100, 0x01000000); - if (dev->sdev->id.revision < 5) + if (dev->dev->core_rev < 5) b43_write32(dev, 0x010C, 0x01000000); b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) @@ -2922,7 +2922,7 @@ static int b43_chip_init(struct b43_wldev *dev) /* Initially set the wireless operation mode. */ b43_adjust_opmode(dev); - if (dev->sdev->id.revision < 3) { + if (dev->dev->core_rev < 3) { b43_write16(dev, 0x060E, 0x0000); b43_write16(dev, 0x0610, 0x8000); b43_write16(dev, 0x0604, 0x0000); @@ -3105,7 +3105,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev) b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); - if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) { + if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) { /* The 32bit register shadows the two 16bit registers * with update sideeffects. Validate this. */ b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); @@ -4352,7 +4352,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) if (err) goto err_busdown; b43_shm_write16(dev, B43_SHM_SHARED, - B43_SHM_SH_WLCOREREV, dev->sdev->id.revision); + B43_SHM_SH_WLCOREREV, dev->dev->core_rev); hf = b43_hf_read(dev); if (phy->type == B43_PHYTYPE_G) { hf |= B43_HF_SYMW; @@ -4756,7 +4756,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) goto out; } /* Get the PHY type. */ - if (dev->sdev->id.revision >= 5) { + if (dev->dev->core_rev >= 5) { u32 tmshigh; tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index e46b2f4f092..3f7bdf84544 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -168,7 +168,7 @@ void b43_phy_lock(struct b43_wldev *dev) B43_WARN_ON(dev->phy.phy_locked); dev->phy.phy_locked = 1; #endif - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); @@ -180,7 +180,7 @@ void b43_phy_unlock(struct b43_wldev *dev) B43_WARN_ON(!dev->phy.phy_locked); dev->phy.phy_locked = 0; #endif - B43_WARN_ON(dev->sdev->id.revision < 3); + B43_WARN_ON(dev->dev->core_rev < 3); if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) b43_power_saving_ctl_bits(dev, 0); diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 05960ddde24..e395550222d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -983,7 +983,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) { u16 tmp; - if (dev->sdev->id.revision == 16) + if (dev->dev->core_rev == 16) b43_mac_suspend(dev); tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); @@ -993,7 +993,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) tmp |= (val & mask); b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); - if (dev->sdev->id.revision == 16) + if (dev->dev->core_rev == 16) b43_mac_enable(dev); return tmp; diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 72ab94df756..44da620d9cc 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c @@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, B43_MMIO_PIO11_BASE5, }; - if (dev->sdev->id.revision >= 11) { + if (dev->dev->core_rev >= 11) { B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); return bases_rev11[index]; } @@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, static u16 pio_txqueue_offset(struct b43_wldev *dev) { - if (dev->sdev->id.revision >= 11) + if (dev->dev->core_rev >= 11) return 0x18; return 0; } static u16 pio_rxqueue_offset(struct b43_wldev *dev) { - if (dev->sdev->id.revision >= 11) + if (dev->dev->core_rev >= 11) return 0x38; return 8; } @@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev, if (!q) return NULL; q->dev = dev; - q->rev = dev->sdev->id.revision; + q->rev = dev->dev->core_rev; q->mmio_base = index_to_pioqueue_base(dev, index) + pio_txqueue_offset(dev); q->index = index; @@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev, if (!q) return NULL; q->dev = dev; - q->rev = dev->sdev->id.revision; + q->rev = dev->dev->core_rev; q->mmio_base = index_to_pioqueue_base(dev, index) + pio_rxqueue_offset(dev); -- cgit v1.2.3-70-g09d2 From 0581483afe1a6f90f828b36111b05a70c162137d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:39 +0200 Subject: b43: bus: abstract SPROM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SPROM is another frequently used struct. We decided to share SPROM struct between ssb na bcma as long as we will not need any hacks. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 2 + drivers/net/wireless/b43/bus.h | 2 + drivers/net/wireless/b43/leds.c | 8 +-- drivers/net/wireless/b43/lo.c | 4 +- drivers/net/wireless/b43/main.c | 10 ++-- drivers/net/wireless/b43/phy_a.c | 14 ++--- drivers/net/wireless/b43/phy_g.c | 36 ++++++------- drivers/net/wireless/b43/phy_lp.c | 93 +++++++++++++++++---------------- drivers/net/wireless/b43/phy_n.c | 18 ++++--- drivers/net/wireless/b43/tables_lpphy.c | 12 ++--- drivers/net/wireless/b43/wa.c | 5 +- drivers/net/wireless/b43/xmit.c | 2 +- 12 files changed, 107 insertions(+), 99 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index be3d206e356..c116f123aea 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -70,6 +70,8 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->block_read = b43_bus_ssb_block_read; dev->block_write = b43_bus_ssb_block_write; + dev->bus_sprom = &sdev->bus->sprom; + dev->core_id = sdev->id.coreid; dev->core_rev = sdev->id.revision; diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index 742f0844194..6d575d6c811 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -20,6 +20,8 @@ struct b43_bus_dev { void (*block_write)(struct b43_bus_dev *dev, const void *buffer, size_t count, u16 offset, u8 reg_width); + struct ssb_sprom *bus_sprom; + u16 core_id; u8 core_rev; }; diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 0cafafe368a..26d37ef0108 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -218,10 +218,10 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, struct ssb_bus *bus = dev->sdev->bus; u8 sprom[4]; - sprom[0] = bus->sprom.gpio0; - sprom[1] = bus->sprom.gpio1; - sprom[2] = bus->sprom.gpio2; - sprom[3] = bus->sprom.gpio3; + sprom[0] = dev->dev->bus_sprom->gpio0; + sprom[1] = dev->dev->bus_sprom->gpio1; + sprom[2] = dev->dev->bus_sprom->gpio2; + sprom[3] = dev->dev->bus_sprom->gpio3; if (sprom[led_index] == 0xFF) { /* There is no LED information in the SPROM diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 2ef7d4b3854..b32efd45c08 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c @@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev, rfover |= pga; rfover |= lna; rfover |= trsw_rx; - if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) + if ((dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) && phy->rev > 6) rfover |= B43_PHY_RFOVERVAL_EXTLNA; @@ -387,7 +387,7 @@ struct lo_g_saved_values { static void lo_measure_setup(struct b43_wldev *dev, struct lo_g_saved_values *sav) { - struct ssb_sprom *sprom = &dev->sdev->bus->sprom; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; struct b43_txpower_lo_control *lo = gphy->lo_control; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 971ec1b56b0..0f3a104a0ac 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1427,9 +1427,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev, /* Get the mask of available antennas. */ if (dev->phy.gmode) - antenna_mask = dev->sdev->bus->sprom.ant_available_bg; + antenna_mask = dev->dev->bus_sprom->ant_available_bg; else - antenna_mask = dev->sdev->bus->sprom.ant_available_a; + antenna_mask = dev->dev->bus_sprom->ant_available_a; if (!(antenna_mask & (1 << (antenna_nr - 1)))) { /* This antenna is not available. Fall back to default. */ @@ -2599,7 +2599,7 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0180; set |= 0x0180; } - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) | 0x0200); @@ -4204,7 +4204,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev) static void b43_bluetooth_coext_enable(struct b43_wldev *dev) { - struct ssb_sprom *sprom = &dev->sdev->bus->sprom; + struct ssb_sprom *sprom = dev->dev->bus_sprom; u64 hf; if (!modparam_btcoex) @@ -4318,7 +4318,7 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) static int b43_wireless_core_init(struct b43_wldev *dev) { struct ssb_bus *bus = dev->sdev->bus; - struct ssb_sprom *sprom = &bus->sprom; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; int err; u64 hf; diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index b01c8ced57c..821b516fe9e 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c @@ -311,7 +311,7 @@ void b43_phy_inita(struct b43_wldev *dev) } if ((phy->type == B43_PHYTYPE_G) && - (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { + (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)) { b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); } } @@ -323,17 +323,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev) struct b43_phy_a *aphy = phy->a; s16 pab0, pab1, pab2; - pab0 = (s16) (dev->sdev->bus->sprom.pa1b0); - pab1 = (s16) (dev->sdev->bus->sprom.pa1b1); - pab2 = (s16) (dev->sdev->bus->sprom.pa1b2); + pab0 = (s16) (dev->dev->bus_sprom->pa1b0); + pab1 = (s16) (dev->dev->bus_sprom->pa1b1); + pab2 = (s16) (dev->dev->bus_sprom->pa1b2); if (pab0 != 0 && pab1 != 0 && pab2 != 0 && pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ - if ((s8) dev->sdev->bus->sprom.itssi_a != 0 && - (s8) dev->sdev->bus->sprom.itssi_a != -1) + if ((s8) dev->dev->bus_sprom->itssi_a != 0 && + (s8) dev->dev->bus_sprom->itssi_a != -1) aphy->tgt_idle_tssi = - (s8) (dev->sdev->bus->sprom.itssi_a); + (s8) (dev->dev->bus_sprom->itssi_a); else aphy->tgt_idle_tssi = 62; aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 1758a282f91..ccb02afca62 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev) B43_WARN_ON(phy->type != B43_PHYTYPE_G); if (!phy->gmode || - !(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { + !(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) { tmp16 = b43_nrssi_hw_read(dev, 0x20); if (tmp16 >= 0x20) tmp16 -= 0x40; @@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, { struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_sprom *sprom = dev->dev->bus_sprom; if (!phy->gmode) return 0; @@ -1620,7 +1620,7 @@ static void b43_phy_initb6(struct b43_wldev *dev) b43_radio_write16(dev, 0x5A, 0x88); b43_radio_write16(dev, 0x5B, 0x6B); b43_radio_write16(dev, 0x5C, 0x0F); - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_ALTIQ) { b43_radio_write16(dev, 0x5D, 0xFA); b43_radio_write16(dev, 0x5E, 0xD8); } else { @@ -1787,7 +1787,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) { if (phy->rev >= 7) { b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); @@ -2053,7 +2053,7 @@ static void b43_phy_initg(struct b43_wldev *dev) if (phy->rev >= 6) { b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); } - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); else b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); @@ -2066,7 +2066,7 @@ static void b43_phy_initg(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); } - if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { + if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) { /* The specs state to update the NRSSI LT with * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. @@ -2105,7 +2105,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev, b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); if (channel == 14) { - if (dev->sdev->bus->sprom.country_code == + if (dev->dev->bus_sprom->country_code == SSB_SPROM1CCODE_JAPAN) b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACPR); @@ -2384,9 +2384,9 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) struct b43_phy_g *gphy = phy->g; s16 pab0, pab1, pab2; - pab0 = (s16) (dev->sdev->bus->sprom.pa0b0); - pab1 = (s16) (dev->sdev->bus->sprom.pa0b1); - pab2 = (s16) (dev->sdev->bus->sprom.pa0b2); + pab0 = (s16) (dev->dev->bus_sprom->pa0b0); + pab1 = (s16) (dev->dev->bus_sprom->pa0b1); + pab2 = (s16) (dev->dev->bus_sprom->pa0b2); B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)); /* Not supported anymore */ @@ -2396,10 +2396,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) if (pab0 != 0 && pab1 != 0 && pab2 != 0 && pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ - if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 && - (s8) dev->sdev->bus->sprom.itssi_bg != -1) { + if ((s8) dev->dev->bus_sprom->itssi_bg != 0 && + (s8) dev->dev->bus_sprom->itssi_bg != -1) { gphy->tgt_idle_tssi = - (s8) (dev->sdev->bus->sprom.itssi_bg); + (s8) (dev->dev->bus_sprom->itssi_bg); } else gphy->tgt_idle_tssi = 62; gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, @@ -2840,7 +2840,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev) B43_TXCTL_TXMIX; rfatt += 2; bbatt += 2; - } else if (dev->sdev->bus->sprom. + } else if (dev->dev->bus_sprom-> boardflags_lo & B43_BFL_PACTRL) { bbatt += 4 * (rfatt - 2); @@ -2914,14 +2914,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); B43_WARN_ON(phy->type != B43_PHYTYPE_G); - max_pwr = dev->sdev->bus->sprom.maxpwr_bg; - if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) + max_pwr = dev->dev->bus_sprom->maxpwr_bg; + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) max_pwr -= 3; /* minus 0.75 */ if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { b43warn(dev->wl, "Invalid max-TX-power value in SPROM.\n"); max_pwr = INT_TO_Q52(20); /* fake it */ - dev->sdev->bus->sprom.maxpwr_bg = max_pwr; + dev->dev->bus_sprom->maxpwr_bg = max_pwr; } /* Get desired power (in Q5.2) */ @@ -3014,7 +3014,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; - if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) + if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) return; b43_mac_suspend(dev); diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 012c8da2f94..41d02810d6d 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -85,39 +85,39 @@ static void b43_lpphy_op_free(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */ static void lpphy_read_band_sprom(struct b43_wldev *dev) { + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; u16 cckpo, maxpwr; u32 ofdmpo; int i; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - lpphy->tx_isolation_med_band = bus->sprom.tri2g; - lpphy->bx_arch = bus->sprom.bxa2g; - lpphy->rx_pwr_offset = bus->sprom.rxpo2g; - lpphy->rssi_vf = bus->sprom.rssismf2g; - lpphy->rssi_vc = bus->sprom.rssismc2g; - lpphy->rssi_gs = bus->sprom.rssisav2g; - lpphy->txpa[0] = bus->sprom.pa0b0; - lpphy->txpa[1] = bus->sprom.pa0b1; - lpphy->txpa[2] = bus->sprom.pa0b2; - maxpwr = bus->sprom.maxpwr_bg; + lpphy->tx_isolation_med_band = sprom->tri2g; + lpphy->bx_arch = sprom->bxa2g; + lpphy->rx_pwr_offset = sprom->rxpo2g; + lpphy->rssi_vf = sprom->rssismf2g; + lpphy->rssi_vc = sprom->rssismc2g; + lpphy->rssi_gs = sprom->rssisav2g; + lpphy->txpa[0] = sprom->pa0b0; + lpphy->txpa[1] = sprom->pa0b1; + lpphy->txpa[2] = sprom->pa0b2; + maxpwr = sprom->maxpwr_bg; lpphy->max_tx_pwr_med_band = maxpwr; - cckpo = bus->sprom.cck2gpo; + cckpo = sprom->cck2gpo; /* * We don't read SPROM's opo as specs say. On rev8 SPROMs * opo == ofdm2gpo and we don't know any SSB with LP-PHY * and SPROM rev below 8. */ - B43_WARN_ON(bus->sprom.revision < 8); - ofdmpo = bus->sprom.ofdm2gpo; + B43_WARN_ON(sprom->revision < 8); + ofdmpo = sprom->ofdm2gpo; if (cckpo) { for (i = 0; i < 4; i++) { lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; ofdmpo >>= 4; } - ofdmpo = bus->sprom.ofdm2gpo; + ofdmpo = sprom->ofdm2gpo; for (i = 4; i < 15; i++) { lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; @@ -131,39 +131,39 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev) lpphy->tx_max_rate[i] = maxpwr - ofdmpo; } } else { /* 5GHz */ - lpphy->tx_isolation_low_band = bus->sprom.tri5gl; - lpphy->tx_isolation_med_band = bus->sprom.tri5g; - lpphy->tx_isolation_hi_band = bus->sprom.tri5gh; - lpphy->bx_arch = bus->sprom.bxa5g; - lpphy->rx_pwr_offset = bus->sprom.rxpo5g; - lpphy->rssi_vf = bus->sprom.rssismf5g; - lpphy->rssi_vc = bus->sprom.rssismc5g; - lpphy->rssi_gs = bus->sprom.rssisav5g; - lpphy->txpa[0] = bus->sprom.pa1b0; - lpphy->txpa[1] = bus->sprom.pa1b1; - lpphy->txpa[2] = bus->sprom.pa1b2; - lpphy->txpal[0] = bus->sprom.pa1lob0; - lpphy->txpal[1] = bus->sprom.pa1lob1; - lpphy->txpal[2] = bus->sprom.pa1lob2; - lpphy->txpah[0] = bus->sprom.pa1hib0; - lpphy->txpah[1] = bus->sprom.pa1hib1; - lpphy->txpah[2] = bus->sprom.pa1hib2; - maxpwr = bus->sprom.maxpwr_al; - ofdmpo = bus->sprom.ofdm5glpo; + lpphy->tx_isolation_low_band = sprom->tri5gl; + lpphy->tx_isolation_med_band = sprom->tri5g; + lpphy->tx_isolation_hi_band = sprom->tri5gh; + lpphy->bx_arch = sprom->bxa5g; + lpphy->rx_pwr_offset = sprom->rxpo5g; + lpphy->rssi_vf = sprom->rssismf5g; + lpphy->rssi_vc = sprom->rssismc5g; + lpphy->rssi_gs = sprom->rssisav5g; + lpphy->txpa[0] = sprom->pa1b0; + lpphy->txpa[1] = sprom->pa1b1; + lpphy->txpa[2] = sprom->pa1b2; + lpphy->txpal[0] = sprom->pa1lob0; + lpphy->txpal[1] = sprom->pa1lob1; + lpphy->txpal[2] = sprom->pa1lob2; + lpphy->txpah[0] = sprom->pa1hib0; + lpphy->txpah[1] = sprom->pa1hib1; + lpphy->txpah[2] = sprom->pa1hib2; + maxpwr = sprom->maxpwr_al; + ofdmpo = sprom->ofdm5glpo; lpphy->max_tx_pwr_low_band = maxpwr; for (i = 4; i < 12; i++) { lpphy->tx_max_ratel[i] = maxpwr - (ofdmpo & 0xF) * 2; ofdmpo >>= 4; } - maxpwr = bus->sprom.maxpwr_a; - ofdmpo = bus->sprom.ofdm5gpo; + maxpwr = sprom->maxpwr_a; + ofdmpo = sprom->ofdm5gpo; lpphy->max_tx_pwr_med_band = maxpwr; for (i = 4; i < 12; i++) { lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; ofdmpo >>= 4; } - maxpwr = bus->sprom.maxpwr_ah; - ofdmpo = bus->sprom.ofdm5ghpo; + maxpwr = sprom->maxpwr_ah; + ofdmpo = sprom->ofdm5ghpo; lpphy->max_tx_pwr_hi_band = maxpwr; for (i = 4; i < 12; i++) { lpphy->tx_max_rateh[i] = maxpwr - (ofdmpo & 0xF) * 2; @@ -215,6 +215,7 @@ static void lpphy_table_init(struct b43_wldev *dev) static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) { struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy_lp *lpphy = dev->phy.lp; u16 tmp, tmp2; @@ -242,9 +243,9 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00); b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, 0xFF00, lpphy->rx_pwr_offset); - if ((bus->sprom.boardflags_lo & B43_BFL_FEM) && + if ((sprom->boardflags_lo & B43_BFL_FEM) && ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || - (bus->sprom.boardflags_hi & B43_BFH_PAREF))) { + (sprom->boardflags_hi & B43_BFH_PAREF))) { ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28); ssb_pmu_set_ldo_paref(&bus->chipco, true); if (dev->phy.rev == 0) { @@ -260,7 +261,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) } tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000; b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp); - if (bus->sprom.boardflags_hi & B43_BFH_RSSIINV) + if (sprom->boardflags_hi & B43_BFH_RSSIINV) b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA); else b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA); @@ -268,7 +269,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL, 0xFFF9, (lpphy->bx_arch << 1)); if (dev->phy.rev == 1 && - (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) { + (sprom->boardflags_hi & B43_BFH_FEM_BT)) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A); @@ -287,7 +288,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || (bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) && - (bus->sprom.boardflags_lo & B43_BFL_FEM))) { + (sprom->boardflags_lo & B43_BFL_FEM))) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001); @@ -297,7 +298,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00); } else if (dev->phy.rev == 1 || - (bus->sprom.boardflags_lo & B43_BFL_FEM)) { + (sprom->boardflags_lo & B43_BFL_FEM)) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004); @@ -316,13 +317,13 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700); } - if (dev->phy.rev == 1 && (bus->sprom.boardflags_hi & B43_BFH_PAREF)) { + if (dev->phy.rev == 1 && (sprom->boardflags_hi & B43_BFH_PAREF)) { b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1); b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2); b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3); b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4); } - if ((bus->sprom.boardflags_hi & B43_BFH_FEM_BT) && + if ((sprom->boardflags_hi & B43_BFH_FEM_BT) && (bus->chip_id == 0x5354) && (bus->chip_package == SSB_CHIPPACK_BCM4712S)) { b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006); diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e395550222d..46428ad5ab8 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) static void b43_nphy_tx_power_fix(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_sprom *sprom = dev->dev->bus_sprom; u8 txpi[2], bbmult, i; u16 tmp, radio_gain, dac_gain; @@ -423,7 +423,7 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev) static void b43_radio_init2055_post(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo); int i; u16 val; @@ -1168,7 +1168,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); + struct ssb_sprom *sprom = dev->dev->bus_sprom; /* PHY rev 0, 1, 2 */ u8 i, j; @@ -1374,6 +1374,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) static void b43_nphy_workarounds(struct b43_wldev *dev) { struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; @@ -1443,9 +1444,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ - if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR && + if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR && b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || - (bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR && + (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR && b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) tmp32 = 0x00088888; else @@ -1503,7 +1504,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); - if (bus->sprom.boardflags2_lo & 0x100 && + if (sprom->boardflags2_lo & 0x100 && bus->boardinfo.type == 0x8B) { delays1[0] = 0x1; delays1[5] = 0x14; @@ -3587,6 +3588,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) int b43_phy_initn(struct b43_wldev *dev) { struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; u8 tx_pwr_state; @@ -3599,7 +3601,7 @@ int b43_phy_initn(struct b43_wldev *dev) bool do_cal = false; if ((dev->phy.rev >= 3) && - (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && + (sprom->boardflags_lo & B43_BFL_EXTLNA) && (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); } @@ -3639,7 +3641,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); - if (bus->sprom.boardflags2_lo & 0x100 || + if (sprom->boardflags2_lo & 0x100 || (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && bus->boardinfo.type == 0x8B)) b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c index 59df3c64af6..aa117550e6c 100644 --- a/drivers/net/wireless/b43/tables_lpphy.c +++ b/drivers/net/wireless/b43/tables_lpphy.c @@ -2416,12 +2416,12 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count, void lpphy_init_tx_gain_table(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; switch (dev->phy.rev) { case 0: - if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) || - (bus->sprom.boardflags_lo & B43_BFL_HGPA)) + if ((sprom->boardflags_hi & B43_BFH_NOPA) || + (sprom->boardflags_lo & B43_BFL_HGPA)) lpphy_write_gain_table_bulk(dev, 0, 128, lpphy_rev0_nopa_tx_gain_table); else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -2432,8 +2432,8 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev) lpphy_rev0_5ghz_tx_gain_table); break; case 1: - if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) || - (bus->sprom.boardflags_lo & B43_BFL_HGPA)) + if ((sprom->boardflags_hi & B43_BFH_NOPA) || + (sprom->boardflags_lo & B43_BFL_HGPA)) lpphy_write_gain_table_bulk(dev, 0, 128, lpphy_rev1_nopa_tx_gain_table); else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -2444,7 +2444,7 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev) lpphy_rev1_5ghz_tx_gain_table); break; default: - if (bus->sprom.boardflags_hi & B43_BFH_NOPA) + if (sprom->boardflags_hi & B43_BFH_NOPA) lpphy_write_gain_table_bulk(dev, 0, 128, lpphy_rev2_nopa_tx_gain_table); else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c index 8f4db448ec3..2829ee1872c 100644 --- a/drivers/net/wireless/b43/wa.c +++ b/drivers/net/wireless/b43/wa.c @@ -487,6 +487,7 @@ static void b43_wa_boards_a(struct b43_wldev *dev) static void b43_wa_boards_g(struct b43_wldev *dev) { struct ssb_bus *bus = dev->sdev->bus; + struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || @@ -498,7 +499,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev) } else { b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); - if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && + if ((sprom->boardflags_lo & B43_BFL_EXTLNA) && (phy->rev >= 7)) { b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); @@ -510,7 +511,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev) } } } - if (bus->sprom.boardflags_lo & B43_BFL_FEM) { + if (sprom->boardflags_lo & B43_BFL_FEM) { b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); } diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index c8f99aebe01..488b898418a 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -547,7 +547,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev, else tmp -= 3; } else { - if (dev->sdev->bus->sprom. + if (dev->dev->bus_sprom-> boardflags_lo & B43_BFL_RSSI) { if (in_rssi > 63) in_rssi = 63; -- cgit v1.2.3-70-g09d2 From a18c715e63505850edd2b69ded5373d6d464cd80 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:40 +0200 Subject: b43: bus: abstract device structs and irq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 4 ++++ drivers/net/wireless/b43/bus.h | 4 ++++ drivers/net/wireless/b43/dma.c | 28 ++++++++++++++-------------- drivers/net/wireless/b43/leds.c | 2 +- drivers/net/wireless/b43/main.c | 10 +++++----- drivers/net/wireless/b43/sysfs.c | 4 ++-- 6 files changed, 30 insertions(+), 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index c116f123aea..ec59a129bae 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -70,6 +70,10 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->block_read = b43_bus_ssb_block_read; dev->block_write = b43_bus_ssb_block_write; + dev->dev = sdev->dev; + dev->dma_dev = sdev->dma_dev; + dev->irq = sdev->irq; + dev->bus_sprom = &sdev->bus->sprom; dev->core_id = sdev->id.coreid; diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index 6d575d6c811..d432f5ceecb 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -20,6 +20,10 @@ struct b43_bus_dev { void (*block_write)(struct b43_bus_dev *dev, const void *buffer, size_t count, u16 offset, u8 reg_width); + struct device *dev; + struct device *dma_dev; + unsigned int irq; + struct ssb_sprom *bus_sprom; u16 core_id; diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index ee45ab9af23..11e66cd2e26 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -333,10 +333,10 @@ static inline dma_addr_t dmaaddr; if (tx) { - dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_TO_DEVICE); } else { - dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_FROM_DEVICE); } @@ -348,10 +348,10 @@ static inline dma_addr_t addr, size_t len, int tx) { if (tx) { - dma_unmap_single(ring->dev->sdev->dma_dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_TO_DEVICE); } else { - dma_unmap_single(ring->dev->sdev->dma_dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } } @@ -361,7 +361,7 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - dma_sync_single_for_cpu(ring->dev->sdev->dma_dev, + dma_sync_single_for_cpu(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -370,7 +370,7 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - dma_sync_single_for_device(ring->dev->sdev->dma_dev, + dma_sync_single_for_device(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) */ if (ring->type == B43_DMA_64BIT) flags |= GFP_DMA; - ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev, + ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, &(ring->dmabase), flags); if (!ring->descbase) { @@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) static void free_ringmemory(struct b43_dmaring *ring) { - dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE, + dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, ring->descbase, ring->dmabase); } @@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, dma_addr_t addr, size_t buffersize, bool dma_to_device) { - if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr))) + if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) return 1; switch (ring->type) { @@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = dma_map_single(dev->sdev->dma_dev, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, b43_txhdr_size(dev), DMA_TO_DEVICE); @@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, if (!ring->txhdr_cache) goto err_kfree_meta; - dma_test = dma_map_single(dev->sdev->dma_dev, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, b43_txhdr_size(dev), DMA_TO_DEVICE); @@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, } } - dma_unmap_single(dev->sdev->dma_dev, + dma_unmap_single(dev->dev->dma_dev, dma_test, b43_txhdr_size(dev), DMA_TO_DEVICE); } @@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask) /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = dma_set_mask(dev->sdev->dma_dev, mask); + err = dma_set_mask(dev->dev->dma_dev, mask); if (!err) { - err = dma_set_coherent_mask(dev->sdev->dma_dev, mask); + err = dma_set_coherent_mask(dev->dev->dma_dev, mask); if (!err) break; } diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 26d37ef0108..70bcf427614 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, led->led_dev.default_trigger = default_trigger; led->led_dev.brightness_set = b43_led_brightness_set; - err = led_classdev_register(dev->sdev->dev, &led->led_dev); + err = led_classdev_register(dev->dev->dev, &led->led_dev); if (err) { b43warn(dev->wl, "LEDs: Failed to register %s\n", name); led->wl = NULL; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 0f3a104a0ac..fd1e74ce0c3 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2063,7 +2063,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, B43_WARN_ON(1); return -ENOSYS; } - err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev); + err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); if (err == -ENOENT) { snprintf(ctx->errors[ctx->req_type], sizeof(ctx->errors[ctx->req_type]), @@ -3970,8 +3970,8 @@ redo: if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { b43_sdio_free_irq(dev); } else { - synchronize_irq(dev->sdev->irq); - free_irq(dev->sdev->irq, dev); + synchronize_irq(dev->dev->irq); + free_irq(dev->dev->irq, dev); } mutex_lock(&wl->mutex); dev = wl->current_dev; @@ -4011,12 +4011,12 @@ static int b43_wireless_core_start(struct b43_wldev *dev) goto out; } } else { - err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler, + err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, b43_interrupt_thread_handler, IRQF_SHARED, KBUILD_MODNAME, dev); if (err) { b43err(dev->wl, "Cannot request IRQ-%d\n", - dev->sdev->irq); + dev->dev->irq); goto out; } } diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c index 57af619725c..f1ae4e05a32 100644 --- a/drivers/net/wireless/b43/sysfs.c +++ b/drivers/net/wireless/b43/sysfs.c @@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644, int b43_sysfs_register(struct b43_wldev *wldev) { - struct device *dev = wldev->sdev->dev; + struct device *dev = wldev->dev->dev; B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); @@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev) void b43_sysfs_unregister(struct b43_wldev *wldev) { - struct device *dev = wldev->sdev->dev; + struct device *dev = wldev->dev->dev; device_remove_file(dev, &dev_attr_interference); } -- cgit v1.2.3-70-g09d2 From c244e08c7aa30abea3c29ff17a40f4b0a58a7913 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:41 +0200 Subject: b43: bus: abstract chip info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 4 ++++ drivers/net/wireless/b43/bus.h | 4 ++++ drivers/net/wireless/b43/main.c | 12 ++++++------ drivers/net/wireless/b43/phy_g.c | 8 ++++---- drivers/net/wireless/b43/phy_lp.c | 22 +++++++++------------- drivers/net/wireless/b43/tables_lpphy.c | 3 +-- 6 files changed, 28 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index ec59a129bae..8d0e7584eaf 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -74,6 +74,10 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->dma_dev = sdev->dma_dev; dev->irq = sdev->irq; + dev->chip_id = sdev->bus->chip_id; + dev->chip_rev = sdev->bus->chip_rev; + dev->chip_pkg = sdev->bus->chip_package; + dev->bus_sprom = &sdev->bus->sprom; dev->core_id = sdev->id.coreid; diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index d432f5ceecb..14942fb605d 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -24,6 +24,10 @@ struct b43_bus_dev { struct device *dma_dev; unsigned int irq; + u16 chip_id; + u8 chip_rev; + u8 chip_pkg; + struct ssb_sprom *bus_sprom; u16 core_id; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index fd1e74ce0c3..e80aaef6318 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2588,7 +2588,7 @@ static int b43_gpio_init(struct b43_wldev *dev) mask = 0x0000001F; set = 0x0000000F; - if (dev->sdev->bus->chip_id == 0x4301) { + if (dev->dev->chip_id == 0x4301) { mask |= 0x0060; set |= 0x0060; } @@ -2748,8 +2748,8 @@ static void b43_adjust_opmode(struct b43_wldev *dev) cfp_pretbtt = 2; if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { - if (dev->sdev->bus->chip_id == 0x4306 && - dev->sdev->bus->chip_rev == 3) + if (dev->dev->chip_id == 0x4306 && + dev->dev->chip_rev == 3) cfp_pretbtt = 100; else cfp_pretbtt = 50; @@ -4096,10 +4096,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) analog_type, phy_type, phy_rev); /* Get RADIO versioning */ - if (dev->sdev->bus->chip_id == 0x4317) { - if (dev->sdev->bus->chip_rev == 0) + if (dev->dev->chip_id == 0x4317) { + if (dev->dev->chip_rev == 0) tmp = 0x3205017F; - else if (dev->sdev->bus->chip_rev == 1) + else if (dev->dev->chip_rev == 1) tmp = 0x4205017F; else tmp = 0x5205017F; diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index ccb02afca62..40ce9e6d104 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -2088,8 +2088,8 @@ static void b43_phy_initg(struct b43_wldev *dev) /* FIXME: The spec says in the following if, the 0 should be replaced 'if OFDM may not be used in the current locale' but OFDM is legal everywhere */ - if ((dev->sdev->bus->chip_id == 0x4306 - && dev->sdev->bus->chip_package == 2) || 0) { + if ((dev->dev->chip_id == 0x4306 + && dev->dev->chip_pkg == 2) || 0) { b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); } @@ -2203,7 +2203,7 @@ static void default_radio_attenuation(struct b43_wldev *dev, && bus->boardinfo.type == SSB_BOARD_BU4306) rf->att = 5; - else if (bus->chip_id == 0x4320) + else if (dev->dev->chip_id == 0x4320) rf->att = 4; else rf->att = 3; @@ -2388,7 +2388,7 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) pab1 = (s16) (dev->dev->bus_sprom->pa0b1); pab2 = (s16) (dev->dev->bus_sprom->pa0b2); - B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) && + B43_WARN_ON((dev->dev->chip_id == 0x4301) && (phy->radio_ver != 0x2050)); /* Not supported anymore */ gphy->dyn_tssi_tbl = 0; diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 41d02810d6d..bb78be319bd 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -324,8 +324,8 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4); } if ((sprom->boardflags_hi & B43_BFH_FEM_BT) && - (bus->chip_id == 0x5354) && - (bus->chip_package == SSB_CHIPPACK_BCM4712S)) { + (dev->dev->chip_id == 0x5354) && + (dev->dev->chip_pkg == SSB_CHIPPACK_BCM4712S)) { b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006); b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005); b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF); @@ -450,7 +450,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0); b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300); b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100); b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA); } else { @@ -468,7 +468,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12); b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0); b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40); } @@ -493,7 +493,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) 0x2000 | ((u16)lpphy->rssi_gs << 10) | ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_phy_set(dev, B43_LPPHY_AFE_ADC_CTL_0, 0x1C); b43_phy_maskset(dev, B43_LPPHY_AFE_CTL, 0x00FF, 0x8800); b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_1, 0xFC3C, 0x0400); @@ -698,7 +698,7 @@ static void lpphy_radio_init(struct b43_wldev *dev) lpphy_sync_stx(dev); b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); - if (dev->sdev->bus->chip_id == 0x4325) { + if (dev->dev->chip_id == 0x4325) { // TODO SSB PMU recalibration } } @@ -1841,7 +1841,6 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; struct lpphy_tx_gains gains, oldgains; int old_txpctl, old_afe_ovr, old_rf, old_bbmult; @@ -1855,7 +1854,7 @@ static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); - if (bus->chip_id == 0x4325 && bus->chip_rev == 0) + if (dev->dev->chip_id == 0x4325 && dev->dev->chip_rev == 0) lpphy_papd_cal(dev, gains, 0, 1, 30); else lpphy_papd_cal(dev, gains, 0, 1, 65); @@ -1871,7 +1870,6 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, bool rx, bool pa, struct lpphy_tx_gains *gains) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; const struct lpphy_rx_iq_comp *iqcomp = NULL; struct lpphy_tx_gains nogains, oldgains; u16 tmp; @@ -1880,7 +1878,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, memset(&nogains, 0, sizeof(nogains)); memset(&oldgains, 0, sizeof(oldgains)); - if (bus->chip_id == 0x5354) { + if (dev->dev->chip_id == 0x5354) { for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) { if (lpphy_5354_iq_table[i].chan == lpphy->channel) { iqcomp = &lpphy_5354_iq_table[i]; @@ -2409,11 +2407,9 @@ static const struct b206x_channel b2063_chantbl[] = { static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; - b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); udelay(20); - if (bus->chip_id == 0x5354) { + if (dev->dev->chip_id == 0x5354) { b43_radio_write(dev, B2062_N_COMM1, 4); b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4); } else { diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c index aa117550e6c..6748c5a196e 100644 --- a/drivers/net/wireless/b43/tables_lpphy.c +++ b/drivers/net/wireless/b43/tables_lpphy.c @@ -2304,7 +2304,6 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev) void lpphy_rev2plus_table_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; int i; B43_WARN_ON(dev->phy.rev < 2); @@ -2341,7 +2340,7 @@ void lpphy_rev2plus_table_init(struct b43_wldev *dev) b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0), ARRAY_SIZE(lpphy_papd_mult_table), lpphy_papd_mult_table); - if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { + if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0), ARRAY_SIZE(lpphy_a0_gain_idx_table), lpphy_a0_gain_idx_table); b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0), -- cgit v1.2.3-70-g09d2 From 79d2232fed23e8e0d1b11abe2f9b78fb09084506 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:42 +0200 Subject: b43: bus: abstract board info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 4 +++ drivers/net/wireless/b43/bus.h | 4 +++ drivers/net/wireless/b43/leds.c | 5 ++-- drivers/net/wireless/b43/phy_a.c | 7 +++-- drivers/net/wireless/b43/phy_common.c | 4 +-- drivers/net/wireless/b43/phy_g.c | 48 +++++++++++++++++------------------ drivers/net/wireless/b43/phy_lp.c | 5 ++-- drivers/net/wireless/b43/phy_n.c | 15 +++++------ drivers/net/wireless/b43/wa.c | 19 ++++++-------- 9 files changed, 54 insertions(+), 57 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 8d0e7584eaf..f897b7054a0 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -74,6 +74,10 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->dma_dev = sdev->dma_dev; dev->irq = sdev->irq; + dev->board_vendor = sdev->bus->boardinfo.vendor; + dev->board_type = sdev->bus->boardinfo.type; + dev->board_rev = sdev->bus->boardinfo.rev; + dev->chip_id = sdev->bus->chip_id; dev->chip_rev = sdev->bus->chip_rev; dev->chip_pkg = sdev->bus->chip_package; diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index 14942fb605d..e88b4494bea 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -24,6 +24,10 @@ struct b43_bus_dev { struct device *dma_dev; unsigned int irq; + u16 board_vendor; + u16 board_type; + u16 board_rev; + u16 chip_id; u8 chip_rev; u8 chip_pkg; diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 70bcf427614..b56ed41fc1b 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -215,7 +215,6 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, enum b43_led_behaviour *behaviour, bool *activelow) { - struct ssb_bus *bus = dev->sdev->bus; u8 sprom[4]; sprom[0] = dev->dev->bus_sprom->gpio0; @@ -231,12 +230,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, case 0: *behaviour = B43_LED_ACTIVITY; *activelow = 1; - if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) + if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ) *behaviour = B43_LED_RADIO_ALL; break; case 1: *behaviour = B43_LED_RADIO_B; - if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) + if (dev->dev->board_vendor == PCI_VENDOR_ID_ASUSTEK) *behaviour = B43_LED_ASSOC; break; case 2: diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index 821b516fe9e..73ace5552ba 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c @@ -265,7 +265,6 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev) void b43_phy_inita(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; /* This lowlevel A-PHY init is also called from G-PHY init. @@ -296,9 +295,9 @@ void b43_phy_inita(struct b43_wldev *dev) b43_radio_init2060(dev); - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - ((bus->boardinfo.type == SSB_BOARD_BU4306) || - (bus->boardinfo.type == SSB_BOARD_BU4309))) { + if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && + ((dev->dev->board_type == SSB_BOARD_BU4306) || + (dev->dev->board_type == SSB_BOARD_BU4309))) { ; //TODO: A PHY LO } diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 3f7bdf84544..425af28ea4e 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) /* The next check will be needed in two seconds, or later. */ phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); - if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306)) + if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && + (dev->dev->board_type == SSB_BOARD_BU4306)) return; /* No software txpower adjustment needed */ result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 40ce9e6d104..684be1fd59a 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -1491,7 +1491,6 @@ static u16 b43_radio_init2050(struct b43_wldev *dev) static void b43_phy_initb5(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; u16 offset, value; @@ -1500,8 +1499,8 @@ static void b43_phy_initb5(struct b43_wldev *dev) if (phy->analog == 1) { b43_radio_set(dev, 0x007A, 0x0050); } - if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type != SSB_BOARD_BU4306)) { + if ((dev->dev->board_vendor != SSB_BOARDVENDOR_BCM) && + (dev->dev->board_type != SSB_BOARD_BU4306)) { value = 0x2120; for (offset = 0x00A8; offset < 0x00C7; offset++) { b43_phy_write(dev, offset, value); @@ -1922,7 +1921,6 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) /* Initialize B/G PHY power control */ static void b43_phy_init_pctl(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; struct b43_rfatt old_rfatt; @@ -1931,8 +1929,8 @@ static void b43_phy_init_pctl(struct b43_wldev *dev) B43_WARN_ON(phy->type != B43_PHYTYPE_G); - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type == SSB_BOARD_BU4306)) + if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && + (dev->dev->board_type == SSB_BOARD_BU4306)) return; b43_phy_write(dev, 0x0028, 0x8018); @@ -2136,17 +2134,17 @@ static void default_baseband_attenuation(struct b43_wldev *dev, static void default_radio_attenuation(struct b43_wldev *dev, struct b43_rfatt *rf) { - struct ssb_bus *bus = dev->sdev->bus; + struct b43_bus_dev *bdev = dev->dev; struct b43_phy *phy = &dev->phy; rf->with_padmix = 0; - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && - bus->boardinfo.type == SSB_BOARD_BCM4309G) { - if (bus->boardinfo.rev < 0x43) { + if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM && + dev->dev->board_type == SSB_BOARD_BCM4309G) { + if (dev->dev->board_rev < 0x43) { rf->att = 2; return; - } else if (bus->boardinfo.rev < 0x51) { + } else if (dev->dev->board_rev < 0x51) { rf->att = 3; return; } @@ -2172,21 +2170,21 @@ static void default_radio_attenuation(struct b43_wldev *dev, return; case 1: if (phy->type == B43_PHYTYPE_G) { - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == SSB_BOARD_BCM4309G - && bus->boardinfo.rev >= 30) + if (bdev->board_vendor == SSB_BOARDVENDOR_BCM + && bdev->board_type == SSB_BOARD_BCM4309G + && bdev->board_rev >= 30) rf->att = 3; - else if (bus->boardinfo.vendor == + else if (bdev->board_vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == + && bdev->board_type == SSB_BOARD_BU4306) rf->att = 3; else rf->att = 1; } else { - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == SSB_BOARD_BCM4309G - && bus->boardinfo.rev >= 30) + if (bdev->board_vendor == SSB_BOARDVENDOR_BCM + && bdev->board_type == SSB_BOARD_BCM4309G + && bdev->board_rev >= 30) rf->att = 7; else rf->att = 6; @@ -2194,16 +2192,16 @@ static void default_radio_attenuation(struct b43_wldev *dev, return; case 2: if (phy->type == B43_PHYTYPE_G) { - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == SSB_BOARD_BCM4309G - && bus->boardinfo.rev >= 30) + if (bdev->board_vendor == SSB_BOARDVENDOR_BCM + && bdev->board_type == SSB_BOARD_BCM4309G + && bdev->board_rev >= 30) rf->att = 3; - else if (bus->boardinfo.vendor == + else if (bdev->board_vendor == SSB_BOARDVENDOR_BCM - && bus->boardinfo.type == + && bdev->board_type == SSB_BOARD_BU4306) rf->att = 5; - else if (dev->dev->chip_id == 0x4320) + else if (bdev->chip_id == 0x4320) rf->att = 4; else rf->att = 3; diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index bb78be319bd..2606c25e574 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -287,7 +287,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || - (bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) && + (dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) && (sprom->boardflags_lo & B43_BFL_FEM))) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); @@ -413,7 +413,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct b43_phy_lp *lpphy = dev->phy.lp; b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); @@ -433,7 +432,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000); b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000); b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1); - if (bus->boardinfo.rev >= 0x18) { + if (dev->dev->board_rev >= 0x18) { b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC); b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14); } else { diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 46428ad5ab8..ad14f3b428c 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -424,15 +424,14 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; struct ssb_sprom *sprom = dev->dev->bus_sprom; - struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo); int i; u16 val; bool workaround = false; if (sprom->revision < 4) - workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM && - binfo->type == 0x46D && - binfo->rev >= 0x41); + workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM + && dev->dev->board_type == 0x46D + && dev->dev->board_rev >= 0x41); else workaround = !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); @@ -1373,7 +1372,6 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ static void b43_nphy_workarounds(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; @@ -1505,7 +1503,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); if (sprom->boardflags2_lo & 0x100 && - bus->boardinfo.type == 0x8B) { + dev->dev->board_type == 0x8B) { delays1[0] = 0x1; delays1[5] = 0x14; } @@ -3587,7 +3585,6 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) */ int b43_phy_initn(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = phy->n; @@ -3642,8 +3639,8 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); if (sprom->boardflags2_lo & 0x100 || - (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && - bus->boardinfo.type == 0x8B)) + (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE && + dev->dev->board_type == 0x8B)) b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); else b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c index 2829ee1872c..5d00d0eaf2e 100644 --- a/drivers/net/wireless/b43/wa.c +++ b/drivers/net/wireless/b43/wa.c @@ -458,17 +458,15 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev) static void b43_wa_boards_a(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; - - if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && - bus->boardinfo.type == SSB_BOARD_BU4306 && - bus->boardinfo.rev < 0x30) { + if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM && + dev->dev->board_type == SSB_BOARD_BU4306 && + dev->dev->board_rev < 0x30) { b43_phy_write(dev, 0x0010, 0xE000); b43_phy_write(dev, 0x0013, 0x0140); b43_phy_write(dev, 0x0014, 0x0280); } else { - if (bus->boardinfo.type == SSB_BOARD_MP4318 && - bus->boardinfo.rev < 0x20) { + if (dev->dev->board_type == SSB_BOARD_MP4318 && + dev->dev->board_rev < 0x20) { b43_phy_write(dev, 0x0013, 0x0210); b43_phy_write(dev, 0x0014, 0x0840); } else { @@ -486,13 +484,12 @@ static void b43_wa_boards_a(struct b43_wldev *dev) static void b43_wa_boards_g(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; - if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || - bus->boardinfo.type != SSB_BOARD_BU4306 || - bus->boardinfo.rev != 0x17) { + if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM || + dev->dev->board_type != SSB_BOARD_BU4306 || + dev->dev->board_rev != 0x17) { if (phy->rev < 2) { b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); -- cgit v1.2.3-70-g09d2 From 24ca39d67968c42d377abc122f6dca635ebcdb79 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 18 May 2011 02:06:43 +0200 Subject: b43: bus: abstract bus and core operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 23 +++++++++++++++++++++++ drivers/net/wireless/b43/bus.c | 31 +++++++++++++++++++++++++++++++ drivers/net/wireless/b43/bus.h | 8 ++++++++ drivers/net/wireless/b43/main.c | 22 +++++++++++----------- drivers/net/wireless/b43/rfkill.c | 9 ++++----- 5 files changed, 77 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 3378d93cc33..0a3c7012901 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -881,6 +881,29 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) return wl->hw->conf.channel->band; } +static inline int b43_bus_may_powerdown(struct b43_wldev *wldev) +{ + return wldev->dev->bus_may_powerdown(wldev->dev); +} +static inline int b43_bus_powerup(struct b43_wldev *wldev, bool dynamic_pctl) +{ + return wldev->dev->bus_powerup(wldev->dev, dynamic_pctl); +} +static inline int b43_device_is_enabled(struct b43_wldev *wldev) +{ + return wldev->dev->device_is_enabled(wldev->dev); +} +static inline void b43_device_enable(struct b43_wldev *wldev, + u32 core_specific_flags) +{ + wldev->dev->device_enable(wldev->dev, core_specific_flags); +} +static inline void b43_device_disable(struct b43_wldev *wldev, + u32 core_specific_flags) +{ + wldev->dev->device_disable(wldev->dev, core_specific_flags); +} + static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) { return dev->dev->read16(dev->dev, offset); diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index f897b7054a0..6c63aecd6ab 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -25,6 +25,31 @@ /* SSB */ + +static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev) +{ + return ssb_bus_may_powerdown(dev->sdev->bus); +} +static inline int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev, + bool dynamic_pctl) +{ + return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl); +} +static inline int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev) +{ + return ssb_device_is_enabled(dev->sdev); +} +static inline void b43_bus_ssb_device_enable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + ssb_device_enable(dev->sdev, core_specific_flags); +} +static inline void b43_bus_ssb_device_disable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + ssb_device_disable(dev->sdev, core_specific_flags); +} + static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset) { return ssb_read16(dev->sdev, offset); @@ -63,6 +88,12 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) dev->bus_type = B43_BUS_SSB; dev->sdev = sdev; + dev->bus_may_powerdown = b43_bus_ssb_bus_may_powerdown; + dev->bus_powerup = b43_bus_ssb_bus_powerup; + dev->device_is_enabled = b43_bus_ssb_device_is_enabled; + dev->device_enable = b43_bus_ssb_device_enable; + dev->device_disable = b43_bus_ssb_device_disable; + dev->read16 = b43_bus_ssb_read16; dev->read32 = b43_bus_ssb_read32; dev->write16 = b43_bus_ssb_write16; diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index e88b4494bea..fd88e2b121a 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -11,6 +11,14 @@ struct b43_bus_dev { struct ssb_device *sdev; }; + int (*bus_may_powerdown)(struct b43_bus_dev *dev); + int (*bus_powerup)(struct b43_bus_dev *dev, bool dynamic_pctl); + int (*device_is_enabled)(struct b43_bus_dev *dev); + void (*device_enable)(struct b43_bus_dev *dev, + u32 core_specific_flags); + void (*device_disable)(struct b43_bus_dev *dev, + u32 core_specific_flags); + u16 (*read16)(struct b43_bus_dev *dev, u16 offset); u32 (*read32)(struct b43_bus_dev *dev, u16 offset); void (*write16)(struct b43_bus_dev *dev, u16 offset, u16 value); diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index e80aaef6318..bb82ddfa44f 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1152,7 +1152,7 @@ static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) flags |= B43_TMSLOW_PHYRESET; if (dev->phy.type == B43_PHYTYPE_N) flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ - ssb_device_enable(dev->sdev, flags); + b43_device_enable(dev, flags); msleep(2); /* Wait for the PLL to turn on. */ /* Now take the PHY out of Reset again */ @@ -4310,8 +4310,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) dev->wl->current_beacon = NULL; } - ssb_device_disable(dev->sdev, 0); - ssb_bus_may_powerdown(dev->sdev->bus); + b43_device_disable(dev, 0); + b43_bus_may_powerdown(dev); } /* Initialize a wireless core */ @@ -4326,10 +4326,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev) B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); - err = ssb_bus_powerup(bus, 0); + err = b43_bus_powerup(dev, 0); if (err) goto out; - if (!ssb_device_is_enabled(dev->sdev)) { + if (!b43_device_is_enabled(dev)) { tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; b43_wireless_core_reset(dev, tmp); } @@ -4414,7 +4414,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) b43_set_synth_pu_delay(dev, 1); b43_bluetooth_coext_enable(dev); - ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); + b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); b43_upload_card_macaddress(dev); b43_security_init(dev); @@ -4431,7 +4431,7 @@ out: err_chip_exit: b43_chip_exit(dev); err_busdown: - ssb_bus_may_powerdown(bus); + b43_bus_may_powerdown(dev); B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); return err; } @@ -4750,7 +4750,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) * that in core_init(), too. */ - err = ssb_bus_powerup(bus, 0); + err = b43_bus_powerup(dev, 0); if (err) { b43err(wl, "Bus powerup failed\n"); goto out; @@ -4832,8 +4832,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) INIT_WORK(&dev->restart_work, b43_chip_reset); dev->phy.ops->switch_analog(dev, 0); - ssb_device_disable(dev->sdev, 0); - ssb_bus_may_powerdown(bus); + b43_device_disable(dev, 0); + b43_bus_may_powerdown(dev); out: return err; @@ -4841,7 +4841,7 @@ out: err_phy_free: b43_phy_free(dev); err_powerdown: - ssb_bus_may_powerdown(bus); + b43_bus_may_powerdown(dev); return err; } diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index a617efe3828..59c3afe047a 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -37,17 +37,16 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; - struct ssb_bus *bus = dev->sdev->bus; bool enabled; bool brought_up = false; mutex_lock(&wl->mutex); if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { - if (ssb_bus_powerup(bus, 0)) { + if (b43_bus_powerup(dev, 0)) { mutex_unlock(&wl->mutex); return; } - ssb_device_enable(dev->sdev, 0); + b43_device_enable(dev, 0); brought_up = true; } @@ -63,8 +62,8 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) } if (brought_up) { - ssb_device_disable(dev->sdev, 0); - ssb_bus_may_powerdown(bus); + b43_device_disable(dev, 0); + b43_bus_may_powerdown(dev); } mutex_unlock(&wl->mutex); -- cgit v1.2.3-70-g09d2 From 65f31b5e7029e55d4f7020a1d0b0658a50ea73cb Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 18 May 2011 20:25:05 +0200 Subject: rt2x00: Enable PA_PE bits in TX_PIN_CFG according to active band. (split off from the earlier RT35xx patch submitted by Shiang) There's no point in enabling the PA_PE bits for the bands that we are not active on. Signed-off-by: Shiang Tu Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 2a6aa85cc6c..0fab3152f2c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1795,8 +1795,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, /* Turn on unused PA or LNA when not using 1T or 1R */ if (rt2x00dev->default_ant.tx_chain_num == 2) { - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, + rf->channel > 14); + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, + rf->channel <= 14); } /* Turn on unused PA or LNA when not using 1T or 1R */ -- cgit v1.2.3-70-g09d2 From 8f96e91fa53761fd63dceedac6bbe4b39e5c5072 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 18 May 2011 20:25:18 +0200 Subject: rt2x00: Don't disable G0 PA_PE bit in case of BT coexistence. (split off from the earlier RT35xx patch submitted by Shiang) Signed-off-by: Shiang Tu Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 0fab3152f2c..2ed3fe0d620 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1811,7 +1811,11 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14); + if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1); + else + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, + rf->channel <= 14); rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14); rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); -- cgit v1.2.3-70-g09d2 From 872834dfb38edc6f72cfc783a5ce78f2a9f36ec5 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 18 May 2011 20:25:31 +0200 Subject: rt2x00: Add support for RT3572/RT3592/RT3592+Bluetooth combo card (based on an earlier patch submitted by Shiang) Add support for RT3572/RT3592/RT3592+Bluetooth combo card Signed-off-by: Shiang Tu Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 16 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 282 +++++++++++++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2800pci.c | 4 +- 3 files changed, 295 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index f67bc9b31b2..c69a7d71f4c 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1740,6 +1740,7 @@ struct mac_iveiv_entry { /* * BBP 3: RX Antenna */ +#define BBP3_RX_ADC FIELD8(0x03) #define BBP3_RX_ANTENNA FIELD8(0x18) #define BBP3_HT40_MINUS FIELD8(0x20) @@ -1783,22 +1784,34 @@ struct mac_iveiv_entry { #define RFCSR1_TX0_PD FIELD8(0x08) #define RFCSR1_RX1_PD FIELD8(0x10) #define RFCSR1_TX1_PD FIELD8(0x20) +#define RFCSR1_RX2_PD FIELD8(0x40) +#define RFCSR1_TX2_PD FIELD8(0x80) /* * RFCSR 2: */ #define RFCSR2_RESCAL_EN FIELD8(0x80) +/* + * FRCSR 5: + */ +#define RFCSR5_R1 FIELD8(0x0c) + /* * RFCSR 6: */ #define RFCSR6_R1 FIELD8(0x03) #define RFCSR6_R2 FIELD8(0x40) +#define RFCSR6_TXDIV FIELD8(0x0c) /* * RFCSR 7: */ #define RFCSR7_RF_TUNING FIELD8(0x01) +#define RFCSR7_R02 FIELD8(0x07) +#define RFCSR7_R3 FIELD8(0x08) +#define RFCSR7_R45 FIELD8(0x30) +#define RFCSR7_R67 FIELD8(0xc0) /* * RFCSR 11: @@ -1809,11 +1822,13 @@ struct mac_iveiv_entry { * RFCSR 12: */ #define RFCSR12_TX_POWER FIELD8(0x1f) +#define RFCSR12_DR0 FIELD8(0xe0) /* * RFCSR 13: */ #define RFCSR13_TX_POWER FIELD8(0x1f) +#define RFCSR13_DR0 FIELD8(0xe0) /* * RFCSR 15: @@ -2256,6 +2271,7 @@ struct mac_iveiv_entry { #define MCU_ANT_SELECT 0X73 #define MCU_BBP_SIGNAL 0x80 #define MCU_POWER_SAVE 0x83 +#define MCU_BAND_SELECT 0x91 /* * MCU mailbox tokens diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 2ed3fe0d620..f0988d8736c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -401,7 +401,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, return -EBUSY; if (rt2x00_is_pci(rt2x00dev)) { - if (rt2x00_rt(rt2x00dev, RT5390)) { + if (rt2x00_rt(rt2x00dev, RT3572) || + rt2x00_rt(rt2x00dev, RT5390)) { rt2800_register_read(rt2x00dev, AUX_CTRL, ®); rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); @@ -1433,6 +1434,40 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, } EXPORT_SYMBOL_GPL(rt2800_config_erp); +static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + u16 eeprom; + u8 led_ctrl, led_g_mode, led_r_mode; + + rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { + rt2x00_set_field32(®, GPIO_SWITCH_0, 1); + rt2x00_set_field32(®, GPIO_SWITCH_1, 1); + } else { + rt2x00_set_field32(®, GPIO_SWITCH_0, 0); + rt2x00_set_field32(®, GPIO_SWITCH_1, 0); + } + rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); + + rt2800_register_read(rt2x00dev, LED_CFG, ®); + led_g_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 3 : 0; + led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3; + if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) || + led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) { + rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); + led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE); + if (led_ctrl == 0 || led_ctrl > 0x40) { + rt2x00_set_field32(®, LED_CFG_G_LED_MODE, led_g_mode); + rt2x00_set_field32(®, LED_CFG_R_LED_MODE, led_r_mode); + rt2800_register_write(rt2x00dev, LED_CFG, reg); + } else { + rt2800_mcu_request(rt2x00dev, MCU_BAND_SELECT, 0xff, + (led_g_mode << 2) | led_r_mode, 1); + } + } +} + static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev, enum antenna ant) { @@ -1463,6 +1498,10 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) rt2800_bbp_read(rt2x00dev, 1, &r1); rt2800_bbp_read(rt2x00dev, 3, &r3); + if (rt2x00_rt(rt2x00dev, RT3572) && + test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) + rt2800_config_3572bt_ant(rt2x00dev); + /* * Configure the TX antenna. */ @@ -1471,7 +1510,11 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); break; case 2: - rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); + if (rt2x00_rt(rt2x00dev, RT3572) && + test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) + rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 1); + else + rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); break; case 3: rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); @@ -1496,7 +1539,15 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); break; case 2: - rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1); + if (rt2x00_rt(rt2x00dev, RT3572) && + test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { + rt2x00_set_field8(&r3, BBP3_RX_ADC, 1); + rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, + rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); + rt2800_set_ant_diversity(rt2x00dev, ANTENNA_B); + } else { + rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1); + } break; case 3: rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2); @@ -1630,6 +1681,161 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); } +static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, + struct channel_info *info) +{ + u8 rfcsr; + u32 reg; + + if (rf->channel <= 14) { + rt2800_bbp_write(rt2x00dev, 25, 0x15); + rt2800_bbp_write(rt2x00dev, 26, 0x85); + } else { + rt2800_bbp_write(rt2x00dev, 25, 0x09); + rt2800_bbp_write(rt2x00dev, 26, 0xff); + } + + rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); + rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3); + + rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2); + if (rf->channel <= 14) + rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 2); + else + rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 1); + rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 5, &rfcsr); + if (rf->channel <= 14) + rt2x00_set_field8(&rfcsr, RFCSR5_R1, 1); + else + rt2x00_set_field8(&rfcsr, RFCSR5_R1, 2); + rt2800_rfcsr_write(rt2x00dev, 5, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); + if (rf->channel <= 14) { + rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3); + rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, + (info->default_power1 & 0x3) | + ((info->default_power1 & 0xC) << 1)); + } else { + rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7); + rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, + (info->default_power1 & 0x3) | + ((info->default_power1 & 0xC) << 1)); + } + rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); + if (rf->channel <= 14) { + rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3); + rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, + (info->default_power2 & 0x3) | + ((info->default_power2 & 0xC) << 1)); + } else { + rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7); + rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, + (info->default_power2 & 0x3) | + ((info->default_power2 & 0xC) << 1)); + } + rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); + if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { + if (rf->channel <= 14) { + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); + } + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); + } else { + switch (rt2x00dev->default_ant.tx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); + break; + } + + switch (rt2x00dev->default_ant.rx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); + break; + } + } + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); + rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); + + rt2800_rfcsr_write(rt2x00dev, 24, + rt2x00dev->calibration[conf_is_ht40(conf)]); + rt2800_rfcsr_write(rt2x00dev, 31, + rt2x00dev->calibration[conf_is_ht40(conf)]); + + if (rf->channel <= 14) { + rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); + rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); + rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); + rt2800_rfcsr_write(rt2x00dev, 15, 0x53); + rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); + rt2800_rfcsr_write(rt2x00dev, 17, 0x23); + rt2800_rfcsr_write(rt2x00dev, 19, 0x93); + rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); + rt2800_rfcsr_write(rt2x00dev, 25, 0x15); + rt2800_rfcsr_write(rt2x00dev, 26, 0x85); + rt2800_rfcsr_write(rt2x00dev, 27, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); + } else { + rt2800_rfcsr_write(rt2x00dev, 7, 0x14); + rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); + rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 11, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x43); + rt2800_rfcsr_write(rt2x00dev, 16, 0x7a); + rt2800_rfcsr_write(rt2x00dev, 17, 0x23); + if (rf->channel <= 64) { + rt2800_rfcsr_write(rt2x00dev, 19, 0xb7); + rt2800_rfcsr_write(rt2x00dev, 20, 0xf6); + rt2800_rfcsr_write(rt2x00dev, 25, 0x3d); + } else if (rf->channel <= 128) { + rt2800_rfcsr_write(rt2x00dev, 19, 0x74); + rt2800_rfcsr_write(rt2x00dev, 20, 0xf4); + rt2800_rfcsr_write(rt2x00dev, 25, 0x01); + } else { + rt2800_rfcsr_write(rt2x00dev, 19, 0x72); + rt2800_rfcsr_write(rt2x00dev, 20, 0xf3); + rt2800_rfcsr_write(rt2x00dev, 25, 0x01); + } + rt2800_rfcsr_write(rt2x00dev, 26, 0x87); + rt2800_rfcsr_write(rt2x00dev, 27, 0x01); + rt2800_rfcsr_write(rt2x00dev, 29, 0x9f); + } + + rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); + rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT7, 0); + if (rf->channel <= 14) + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 1); + else + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 0); + rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); + + rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); + rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); +} #define RT5390_POWER_BOUND 0x27 #define RT5390_FREQ_OFFSET_BOUND 0x5f @@ -1748,9 +1954,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_rf(rt2x00dev, RF3020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || - rt2x00_rf(rt2x00dev, RF3052) || rt2x00_rf(rt2x00dev, RF3320)) rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); + else if (rt2x00_rf(rt2x00dev, RF3052)) + rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); else if (rt2x00_rf(rt2x00dev, RF5370) || rt2x00_rf(rt2x00dev, RF5390)) rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); @@ -1777,7 +1984,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, } } } else { - rt2800_bbp_write(rt2x00dev, 82, 0xf2); + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_bbp_write(rt2x00dev, 82, 0x94); + else + rt2800_bbp_write(rt2x00dev, 82, 0xf2); if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) rt2800_bbp_write(rt2x00dev, 75, 0x46); @@ -1791,6 +2001,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14); rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_rfcsr_write(rt2x00dev, 8, 0); + tx_pin = 0; /* Turn on unused PA or LNA when not using 1T or 1R */ @@ -1820,6 +2033,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_rfcsr_write(rt2x00dev, 8, 0x80); + rt2800_bbp_read(rt2x00dev, 4, &bbp); rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); rt2800_bbp_write(rt2x00dev, 4, bbp); @@ -2419,6 +2635,9 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030); + } else if (rt2x00_rt(rt2x00dev, RT3572)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); } else if (rt2x00_rt(rt2x00dev, RT5390)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); @@ -2805,6 +3024,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) } if (rt2800_is_305x_soc(rt2x00dev) || + rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390)) rt2800_bbp_write(rt2x00dev, 31, 0x08); @@ -2834,6 +3054,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390)) { rt2800_bbp_write(rt2x00dev, 79, 0x13); rt2800_bbp_write(rt2x00dev, 80, 0x05); @@ -2874,6 +3095,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || + rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 103, 0xc0); @@ -2901,6 +3123,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390)) { rt2800_bbp_read(rt2x00dev, 138, &value); @@ -3037,6 +3260,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && !rt2x00_rt(rt2x00dev, RT3390) && + !rt2x00_rt(rt2x00dev, RT3572) && !rt2x00_rt(rt2x00dev, RT5390) && !rt2800_is_305x_soc(rt2x00dev)) return 0; @@ -3115,6 +3339,38 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); rt2800_rfcsr_write(rt2x00dev, 30, 0x20); rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); + } else if (rt2x00_rt(rt2x00dev, RT3572)) { + rt2800_rfcsr_write(rt2x00dev, 0, 0x70); + rt2800_rfcsr_write(rt2x00dev, 1, 0x81); + rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 3, 0x02); + rt2800_rfcsr_write(rt2x00dev, 4, 0x4c); + rt2800_rfcsr_write(rt2x00dev, 5, 0x05); + rt2800_rfcsr_write(rt2x00dev, 6, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); + rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); + rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); + rt2800_rfcsr_write(rt2x00dev, 12, 0x70); + rt2800_rfcsr_write(rt2x00dev, 13, 0x65); + rt2800_rfcsr_write(rt2x00dev, 14, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 15, 0x53); + rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); + rt2800_rfcsr_write(rt2x00dev, 17, 0x23); + rt2800_rfcsr_write(rt2x00dev, 18, 0xac); + rt2800_rfcsr_write(rt2x00dev, 19, 0x93); + rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); + rt2800_rfcsr_write(rt2x00dev, 21, 0xd0); + rt2800_rfcsr_write(rt2x00dev, 22, 0x00); + rt2800_rfcsr_write(rt2x00dev, 23, 0x3c); + rt2800_rfcsr_write(rt2x00dev, 24, 0x16); + rt2800_rfcsr_write(rt2x00dev, 25, 0x15); + rt2800_rfcsr_write(rt2x00dev, 26, 0x85); + rt2800_rfcsr_write(rt2x00dev, 27, 0x00); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); + rt2800_rfcsr_write(rt2x00dev, 30, 0x09); + rt2800_rfcsr_write(rt2x00dev, 31, 0x10); } else if (rt2800_is_305x_soc(rt2x00dev)) { rt2800_rfcsr_write(rt2x00dev, 0, 0x50); rt2800_rfcsr_write(rt2x00dev, 1, 0x01); @@ -3264,6 +3520,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); rt2x00_set_field32(®, GPIO_SWITCH_5, 0); rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); + } else if (rt2x00_rt(rt2x00dev, RT3572)) { + rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); + rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); + + rt2800_register_read(rt2x00dev, LDO_CFG0, ®); + rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); + rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); + rt2800_register_write(rt2x00dev, LDO_CFG0, reg); + msleep(1); + rt2800_register_read(rt2x00dev, LDO_CFG0, ®); + rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); + rt2800_register_write(rt2x00dev, LDO_CFG0, reg); } /* @@ -3276,7 +3545,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); } else if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390)) { + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT3572)) { rt2x00dev->calibration[0] = rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13); rt2x00dev->calibration[1] = diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cc4a54f571b..5513edfa952 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -501,7 +501,9 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); - if (rt2x00_rt(rt2x00dev, RT5390)) { + if (rt2x00_is_pcie(rt2x00dev) && + (rt2x00_rt(rt2x00dev, RT3572) || + rt2x00_rt(rt2x00dev, RT5390))) { rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); -- cgit v1.2.3-70-g09d2 From 798eefde3097f218849194f1abda1f179a169cc2 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 18 May 2011 20:25:42 +0200 Subject: rt2x00: Interface sequence lock doesn't have to disable interrupts. This lock is only used in the TX path and thus in process context. Therefore we can use a much lighter spinlock variant. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index ab8c16f8bca..c7fc9def6bc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -206,7 +206,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); - unsigned long irqflags; if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) return; @@ -227,14 +226,14 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, * sequence counting per-frame, since those will override the * sequence counter given by mac80211. */ - spin_lock_irqsave(&intf->seqlock, irqflags); + spin_lock(&intf->seqlock); if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) intf->seqno += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); hdr->seq_ctrl |= cpu_to_le16(intf->seqno); - spin_unlock_irqrestore(&intf->seqlock, irqflags); + spin_unlock(&intf->seqlock); } -- cgit v1.2.3-70-g09d2 From 8f66bbb5248c59b69b521b35e097ffa6cad07f01 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 18 May 2011 20:25:49 +0200 Subject: rt2x00: Move rt2800_txdone and rt2800_txdone_entry_check to rt2800usb. These two functions are only used by rt2800usb so they don't have to be in rt2800lib. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 82 -------------------------------- drivers/net/wireless/rt2x00/rt2800lib.h | 1 - drivers/net/wireless/rt2x00/rt2800usb.c | 83 ++++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 84 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index f0988d8736c..75d2c6cc93e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -601,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); -static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) -{ - __le32 *txwi; - u32 word; - int wcid, ack, pid; - int tx_wcid, tx_ack, tx_pid; - - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); - - /* - * This frames has returned with an IO error, - * so the status report is not intended for this - * frame. - */ - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - return false; - } - - /* - * Validate if this TX status report is intended for - * this entry by comparing the WCID/ACK/PID fields. - */ - txwi = rt2800_drv_get_txwi(entry); - - rt2x00_desc_read(txwi, 1, &word); - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { - WARNING(entry->queue->rt2x00dev, - "TX status report missed for queue %d entry %d\n", - entry->queue->qid, entry->entry_idx); - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); - return false; - } - - return true; -} - void rt2800_txdone_entry(struct queue_entry *entry, u32 status) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; @@ -726,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) } EXPORT_SYMBOL_GPL(rt2800_txdone_entry); -void rt2800_txdone(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - struct queue_entry *entry; - u32 reg; - u8 qid; - - while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { - - /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus - * qid is guaranteed to be one of the TX QIDs - */ - qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); - if (unlikely(!queue)) { - WARNING(rt2x00dev, "Got TX status for an unavailable " - "queue %u, dropping\n", qid); - continue; - } - - /* - * Inside each queue, we process each entry in a chronological - * order. We first check that the queue is not empty. - */ - entry = NULL; - while (!rt2x00queue_empty(queue)) { - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (rt2800_txdone_entry_check(entry, reg)) - break; - } - - if (!entry || rt2x00queue_empty(queue)) - break; - - rt2800_txdone_entry(entry, reg); - } -} -EXPORT_SYMBOL_GPL(rt2800_txdone); - void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index f2d15941c71..69deb3148ae 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry, struct txentry_desc *txdesc); void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); -void rt2800_txdone(struct rt2x00_dev *rt2x00dev); void rt2800_txdone_entry(struct queue_entry *entry, u32 status); void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index ba82c972703..6e9229830a2 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) /* * TX control handlers */ +static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) +{ + __le32 *txwi; + u32 word; + int wcid, ack, pid; + int tx_wcid, tx_ack, tx_pid; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + + /* + * This frames has returned with an IO error, + * so the status report is not intended for this + * frame. + */ + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + return false; + } + + /* + * Validate if this TX status report is intended for + * this entry by comparing the WCID/ACK/PID fields. + */ + txwi = rt2800usb_get_txwi(entry); + + rt2x00_desc_read(txwi, 1, &word); + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); + + if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { + WARNING(entry->queue->rt2x00dev, + "TX status report missed for queue %d entry %d\n", + entry->queue->qid, entry->entry_idx); + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); + return false; + } + + return true; +} + +static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + u32 reg; + u8 qid; + + while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { + + /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus + * qid is guaranteed to be one of the TX QIDs + */ + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); + if (unlikely(!queue)) { + WARNING(rt2x00dev, "Got TX status for an unavailable " + "queue %u, dropping\n", qid); + continue; + } + + /* + * Inside each queue, we process each entry in a chronological + * order. We first check that the queue is not empty. + */ + entry = NULL; + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800usb_txdone_entry_check(entry, reg)) + break; + } + + if (!entry || rt2x00queue_empty(queue)) + break; + + rt2800_txdone_entry(entry, reg); + } +} + static void rt2800usb_work_txdone(struct work_struct *work) { struct rt2x00_dev *rt2x00dev = @@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct *work) struct data_queue *queue; struct queue_entry *entry; - rt2800_txdone(rt2x00dev); + rt2800usb_txdone(rt2x00dev); /* * Process any trailing TX status reports for IO failures, -- cgit v1.2.3-70-g09d2 From 0f93c79404e1eaa5207f6d8a7aea14119808d382 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 18 May 2011 20:26:04 +0200 Subject: rt2x00: Enabled rt35xx device support by default. Now that support for these devices has been added we can enable them by default and remove the Kconfig not on support for these devices to be non-functional. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index b2f8b8fd4d2..a0a7854facc 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -83,14 +83,12 @@ config RT2800PCI_RT33XX config RT2800PCI_RT35XX bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL - default n + default y ---help--- This adds support for rt35xx wireless chipset family to the rt2800pci driver. Supported chips: RT3060, RT3062, RT3562, RT3592 - Support for these devices is non-functional at the moment and is - intended for testers and developers. config RT2800PCI_RT53XX bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)" @@ -154,15 +152,12 @@ config RT2800USB_RT33XX config RT2800USB_RT35XX bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL - default n + default y ---help--- This adds support for rt35xx wireless chipset family to the rt2800usb driver. Supported chips: RT3572 - Support for these devices is non-functional at the moment and is - intended for testers and developers. - config RT2800USB_RT53XX bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL -- cgit v1.2.3-70-g09d2 From 7882513bacb176ab4aacceefdd035ca9479da4fb Mon Sep 17 00:00:00 2001 From: Javier Lopez Date: Wed, 1 Jun 2011 11:26:13 +0200 Subject: mac80211_hwsim driver support userspace frame tx/rx This patch adds to mac80211_hwsim the capability to send traffic via userspace. Frame exchange between kernel and user spaces is done through generic netlink communication protocol. A new generic netlink family MAC80211_HWSIM is proposed, this family contains three basic commands HWSIM_CMD_REGISTER, which is the command used to register a new traffic listener, HWSIM_CMD_FRAME, to exchange the frames from kernel to user and vice-versa, and HWSIM_CMD_TX_INFO_FRAME which returns from user all the information about retransmissions, rates, rx signal, and so on. How it works: Once the driver is loaded the MAC80211_HWSIM family will be registered. In the absence of userspace daemon, the driver itselfs implements a perfect wireless medium as it did in the past. When a daemon sends a HWSIM_CMD_REGISTER command, the module stores the application PID, and from this moment all frames will be sent to the registered daemon. The user space application will be in charge of process/forward all frames broadcast by any mac80211_hwsim radio. If the user application is stopped, the kernel module will detect the release of the socket and it will switch back to in-kernel perfect channel simulation. The userspace daemon must be waiting for incoming HWSIM_CMD_FRAME commands sent from kernel, for each HWSIM_CMD_FRAME command the application will try to broadcast this frame to all mac80211_hwsim radios, however the application may decide to forward/drop this frame. In the case of forwarding the frame, a new HWSIM_CMD_FRAME command will be created, all necessary attributes will be populated and the frame will be sent back to the kernel. Also after the frame broadcast phase, a HWSIM_CMD_TX_INFO_FRAME command will be sent from userspace to kernel, this command contains all the information regarding the transmission, such as number of tries, rates, ack signal, etc. You can find the actual implementation of wireless mediumd daemon (wmediumd) at: * Last version tarball: https://github.com/jlopex/cozybit/tarball/master * Or visiting my github tree: https://github.com/jlopex/cozybit/tree Signed-off-by: Javier Lopez Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 462 ++++++++++++++++++++++++++++++++-- drivers/net/wireless/mac80211_hwsim.h | 133 ++++++++++ 2 files changed, 580 insertions(+), 15 deletions(-) create mode 100644 drivers/net/wireless/mac80211_hwsim.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 9d4a40ee16c..7e1fa967127 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1,6 +1,7 @@ /* * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 * Copyright (c) 2008, Jouni Malinen + * Copyright (c) 2011, Javier Lopez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -25,11 +26,17 @@ #include #include #include +#include +#include "mac80211_hwsim.h" + +#define WARN_QUEUE 100 +#define MAX_QUEUE 200 MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211"); MODULE_LICENSE("GPL"); +int wmediumd_pid; static int radios = 2; module_param(radios, int, 0444); MODULE_PARM_DESC(radios, "Number of simulated radios"); @@ -302,6 +309,7 @@ struct mac80211_hwsim_data { struct dentry *debugfs; struct dentry *debugfs_ps; + struct sk_buff_head pending; /* packets pending */ /* * Only radios in the same group can communicate together (the * channel has to match too). Each bit represents a group. A @@ -322,6 +330,32 @@ struct hwsim_radiotap_hdr { __le16 rt_chbitmask; } __packed; +/* MAC80211_HWSIM netlinf family */ +static struct genl_family hwsim_genl_family = { + .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = "MAC80211_HWSIM", + .version = 1, + .maxattr = HWSIM_ATTR_MAX, +}; + +/* MAC80211_HWSIM netlink policy */ + +static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { + [HWSIM_ATTR_ADDR_RECEIVER] = { .type = NLA_UNSPEC, + .len = 6*sizeof(u8) }, + [HWSIM_ATTR_ADDR_TRANSMITTER] = { .type = NLA_UNSPEC, + .len = 6*sizeof(u8) }, + [HWSIM_ATTR_FRAME] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_DATA_LEN }, + [HWSIM_ATTR_FLAGS] = { .type = NLA_U32 }, + [HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 }, + [HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 }, + [HWSIM_ATTR_TX_INFO] = { .type = NLA_UNSPEC, + .len = IEEE80211_TX_MAX_RATES*sizeof( + struct hwsim_tx_rate)}, + [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 }, +}; static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, struct net_device *dev) @@ -478,9 +512,89 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data, return md.ret; } +static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, + struct sk_buff *my_skb, + int dst_pid) +{ + struct sk_buff *skb; + struct mac80211_hwsim_data *data = hw->priv; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) my_skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(my_skb); + void *msg_head; + unsigned int hwsim_flags = 0; + int i; + struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; + + if (data->idle) { + wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); + dev_kfree_skb(my_skb); + return; + } + + if (data->ps != PS_DISABLED) + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); + /* If the queue contains MAX_QUEUE skb's drop some */ + if (skb_queue_len(&data->pending) >= MAX_QUEUE) { + /* Droping until WARN_QUEUE level */ + while (skb_queue_len(&data->pending) >= WARN_QUEUE) + skb_dequeue(&data->pending); + } + + skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + if (skb == NULL) + goto nla_put_failure; + + msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, + HWSIM_CMD_FRAME); + if (msg_head == NULL) { + printk(KERN_DEBUG "mac80211_hwsim: problem with msg_head\n"); + goto nla_put_failure; + } + + NLA_PUT(skb, HWSIM_ATTR_ADDR_TRANSMITTER, + sizeof(struct mac_address), data->addresses[1].addr); -static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, - struct sk_buff *skb) + /* We get the skb->data */ + NLA_PUT(skb, HWSIM_ATTR_FRAME, my_skb->len, my_skb->data); + + /* We get the flags for this transmission, and we translate them to + wmediumd flags */ + + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) + hwsim_flags |= HWSIM_TX_CTL_REQ_TX_STATUS; + + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + hwsim_flags |= HWSIM_TX_CTL_NO_ACK; + + NLA_PUT_U32(skb, HWSIM_ATTR_FLAGS, hwsim_flags); + + /* We get the tx control (rate and retries) info*/ + + for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { + tx_attempts[i].idx = info->status.rates[i].idx; + tx_attempts[i].count = info->status.rates[i].count; + } + + NLA_PUT(skb, HWSIM_ATTR_TX_INFO, + sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES, + tx_attempts); + + /* We create a cookie to identify this skb */ + NLA_PUT_U64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb); + + genlmsg_end(skb, msg_head); + genlmsg_unicast(&init_net, skb, dst_pid); + + /* Enqueue the packet */ + skb_queue_tail(&data->pending, my_skb); + return; + +nla_put_failure: + printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); +} + +static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, + struct sk_buff *skb) { struct mac80211_hwsim_data *data = hw->priv, *data2; bool ack = false; @@ -540,11 +654,11 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, return ack; } - static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { bool ack; struct ieee80211_tx_info *txi; + int _pid; mac80211_hwsim_monitor_rx(hw, skb); @@ -554,7 +668,15 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return; } - ack = mac80211_hwsim_tx_frame(hw, skb); + /* wmediumd mode check */ + _pid = wmediumd_pid; + + if (_pid) + return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); + + /* NO wmediumd detected, perfect medium simulation */ + ack = mac80211_hwsim_tx_frame_no_nl(hw, skb); + if (ack && skb->len >= 16) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; mac80211_hwsim_monitor_ack(hw, hdr->addr2); @@ -635,6 +757,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, struct ieee80211_hw *hw = arg; struct sk_buff *skb; struct ieee80211_tx_info *info; + int _pid; hwsim_check_magic(vif); @@ -649,7 +772,14 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, info = IEEE80211_SKB_CB(skb); mac80211_hwsim_monitor_rx(hw, skb); - mac80211_hwsim_tx_frame(hw, skb); + + /* wmediumd mode check */ + _pid = wmediumd_pid; + + if (_pid) + return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); + + mac80211_hwsim_tx_frame_no_nl(hw, skb); dev_kfree_skb(skb); } @@ -966,12 +1096,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw, static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) { - /* - * In this special case, there's nothing we need to - * do because hwsim does transmission synchronously. - * In the future, when it does transmissions via - * userspace, we may need to do something. - */ + /* Not implemented, queues only on kernel side */ } struct hw_scan_done { @@ -1119,6 +1244,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct sk_buff *skb; struct ieee80211_pspoll *pspoll; + int _pid; if (!vp->assoc) return; @@ -1137,8 +1263,15 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) pspoll->aid = cpu_to_le16(0xc000 | vp->aid); memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); memcpy(pspoll->ta, mac, ETH_ALEN); - if (!mac80211_hwsim_tx_frame(data->hw, skb)) - printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__); + + /* wmediumd mode check */ + _pid = wmediumd_pid; + + if (_pid) + return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid); + + if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) + printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__); dev_kfree_skb(skb); } @@ -1149,6 +1282,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct sk_buff *skb; struct ieee80211_hdr *hdr; + int _pid; if (!vp->assoc) return; @@ -1168,7 +1302,14 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, memcpy(hdr->addr1, vp->bssid, ETH_ALEN); memcpy(hdr->addr2, mac, ETH_ALEN); memcpy(hdr->addr3, vp->bssid, ETH_ALEN); - if (!mac80211_hwsim_tx_frame(data->hw, skb)) + + /* wmediumd mode check */ + _pid = wmediumd_pid; + + if (_pid) + return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid); + + if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); dev_kfree_skb(skb); } @@ -1248,6 +1389,273 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group, hwsim_fops_group_read, hwsim_fops_group_write, "%llx\n"); +struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr( + struct mac_address *addr) +{ + struct mac80211_hwsim_data *data; + bool _found = false; + + spin_lock_bh(&hwsim_radio_lock); + list_for_each_entry(data, &hwsim_radios, list) { + if (memcmp(data->addresses[1].addr, addr, + sizeof(struct mac_address)) == 0) { + _found = true; + break; + } + } + spin_unlock_bh(&hwsim_radio_lock); + + if (!_found) + return NULL; + + return data; +} + +static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, + struct genl_info *info) +{ + + struct ieee80211_hdr *hdr; + struct mac80211_hwsim_data *data2; + struct ieee80211_tx_info *txi; + struct hwsim_tx_rate *tx_attempts; + struct sk_buff __user *ret_skb; + struct sk_buff *skb, *tmp; + struct mac_address *src; + unsigned int hwsim_flags; + + int i; + bool found = false; + + if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || + !info->attrs[HWSIM_ATTR_FLAGS] || + !info->attrs[HWSIM_ATTR_COOKIE] || + !info->attrs[HWSIM_ATTR_TX_INFO]) + goto out; + + src = (struct mac_address *)nla_data( + info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); + hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]); + + ret_skb = (struct sk_buff __user *) + (unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); + + data2 = get_hwsim_data_ref_from_addr(src); + + if (data2 == NULL) + goto out; + + /* look for the skb matching the cookie passed back from user */ + skb_queue_walk_safe(&data2->pending, skb, tmp) { + if (skb == ret_skb) { + skb_unlink(skb, &data2->pending); + found = true; + break; + } + } + + /* not found */ + if (!found) + goto out; + + /* Tx info received because the frame was broadcasted on user space, + so we get all the necessary info: tx attempts and skb control buff */ + + tx_attempts = (struct hwsim_tx_rate *)nla_data( + info->attrs[HWSIM_ATTR_TX_INFO]); + + /* now send back TX status */ + txi = IEEE80211_SKB_CB(skb); + + if (txi->control.vif) + hwsim_check_magic(txi->control.vif); + if (txi->control.sta) + hwsim_check_sta_magic(txi->control.sta); + + ieee80211_tx_info_clear_status(txi); + + for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { + txi->status.rates[i].idx = tx_attempts[i].idx; + txi->status.rates[i].count = tx_attempts[i].count; + /*txi->status.rates[i].flags = 0;*/ + } + + txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); + + if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) && + (hwsim_flags & HWSIM_TX_STAT_ACK)) { + if (skb->len >= 16) { + hdr = (struct ieee80211_hdr *) skb->data; + mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); + } + } + ieee80211_tx_status_irqsafe(data2->hw, skb); + return 0; +out: + return -EINVAL; + +} + +static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, + struct genl_info *info) +{ + + struct mac80211_hwsim_data *data2; + struct ieee80211_rx_status rx_status; + struct mac_address *dst; + int frame_data_len; + char *frame_data; + struct sk_buff *skb = NULL; + + if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || + !info->attrs[HWSIM_ATTR_FRAME] || + !info->attrs[HWSIM_ATTR_RX_RATE] || + !info->attrs[HWSIM_ATTR_SIGNAL]) + goto out; + + dst = (struct mac_address *)nla_data( + info->attrs[HWSIM_ATTR_ADDR_RECEIVER]); + + frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]); + frame_data = (char *)nla_data(info->attrs[HWSIM_ATTR_FRAME]); + + /* Allocate new skb here */ + skb = alloc_skb(frame_data_len, GFP_KERNEL); + if (skb == NULL) + goto err; + + if (frame_data_len <= IEEE80211_MAX_DATA_LEN) { + /* Copy the data */ + memcpy(skb_put(skb, frame_data_len), frame_data, + frame_data_len); + } else + goto err; + + data2 = get_hwsim_data_ref_from_addr(dst); + + if (data2 == NULL) + goto out; + + /* check if radio is configured properly */ + + if (data2->idle || !data2->started || !data2->channel) + goto out; + + /*A frame is received from user space*/ + memset(&rx_status, 0, sizeof(rx_status)); + rx_status.freq = data2->channel->center_freq; + rx_status.band = data2->channel->band; + rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); + rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); + + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(data2->hw, skb); + + return 0; +err: + printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); + goto out; +out: + dev_kfree_skb(skb); + return -EINVAL; +} + +static int hwsim_register_received_nl(struct sk_buff *skb_2, + struct genl_info *info) +{ + if (info == NULL) + goto out; + + wmediumd_pid = info->snd_pid; + + printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, " + "switching to wmediumd mode with pid %d\n", info->snd_pid); + + return 0; +out: + printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); + return -EINVAL; +} + +/* Generic Netlink operations array */ +static struct genl_ops hwsim_ops[] = { + { + .cmd = HWSIM_CMD_REGISTER, + .policy = hwsim_genl_policy, + .doit = hwsim_register_received_nl, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = HWSIM_CMD_FRAME, + .policy = hwsim_genl_policy, + .doit = hwsim_cloned_frame_received_nl, + }, + { + .cmd = HWSIM_CMD_TX_INFO_FRAME, + .policy = hwsim_genl_policy, + .doit = hwsim_tx_info_frame_received_nl, + }, +}; + +static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, + unsigned long state, + void *_notify) +{ + struct netlink_notify *notify = _notify; + + if (state != NETLINK_URELEASE) + return NOTIFY_DONE; + + if (notify->pid == wmediumd_pid) { + printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink" + " socket, switching to perfect channel medium\n"); + wmediumd_pid = 0; + } + return NOTIFY_DONE; + +} + +static struct notifier_block hwsim_netlink_notifier = { + .notifier_call = mac80211_hwsim_netlink_notify, +}; + +static int hwsim_init_netlink(void) +{ + int rc; + printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); + + wmediumd_pid = 0; + + rc = genl_register_family_with_ops(&hwsim_genl_family, + hwsim_ops, ARRAY_SIZE(hwsim_ops)); + if (rc) + goto failure; + + rc = netlink_register_notifier(&hwsim_netlink_notifier); + if (rc) + goto failure; + + return 0; + +failure: + printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); + return -EINVAL; +} + +static void hwsim_exit_netlink(void) +{ + int ret; + + printk(KERN_INFO "mac80211_hwsim: closing netlink\n"); + /* unregister the notifier */ + netlink_unregister_notifier(&hwsim_netlink_notifier); + /* unregister the family */ + ret = genl_unregister_family(&hwsim_genl_family); + if (ret) + printk(KERN_DEBUG "mac80211_hwsim: " + "unregister family %i\n", ret); +} + static int __init init_mac80211_hwsim(void) { int i, err = 0; @@ -1298,6 +1706,7 @@ static int __init init_mac80211_hwsim(void) goto failed_drvdata; } data->dev->driver = &mac80211_hwsim_driver; + skb_queue_head_init(&data->pending); SET_IEEE80211_DEV(hw, data->dev); addr[3] = i >> 8; @@ -1379,6 +1788,10 @@ static int __init init_mac80211_hwsim(void) data->group = 1; mutex_init(&data->mutex); + /* Enable frame retransmissions for lossy channels */ + hw->max_rates = 4; + hw->max_rate_tries = 11; + /* Work to be done prior to ieee80211_register_hw() */ switch (regtest) { case HWSIM_REGTEST_DISABLED: @@ -1515,12 +1928,29 @@ static int __init init_mac80211_hwsim(void) if (hwsim_mon == NULL) goto failed; - err = register_netdev(hwsim_mon); + rtnl_lock(); + + err = dev_alloc_name(hwsim_mon, hwsim_mon->name); if (err < 0) goto failed_mon; + + err = register_netdevice(hwsim_mon); + if (err < 0) + goto failed_mon; + + rtnl_unlock(); + + err = hwsim_init_netlink(); + if (err < 0) + goto failed_nl; + return 0; +failed_nl: + printk(KERN_DEBUG "mac_80211_hwsim: failed initializing netlink\n"); + return err; + failed_mon: rtnl_unlock(); free_netdev(hwsim_mon); @@ -1541,6 +1971,8 @@ static void __exit exit_mac80211_hwsim(void) { printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); + hwsim_exit_netlink(); + mac80211_hwsim_free(); unregister_netdev(hwsim_mon); } diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h new file mode 100644 index 00000000000..afaad5a443b --- /dev/null +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -0,0 +1,133 @@ +/* + * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 + * Copyright (c) 2008, Jouni Malinen + * Copyright (c) 2011, Javier Lopez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __MAC80211_HWSIM_H +#define __MAC80211_HWSIM_H + +/** + * enum hwsim_tx_control_flags - flags to describe transmission info/status + * + * These flags are used to give the wmediumd extra information in order to + * modify its behavior for each frame + * + * @HWSIM_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame. + * @HWSIM_TX_CTL_NO_ACK: tell the wmediumd not to wait for an ack + * @HWSIM_TX_STAT_ACK: Frame was acknowledged + * + */ +enum hwsim_tx_control_flags { + HWSIM_TX_CTL_REQ_TX_STATUS = BIT(0), + HWSIM_TX_CTL_NO_ACK = BIT(1), + HWSIM_TX_STAT_ACK = BIT(2), +}; + +/** + * DOC: Frame transmission/registration support + * + * Frame transmission and registration support exists to allow userspace + * entities such as wmediumd to receive and process all broadcasted + * frames from a mac80211_hwsim radio device. + * + * This allow user space applications to decide if the frame should be + * dropped or not and implement a wireless medium simulator at user space. + * + * Registration is done by sending a register message to the driver and + * will be automatically unregistered if the user application doesn't + * responds to sent frames. + * Once registered the user application has to take responsibility of + * broadcasting the frames to all listening mac80211_hwsim radio + * interfaces. + * + * For more technical details, see the corresponding command descriptions + * below. + */ + +/** + * enum hwsim_commands - supported hwsim commands + * + * @HWSIM_CMD_UNSPEC: unspecified command to catch errors + * + * @HWSIM_CMD_REGISTER: request to register and received all broadcasted + * frames by any mac80211_hwsim radio device. + * @HWSIM_CMD_FRAME: send/receive a broadcasted frame from/to kernel/user + * space, uses: + * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER, + * %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE, + * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE + * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to + * kernel, uses: + * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, + * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE + * @__HWSIM_CMD_MAX: enum limit + */ +enum { + HWSIM_CMD_UNSPEC, + HWSIM_CMD_REGISTER, + HWSIM_CMD_FRAME, + HWSIM_CMD_TX_INFO_FRAME, + __HWSIM_CMD_MAX, +}; +#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) + +/** + * enum hwsim_attrs - hwsim netlink attributes + * + * @HWSIM_ATTR_UNSPEC: unspecified attribute to catch errors + * + * @HWSIM_ATTR_ADDR_RECEIVER: MAC address of the radio device that + * the frame is broadcasted to + * @HWSIM_ATTR_ADDR_TRANSMITTER: MAC address of the radio device that + * the frame was broadcasted from + * @HWSIM_ATTR_FRAME: Data array + * @HWSIM_ATTR_FLAGS: mac80211 transmission flags, used to process + properly the frame at user space + * @HWSIM_ATTR_RX_RATE: estimated rx rate index for this frame at user + space + * @HWSIM_ATTR_SIGNAL: estimated RX signal for this frame at user + space + * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array + * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame + * @__HWSIM_ATTR_MAX: enum limit + */ + + +enum { + HWSIM_ATTR_UNSPEC, + HWSIM_ATTR_ADDR_RECEIVER, + HWSIM_ATTR_ADDR_TRANSMITTER, + HWSIM_ATTR_FRAME, + HWSIM_ATTR_FLAGS, + HWSIM_ATTR_RX_RATE, + HWSIM_ATTR_SIGNAL, + HWSIM_ATTR_TX_INFO, + HWSIM_ATTR_COOKIE, + __HWSIM_ATTR_MAX, +}; +#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) + +/** + * struct hwsim_tx_rate - rate selection/status + * + * @idx: rate index to attempt to send with + * @count: number of tries in this rate before going to the next rate + * + * A value of -1 for @idx indicates an invalid rate and, if used + * in an array of retry rates, that no more rates should be tried. + * + * When used for transmit status reporting, the driver should + * always report the rate and number of retries used. + * + */ +struct hwsim_tx_rate { + s8 idx; + u8 count; +} __packed; + +#endif /* __MAC80211_HWSIM_H */ -- cgit v1.2.3-70-g09d2 From e62ddec94a1e11ab1043b607e20ae0d142069132 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 19 May 2011 15:05:46 +0530 Subject: ath9k: remove redundant if check Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2ca351fe6d3..3a6bed0f00b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -515,24 +515,19 @@ void ath_ani_calibrate(unsigned long data) common->ani.checkani_timer = timestamp; } - /* Skip all processing if there's nothing to do. */ - if (longcal || shortcal || aniflag) { - /* Call ANI routine if necessary */ - if (aniflag) { - spin_lock_irqsave(&common->cc_lock, flags); - ath9k_hw_ani_monitor(ah, ah->curchan); - ath_update_survey_stats(sc); - spin_unlock_irqrestore(&common->cc_lock, flags); - } + /* Call ANI routine if necessary */ + if (aniflag) { + spin_lock_irqsave(&common->cc_lock, flags); + ath9k_hw_ani_monitor(ah, ah->curchan); + ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + } - /* Perform calibration if necessary */ - if (longcal || shortcal) { - common->ani.caldone = - ath9k_hw_calibrate(ah, - ah->curchan, - common->rx_chainmask, - longcal); - } + /* Perform calibration if necessary */ + if (longcal || shortcal) { + common->ani.caldone = + ath9k_hw_calibrate(ah, ah->curchan, + common->rx_chainmask, longcal); } ath9k_ps_restore(sc); -- cgit v1.2.3-70-g09d2 From fce041beb03f93c7a771f0b4b6c45bb71ef90901 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 19 May 2011 12:20:25 +0200 Subject: ath9k: unify edma and non-edma tx code, improve tx fifo handling EDMA based chips (AR9380+) have 8 Tx FIFO slots, which are used to fix the tx queue start/stop race conditions which have to be worked around for earlier chips by keeping the last descriptor in the queue. The current code stores all frames that do not fit onto the 8 FIFO slots in a separate list. Whenever a FIFO slot is freed up, the next frame (or A-MPDU) from the pending queue gets moved to that slot. This process is not only inefficient, but also unnecessary. The code can be improved visibly by keeping the pending queue fully linked, and moving the contents of the entire queue to a FIFO slot as it becomes available. This patch makes the necessary changes for that and also merges some code that was duplicated for EDMA vs non-EDMA. It changes txq->axq_link to point to the last descriptor instead of the link pointer, so that ath9k_hw_set_desc_link can be used, which works on all chips. With this patch, a small performance increase for non-aggregated traffic was observed on AR9380 based embedded hardware. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +- drivers/net/wireless/ath/ath9k/debug.c | 1 - drivers/net/wireless/ath/ath9k/main.c | 2 - drivers/net/wireless/ath/ath9k/xmit.c | 338 +++++++++++++-------------------- 4 files changed, 138 insertions(+), 206 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f75068b4b31..41e7f383e89 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -179,7 +179,7 @@ enum ATH_AGGR_STATUS { struct ath_txq { int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ u32 axq_qnum; /* ath9k hardware queue number */ - u32 *axq_link; + void *axq_link; struct list_head axq_q; spinlock_t axq_lock; u32 axq_depth; @@ -188,7 +188,6 @@ struct ath_txq { bool axq_tx_inprogress; struct list_head axq_acq; struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; - struct list_head txq_fifo_pending; u8 txq_headidx; u8 txq_tailidx; int pending_frames; diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index d55ffd7d4bd..202399d4fe1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -587,7 +587,6 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PRQLE("axq_q empty: ", axq_q); PRQLE("axq_acq empty: ", axq_acq); - PRQLE("txq_fifo_pending: ", txq_fifo_pending); for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); PRQLE(tmp, txq_fifo[i]); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3a6bed0f00b..05a909443e1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -62,8 +62,6 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) if (txq->axq_depth || !list_empty(&txq->axq_acq)) pending = true; - else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) - pending = !list_empty(&txq->txq_fifo_pending); spin_unlock_bh(&txq->axq_lock); return pending; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3779b8977d4..ec012b4317a 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -53,7 +53,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, struct ath_txq *txq, struct list_head *bf_q, struct ath_tx_status *ts, int txok, int sendbar); static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, - struct list_head *head); + struct list_head *head, bool internal); static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int nframes, int nbad, @@ -377,8 +377,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, bf_next = bf->bf_next; bf->bf_state.bf_type |= BUF_XRETRY; - if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || - !bf->bf_stale || bf_next != NULL) + if (!bf->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); @@ -463,20 +462,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, } } - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && - bf_next == NULL) { - /* - * Make sure the last desc is reclaimed if it - * not a holding desc. - */ - if (!bf_last->bf_stale) - list_move_tail(&bf->list, &bf_head); - else - INIT_LIST_HEAD(&bf_head); - } else { - BUG_ON(list_empty(bf_q)); + /* + * Make sure the last desc is reclaimed if it + * not a holding desc. + */ + if (!bf_last->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); - } + else + INIT_LIST_HEAD(&bf_head); if (!txpending || (tid->state & AGGR_CLEANUP)) { /* @@ -837,7 +830,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, bf->bf_state.bf_type &= ~BUF_AGGR; ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); ath_buf_set_rate(sc, bf, fi->framelen); - ath_tx_txqaddbuf(sc, txq, &bf_q); + ath_tx_txqaddbuf(sc, txq, &bf_q, false); continue; } @@ -849,7 +842,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, /* anchor last desc of aggregate */ ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); - ath_tx_txqaddbuf(sc, txq, &bf_q); + ath_tx_txqaddbuf(sc, txq, &bf_q, false); TX_STAT_INC(txq->axq_qnum, a_aggr); } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && @@ -1085,7 +1078,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) txq->txq_headidx = txq->txq_tailidx = 0; for (i = 0; i < ATH_TXFIFO_DEPTH; i++) INIT_LIST_HEAD(&txq->txq_fifo[i]); - INIT_LIST_HEAD(&txq->txq_fifo_pending); } return &sc->tx.txq[axq_qnum]; } @@ -1155,13 +1147,8 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf) return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); } -/* - * Drain a given TX queue (could be Beacon or Data) - * - * This assumes output has been stopped and - * we do not need to block ath_tx_tasklet. - */ -void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) +static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, + struct list_head *list, bool retry_tx) { struct ath_buf *bf, *lastbf; struct list_head bf_head; @@ -1170,93 +1157,63 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) memset(&ts, 0, sizeof(ts)); INIT_LIST_HEAD(&bf_head); - for (;;) { - spin_lock_bh(&txq->axq_lock); + while (!list_empty(list)) { + bf = list_first_entry(list, struct ath_buf, list); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { - txq->txq_headidx = txq->txq_tailidx = 0; - spin_unlock_bh(&txq->axq_lock); - break; - } else { - bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], - struct ath_buf, list); - } - } else { - if (list_empty(&txq->axq_q)) { - txq->axq_link = NULL; - spin_unlock_bh(&txq->axq_lock); - break; - } - bf = list_first_entry(&txq->axq_q, struct ath_buf, - list); - - if (bf->bf_stale) { - list_del(&bf->list); - spin_unlock_bh(&txq->axq_lock); + if (bf->bf_stale) { + list_del(&bf->list); - ath_tx_return_buffer(sc, bf); - continue; - } + ath_tx_return_buffer(sc, bf); + continue; } lastbf = bf->bf_lastbf; - - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - list_cut_position(&bf_head, - &txq->txq_fifo[txq->txq_tailidx], - &lastbf->list); - INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); - } else { - /* remove ath_buf's of the same mpdu from txq */ - list_cut_position(&bf_head, &txq->axq_q, &lastbf->list); - } + list_cut_position(&bf_head, list, &lastbf->list); txq->axq_depth--; if (bf_is_ampdu_not_probing(bf)) txq->axq_ampdu_depth--; - spin_unlock_bh(&txq->axq_lock); + spin_unlock_bh(&txq->axq_lock); if (bf_isampdu(bf)) ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, retry_tx); else ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); + spin_lock_bh(&txq->axq_lock); } +} +/* + * Drain a given TX queue (could be Beacon or Data) + * + * This assumes output has been stopped and + * we do not need to block ath_tx_tasklet. + */ +void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) +{ spin_lock_bh(&txq->axq_lock); - txq->axq_tx_inprogress = false; - spin_unlock_bh(&txq->axq_lock); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - spin_lock_bh(&txq->axq_lock); - while (!list_empty(&txq->txq_fifo_pending)) { - bf = list_first_entry(&txq->txq_fifo_pending, - struct ath_buf, list); - list_cut_position(&bf_head, - &txq->txq_fifo_pending, - &bf->bf_lastbf->list); - spin_unlock_bh(&txq->axq_lock); + int idx = txq->txq_tailidx; - if (bf_isampdu(bf)) - ath_tx_complete_aggr(sc, txq, bf, &bf_head, - &ts, 0, retry_tx); - else - ath_tx_complete_buf(sc, bf, txq, &bf_head, - &ts, 0, 0); - spin_lock_bh(&txq->axq_lock); + while (!list_empty(&txq->txq_fifo[idx])) { + ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx], + retry_tx); + + INCR(idx, ATH_TXFIFO_DEPTH); } - spin_unlock_bh(&txq->axq_lock); + txq->txq_tailidx = idx; } + txq->axq_link = NULL; + txq->axq_tx_inprogress = false; + ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); + /* flush any pending frames if aggregation is enabled */ - if (sc->sc_flags & SC_OP_TXAGGR) { - if (!retry_tx) { - spin_lock_bh(&txq->axq_lock); - ath_txq_drain_pending_buffers(sc, txq); - spin_unlock_bh(&txq->axq_lock); - } - } + if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) + ath_txq_drain_pending_buffers(sc, txq); + + spin_unlock_bh(&txq->axq_lock); } bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) @@ -1370,11 +1327,13 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) * assume the descriptors are already chained together by caller. */ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, - struct list_head *head) + struct list_head *head, bool internal) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - struct ath_buf *bf; + struct ath_buf *bf, *bf_last; + bool puttxbuf = false; + bool edma; /* * Insert the frame on the outbound list and @@ -1384,51 +1343,49 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, if (list_empty(head)) return; + edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); bf = list_first_entry(head, struct ath_buf, list); + bf_last = list_entry(head->prev, struct ath_buf, list); ath_dbg(common, ATH_DBG_QUEUE, "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - if (txq->axq_depth >= ATH_TXFIFO_DEPTH) { - list_splice_tail_init(head, &txq->txq_fifo_pending); - return; - } - if (!list_empty(&txq->txq_fifo[txq->txq_headidx])) - ath_dbg(common, ATH_DBG_XMIT, - "Initializing tx fifo %d which is non-empty\n", - txq->txq_headidx); - INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]); - list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]); + if (edma && list_empty(&txq->txq_fifo[txq->txq_headidx])) { + list_splice_tail_init(head, &txq->txq_fifo[txq->txq_headidx]); INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH); - TX_STAT_INC(txq->axq_qnum, puttxbuf); - ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); - ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", - txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); + puttxbuf = true; } else { list_splice_tail_init(head, &txq->axq_q); - if (txq->axq_link == NULL) { - TX_STAT_INC(txq->axq_qnum, puttxbuf); - ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); - ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", - txq->axq_qnum, ito64(bf->bf_daddr), - bf->bf_desc); - } else { - *txq->axq_link = bf->bf_daddr; + if (txq->axq_link) { + ath9k_hw_set_desc_link(ah, txq->axq_link, bf->bf_daddr); ath_dbg(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n", txq->axq_qnum, txq->axq_link, ito64(bf->bf_daddr), bf->bf_desc); - } - ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc, - &txq->axq_link); + } else if (!edma) + puttxbuf = true; + + txq->axq_link = bf_last->bf_desc; + } + + if (puttxbuf) { + TX_STAT_INC(txq->axq_qnum, puttxbuf); + ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); + ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", + txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); + } + + if (!edma) { TX_STAT_INC(txq->axq_qnum, txstart); ath9k_hw_txstart(ah, txq->axq_qnum); } - txq->axq_depth++; - if (bf_is_ampdu_not_probing(bf)) - txq->axq_ampdu_depth++; + + if (!internal) { + txq->axq_depth++; + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth++; + } } static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, @@ -1470,7 +1427,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); bf->bf_lastbf = bf; ath_buf_set_rate(sc, bf, fi->framelen); - ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); + ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); } static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, @@ -1490,7 +1447,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, bf->bf_lastbf = bf; fi = get_frame_info(bf->bf_mpdu); ath_buf_set_rate(sc, bf, fi->framelen); - ath_tx_txqaddbuf(sc, txq, bf_head); + ath_tx_txqaddbuf(sc, txq, bf_head, false); TX_STAT_INC(txq->axq_qnum, queued); } @@ -2077,6 +2034,38 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; } +static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, + struct ath_tx_status *ts, struct ath_buf *bf, + struct list_head *bf_head) +{ + int txok; + + txq->axq_depth--; + txok = !(ts->ts_status & ATH9K_TXERR_MASK); + txq->axq_tx_inprogress = false; + if (bf_is_ampdu_not_probing(bf)) + txq->axq_ampdu_depth--; + + spin_unlock_bh(&txq->axq_lock); + + if (!bf_isampdu(bf)) { + /* + * This frame is sent out as a single frame. + * Use hardware retry status for this frame. + */ + if (ts->ts_status & ATH9K_TXERR_XRETRY) + bf->bf_state.bf_type |= BUF_XRETRY; + ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true); + ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0); + } else + ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); + + spin_lock_bh(&txq->axq_lock); + + if (sc->sc_flags & SC_OP_TXAGGR) + ath_txq_schedule(sc, txq); +} + static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) { struct ath_hw *ah = sc->sc_ah; @@ -2085,20 +2074,18 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) struct list_head bf_head; struct ath_desc *ds; struct ath_tx_status ts; - int txok; int status; ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), txq->axq_link); + spin_lock_bh(&txq->axq_lock); for (;;) { - spin_lock_bh(&txq->axq_lock); if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; if (sc->sc_flags & SC_OP_TXAGGR) ath_txq_schedule(sc, txq); - spin_unlock_bh(&txq->axq_lock); break; } bf = list_first_entry(&txq->axq_q, struct ath_buf, list); @@ -2114,13 +2101,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) bf_held = NULL; if (bf->bf_stale) { bf_held = bf; - if (list_is_last(&bf_held->list, &txq->axq_q)) { - spin_unlock_bh(&txq->axq_lock); + if (list_is_last(&bf_held->list, &txq->axq_q)) break; - } else { - bf = list_entry(bf_held->list.next, - struct ath_buf, list); - } + + bf = list_entry(bf_held->list.next, struct ath_buf, + list); } lastbf = bf->bf_lastbf; @@ -2128,10 +2113,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) memset(&ts, 0, sizeof(ts)); status = ath9k_hw_txprocdesc(ah, ds, &ts); - if (status == -EINPROGRESS) { - spin_unlock_bh(&txq->axq_lock); + if (status == -EINPROGRESS) break; - } + TX_STAT_INC(txq->axq_qnum, txprocdesc); /* @@ -2145,42 +2129,14 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) list_cut_position(&bf_head, &txq->axq_q, lastbf->list.prev); - txq->axq_depth--; - txok = !(ts.ts_status & ATH9K_TXERR_MASK); - txq->axq_tx_inprogress = false; - if (bf_held) + if (bf_held) { list_del(&bf_held->list); - - if (bf_is_ampdu_not_probing(bf)) - txq->axq_ampdu_depth--; - - spin_unlock_bh(&txq->axq_lock); - - if (bf_held) ath_tx_return_buffer(sc, bf_held); - - if (!bf_isampdu(bf)) { - /* - * This frame is sent out as a single frame. - * Use hardware retry status for this frame. - */ - if (ts.ts_status & ATH9K_TXERR_XRETRY) - bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(sc, bf, &ts, 1, txok ? 0 : 1, txok, true); } - if (bf_isampdu(bf)) - ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, - true); - else - ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); - - spin_lock_bh(&txq->axq_lock); - - if (sc->sc_flags & SC_OP_TXAGGR) - ath_txq_schedule(sc, txq); - spin_unlock_bh(&txq->axq_lock); + ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); } + spin_unlock_bh(&txq->axq_lock); } static void ath_tx_complete_poll_work(struct work_struct *work) @@ -2237,17 +2193,16 @@ void ath_tx_tasklet(struct ath_softc *sc) void ath_tx_edma_tasklet(struct ath_softc *sc) { - struct ath_tx_status txs; + struct ath_tx_status ts; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_hw *ah = sc->sc_ah; struct ath_txq *txq; struct ath_buf *bf, *lastbf; struct list_head bf_head; int status; - int txok; for (;;) { - status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); + status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts); if (status == -EINPROGRESS) break; if (status == -EIO) { @@ -2257,12 +2212,13 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) } /* Skip beacon completions */ - if (txs.qid == sc->beacon.beaconq) + if (ts.qid == sc->beacon.beaconq) continue; - txq = &sc->tx.txq[txs.qid]; + txq = &sc->tx.txq[ts.qid]; spin_lock_bh(&txq->axq_lock); + if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { spin_unlock_bh(&txq->axq_lock); return; @@ -2275,41 +2231,21 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) INIT_LIST_HEAD(&bf_head); list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], &lastbf->list); - INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); - txq->axq_depth--; - txq->axq_tx_inprogress = false; - if (bf_is_ampdu_not_probing(bf)) - txq->axq_ampdu_depth--; - spin_unlock_bh(&txq->axq_lock); - txok = !(txs.ts_status & ATH9K_TXERR_MASK); - - if (!bf_isampdu(bf)) { - if (txs.ts_status & ATH9K_TXERR_XRETRY) - bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true); - } - - if (bf_isampdu(bf)) - ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, - txok, true); - else - ath_tx_complete_buf(sc, bf, txq, &bf_head, - &txs, txok, 0); + if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { + INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); - spin_lock_bh(&txq->axq_lock); + if (!list_empty(&txq->axq_q)) { + struct list_head bf_q; - if (!list_empty(&txq->txq_fifo_pending)) { - INIT_LIST_HEAD(&bf_head); - bf = list_first_entry(&txq->txq_fifo_pending, - struct ath_buf, list); - list_cut_position(&bf_head, - &txq->txq_fifo_pending, - &bf->bf_lastbf->list); - ath_tx_txqaddbuf(sc, txq, &bf_head); - } else if (sc->sc_flags & SC_OP_TXAGGR) - ath_txq_schedule(sc, txq); + INIT_LIST_HEAD(&bf_q); + txq->axq_link = NULL; + list_splice_tail_init(&txq->axq_q, &bf_q); + ath_tx_txqaddbuf(sc, txq, &bf_q, true); + } + } + ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); spin_unlock_bh(&txq->axq_lock); } } -- cgit v1.2.3-70-g09d2 From 33e6ef4e82f1de4f9a98a86633412390a322e2e8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 19 May 2011 12:20:26 +0200 Subject: ath9k_hw: remove ath9k_hw_get_desc_link Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 6 ------ drivers/net/wireless/ath/ath9k/ar9003_mac.c | 8 -------- drivers/net/wireless/ath/ath9k/hw-ops.h | 5 ----- drivers/net/wireless/ath/ath9k/hw.h | 1 - 4 files changed, 20 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 077e8a6983f..45b262fe2c2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -28,11 +28,6 @@ static void ar9002_hw_set_desc_link(void *ds, u32 ds_link) ((struct ath_desc*) ds)->ds_link = ds_link; } -static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link) -{ - *ds_link = &((struct ath_desc *)ds)->ds_link; -} - static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) { u32 isr = 0; @@ -437,7 +432,6 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) ops->rx_enable = ar9002_hw_rx_enable; ops->set_desc_link = ar9002_hw_set_desc_link; - ops->get_desc_link = ar9002_hw_get_desc_link; ops->get_isr = ar9002_hw_get_isr; ops->fill_txdesc = ar9002_hw_fill_txdesc; ops->proc_txdesc = ar9002_hw_proc_txdesc; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 10d71f7d3fc..04e6be04acf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -43,13 +43,6 @@ static void ar9003_hw_set_desc_link(void *ds, u32 ds_link) ads->ctl10 |= ar9003_calc_ptr_chksum(ads); } -static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link) -{ - struct ar9003_txc *ads = ds; - - *ds_link = &ads->link; -} - static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) { u32 isr = 0; @@ -498,7 +491,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) ops->rx_enable = ar9003_hw_rx_enable; ops->set_desc_link = ar9003_hw_set_desc_link; - ops->get_desc_link = ar9003_hw_get_desc_link; ops->get_isr = ar9003_hw_get_isr; ops->fill_txdesc = ar9003_hw_fill_txdesc; ops->proc_txdesc = ar9003_hw_proc_txdesc; diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 2f3e07263fc..cb29e887538 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -39,11 +39,6 @@ static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set_desc_link(ds, link); } -static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds, - u32 **link) -{ - ath9k_hw_ops(ah)->get_desc_link(ds, link); -} static inline bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 4b157c53d1a..d8381785413 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -603,7 +603,6 @@ struct ath_hw_ops { int power_off); void (*rx_enable)(struct ath_hw *ah); void (*set_desc_link)(void *ds, u32 link); - void (*get_desc_link)(void *ds, u32 **link); bool (*calibrate)(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, -- cgit v1.2.3-70-g09d2 From 6d79cb4ca3ff212984c1f9751accf2f033163be9 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 19 May 2011 17:40:46 +0530 Subject: ath9k: make ath9k_setpower function as static Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/main.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 41e7f383e89..c2ac12b2df7 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -673,7 +673,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); -bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); bool ath9k_uses_beacons(int type); #ifdef CONFIG_ATH9K_PCI diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 05a909443e1..097225d2505 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -67,7 +67,7 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) return pending; } -bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) +static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) { unsigned long flags; bool ret; -- cgit v1.2.3-70-g09d2 From 5595f119649b3178c03479baa794113b8533158a Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 19 May 2011 18:08:57 +0530 Subject: ath9k: mark few functions as static Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 --- drivers/net/wireless/ath/ath9k/main.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c2ac12b2df7..4cc78449ed9 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -668,10 +668,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops); void ath9k_deinit_device(struct ath_softc *sc); void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); -int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, - struct ath9k_channel *hchan); -void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); bool ath9k_uses_beacons(int type); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 097225d2505..15e5f3199d1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -217,7 +217,7 @@ static int ath_update_survey_stats(struct ath_softc *sc) * by reseting the chip. To accomplish this we must first cleanup any pending * DMA, then restart stuff. */ -int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, +static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, struct ath9k_channel *hchan) { struct ath_hw *ah = sc->sc_ah; @@ -861,7 +861,7 @@ chip_reset: #undef SCHED_INTR } -void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) +static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -2327,7 +2327,7 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) return false; } -int ath9k_tx_last_beacon(struct ieee80211_hw *hw) +static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; -- cgit v1.2.3-70-g09d2 From 6ac53692179da165b2cb1e2a122b0ed9dad9b9ad Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 19 May 2011 15:11:24 +0200 Subject: b43: LP-PHY: use new pointers path to access ssb_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LP-PHY code is SSB specific, add check for bus type. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lp.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 2606c25e574..daec1d9e4a1 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -214,7 +214,7 @@ static void lpphy_table_init(struct b43_wldev *dev) static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy_lp *lpphy = dev->phy.lp; u16 tmp, tmp2; @@ -519,7 +519,7 @@ struct b2062_freqdata { static void lpphy_2062_init(struct b43_wldev *dev) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; u32 crystalfreq, tmp, ref; unsigned int i; const struct b2062_freqdata *fd = NULL; @@ -1289,7 +1289,7 @@ finish: static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; int i; @@ -2428,7 +2428,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev, unsigned int channel) { struct b43_phy_lp *lpphy = dev->phy.lp; - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; const struct b206x_channel *chandata = NULL; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; @@ -2518,7 +2518,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev) static int lpphy_b2063_tune(struct b43_wldev *dev, unsigned int channel) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; static const struct b206x_channel *chandata = NULL; u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; @@ -2666,6 +2666,11 @@ static int b43_lpphy_op_init(struct b43_wldev *dev) { int err; + if (dev->dev->bus_type != B43_BUS_SSB) { + b43err(dev->wl, "LP-PHY is supported only on SSB!\n"); + return -EOPNOTSUPP; + } + lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? lpphy_baseband_init(dev); lpphy_radio_init(dev); -- cgit v1.2.3-70-g09d2 From 02a0fbe4dcb4c318d09d97b19e51f48ba6d36ede Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 19 May 2011 15:11:25 +0200 Subject: b43: SDIO: use new pointers path to access ssb_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SDIO code is SSB specific, we can safely just use "sdev" Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/sdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 808e25b7970..e6c733d37c9 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c @@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func) int b43_sdio_request_irq(struct b43_wldev *dev, void (*handler)(struct b43_wldev *dev)) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; struct sdio_func *func = bus->host_sdio; struct b43_sdio *sdio = sdio_get_drvdata(func); int err; @@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev, void b43_sdio_free_irq(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; struct sdio_func *func = bus->host_sdio; struct b43_sdio *sdio = sdio_get_drvdata(func); -- cgit v1.2.3-70-g09d2 From d48ae5c826f9af7d8b39867887d48e2a6f47af1f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 19 May 2011 15:11:26 +0200 Subject: b43: use new pointers path to access ssb_device in SSB specific places MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index bb82ddfa44f..99411dadd10 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1146,6 +1146,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) { + struct ssb_device *sdev = dev->dev->sdev; u32 tmslow; flags |= B43_TMSLOW_PHYCLKEN; @@ -1156,15 +1157,15 @@ static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) msleep(2); /* Wait for the PLL to turn on. */ /* Now take the PHY out of Reset again */ - tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); + tmslow = ssb_read32(sdev, SSB_TMSLOW); tmslow |= SSB_TMSLOW_FGC; tmslow &= ~B43_TMSLOW_PHYRESET; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); - ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ + ssb_write32(sdev, SSB_TMSLOW, tmslow); + ssb_read32(sdev, SSB_TMSLOW); /* flush */ msleep(1); tmslow &= ~SSB_TMSLOW_FGC; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); - ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ + ssb_write32(sdev, SSB_TMSLOW, tmslow); + ssb_read32(sdev, SSB_TMSLOW); /* flush */ msleep(1); } @@ -2157,7 +2158,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) switch (dev->phy.type) { case B43_PHYTYPE_A: if ((rev >= 5) && (rev <= 10)) { - tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); + tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) filename = "a0g1initvals5"; else @@ -2202,7 +2203,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) switch (dev->phy.type) { case B43_PHYTYPE_A: if ((rev >= 5) && (rev <= 10)) { - tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); + tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) filename = "a0g1bsinitvals5"; else @@ -2566,7 +2567,7 @@ out: */ static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus = dev->dev->sdev->bus; #ifdef CONFIG_SSB_DRIVER_PCICORE return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); @@ -4231,16 +4232,21 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev) static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; + struct ssb_bus *bus; u32 tmp; + if (dev->dev->bus_type != B43_BUS_SSB) + return; + + bus = dev->dev->sdev->bus; + if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || (bus->chip_id == 0x4312)) { - tmp = ssb_read32(dev->sdev, SSB_IMCFGLO); + tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO); tmp &= ~SSB_IMCFGLO_REQTO; tmp &= ~SSB_IMCFGLO_SERTO; tmp |= 0x3; - ssb_write32(dev->sdev, SSB_IMCFGLO, tmp); + ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp); ssb_commit_settings(bus); } } -- cgit v1.2.3-70-g09d2 From 505fb019d4924e425bb1024eb603a7bc7fe7fe63 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 19 May 2011 15:11:27 +0200 Subject: b43: bus: add helpers for checking host type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.h | 11 +++++++++++ drivers/net/wireless/b43/main.c | 12 ++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index fd88e2b121a..79a5ab4270c 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -46,6 +46,17 @@ struct b43_bus_dev { u8 core_rev; }; +static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev) +{ + return (dev->bus_type == B43_BUS_SSB && + dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA); +} +static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) +{ + return (dev->bus_type == B43_BUS_SSB && + dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); +} + struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); #endif /* B43_BUS_H_ */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 99411dadd10..659bc3169a4 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1645,7 +1645,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) mutex_lock(&wl->mutex); dev = wl->current_dev; if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { /* wl->mutex is enough. */ b43_do_beacon_update_trigger_work(dev); mmiowb(); @@ -3955,7 +3955,7 @@ redo: /* Disable interrupts on the device. */ b43_set_status(dev, B43_STAT_INITIALIZED); - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { /* wl->mutex is locked. That is enough. */ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ @@ -3968,7 +3968,7 @@ redo: /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ orig_dev = dev; mutex_unlock(&wl->mutex); - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { b43_sdio_free_irq(dev); } else { synchronize_irq(dev->dev->irq); @@ -4005,7 +4005,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev) B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); drain_txstatus_queue(dev); - if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { + if (b43_bus_host_is_sdio(dev->dev)) { err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); if (err) { b43err(dev->wl, "Cannot request SDIO IRQ\n"); @@ -4405,8 +4405,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) /* Maximum Contention Window */ b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); - if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) || - (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) || + if (b43_bus_host_is_pcmcia(dev->dev) || + b43_bus_host_is_sdio(dev->dev) || dev->use_pio) { dev->__using_pio_transfers = 1; err = b43_pio_init(dev); -- cgit v1.2.3-70-g09d2 From f29f5c0882bdd58c42b8176ee0b578f92589fda2 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 20 May 2011 17:52:11 +0530 Subject: ath9k: Remove ATH9K_BEACON_PERIOD mask Earlier beacon_interval is used to hold interval value and some flags (ATH9K_BEACON_ENA &ATH9K_BEACON_PERIOD). So to extract interval ATH9K_BEACON_PERIOD is used. Those flags were completely removed. So masking beacon_interval is not required. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 6 +++--- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 8 ++++---- drivers/net/wireless/ath/ath9k/hw.c | 6 +++--- drivers/net/wireless/ath/ath9k/hw.h | 1 - 4 files changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index d4d8ceced89..8b85d7c1d38 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -496,7 +496,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc, u32 nexttbtt, intval; /* NB: the beacon interval is kept internally in TU's */ - intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); + intval = TU_TO_USEC(conf->beacon_interval); intval /= ATH_BCBUF; /* for staggered beacons */ nexttbtt = intval; @@ -543,7 +543,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc, } memset(&bs, 0, sizeof(bs)); - intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; + intval = conf->beacon_interval; /* * Setup dtim and cfp parameters according to @@ -657,7 +657,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, ath9k_reset_beacon_status(sc); tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); - intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); + intval = TU_TO_USEC(conf->beacon_interval); if (!sc->beacon.bc_tstamp) nexttbtt = tsf + intval; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index aa6a7311870..57fe22b2424 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -79,7 +79,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, memset(&bs, 0, sizeof(bs)); - intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; + intval = bss_conf->beacon_interval; bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval); /* @@ -194,7 +194,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, u8 cmd_rsp; u64 tsf; - intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; + intval = bss_conf->beacon_interval; intval /= ATH9K_HTC_MAX_BCN_VIF; nexttbtt = intval; @@ -250,7 +250,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, u8 cmd_rsp; u64 tsf; - intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; + intval = bss_conf->beacon_interval; nexttbtt = intval; /* @@ -427,7 +427,7 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, u16 intval; int slot; - intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; + intval = priv->cur_beacon_conf.beacon_interval; tsf = be64_to_cpu(swba->tsf); tsftu = TSF_TO_TU(tsf >> 32, tsf); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1be7c8bbef8..6de2655e07d 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1785,16 +1785,16 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); REG_WRITE(ah, AR_BEACON_PERIOD, - TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); + TU_TO_USEC(bs->bs_intval)); REG_WRITE(ah, AR_DMA_BEACON_PERIOD, - TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); + TU_TO_USEC(bs->bs_intval)); REGWRITE_BUFFER_FLUSH(ah); REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); - beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD; + beaconintval = bs->bs_intval; if (bs->bs_sleepduration > beaconintval) beaconintval = bs->bs_sleepduration; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index d8381785413..6a6fb543983 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -403,7 +403,6 @@ struct ath9k_beacon_state { u32 bs_nexttbtt; u32 bs_nextdtim; u32 bs_intval; -#define ATH9K_BEACON_PERIOD 0x0000ffff #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ u32 bs_dtimperiod; u16 bs_cfpperiod; -- cgit v1.2.3-70-g09d2 From 2e5ef4599addb1046086b63743f41822858a23b7 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 20 May 2011 17:52:12 +0530 Subject: ath9k: Handle IBSS status changes in BSS_CHANGED_IBSS Configure ibss node's bss_changes under BSS_CHANGED_IBSS. And also start/stop ani timer only if the station join/leave the group. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 85 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 41 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 15e5f3199d1..0c545d38f9d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1405,7 +1405,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, ath9k_hw_set_interrupts(ah, ah->imask); /* Set up ANI */ - if ((iter_data.naps + iter_data.nadhocs) > 0) { + if (iter_data.naps > 0) { sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); @@ -1945,50 +1945,35 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; struct ath_vif *avp = (void *)vif->drv_priv; - switch (sc->sc_ah->opmode) { - case NL80211_IFTYPE_ADHOC: - /* There can be only one vif available */ + /* + * Skip iteration if primary station vif's bss info + * was not changed + */ + if (sc->sc_flags & SC_OP_PRIM_STA_VIF) + return; + + if (bss_conf->assoc) { + sc->sc_flags |= SC_OP_PRIM_STA_VIF; + avp->primary_sta_vif = true; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); common->curaid = bss_conf->aid; ath9k_hw_write_associd(sc->sc_ah); - /* configure beacon */ - if (bss_conf->enable_beacon) - ath_beacon_config(sc, vif); - break; - case NL80211_IFTYPE_STATION: - /* - * Skip iteration if primary station vif's bss info - * was not changed - */ - if (sc->sc_flags & SC_OP_PRIM_STA_VIF) - break; - - if (bss_conf->assoc) { - sc->sc_flags |= SC_OP_PRIM_STA_VIF; - avp->primary_sta_vif = true; - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - common->curaid = bss_conf->aid; - ath9k_hw_write_associd(sc->sc_ah); - ath_dbg(common, ATH_DBG_CONFIG, + ath_dbg(common, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", bss_conf->aid, common->curbssid); - ath_beacon_config(sc, vif); - /* - * Request a re-configuration of Beacon related timers - * on the receipt of the first Beacon frame (i.e., - * after time sync with the AP). - */ - sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; - /* Reset rssi stats */ - sc->last_rssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; + ath_beacon_config(sc, vif); + /* + * Request a re-configuration of Beacon related timers + * on the receipt of the first Beacon frame (i.e., + * after time sync with the AP). + */ + sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; + /* Reset rssi stats */ + sc->last_rssi = ATH_RSSI_DUMMY_MARKER; + sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); - } - break; - default: - break; + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); } } @@ -1998,6 +1983,9 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; struct ath_vif *avp = (void *)vif->drv_priv; + if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) + return; + /* Reconfigure bss info */ if (avp->primary_sta_vif && !bss_conf->assoc) { ath_dbg(common, ATH_DBG_CONFIG, @@ -2016,8 +2004,7 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) * None of station vifs are associated. * Clear bssid & aid */ - if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && - !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { + if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { ath9k_hw_write_associd(sc->sc_ah); /* Stop ANI */ sc->sc_flags &= ~SC_OP_ANI_RUN; @@ -2047,6 +2034,22 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, common->curbssid, common->curaid); } + if (changed & BSS_CHANGED_IBSS) { + /* There can be only one vif available */ + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + common->curaid = bss_conf->aid; + ath9k_hw_write_associd(sc->sc_ah); + + if (bss_conf->ibss_joined) { + sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } else { + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); + } + } + /* Enable transmission of beacons (AP, IBSS, MESH) */ if ((changed & BSS_CHANGED_BEACON) || ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { -- cgit v1.2.3-70-g09d2 From 9c1cacd2c08ede12765e838c35b6d1e9eb900f60 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 22 May 2011 20:54:25 -0500 Subject: b43: Fix warnings from gcc 4.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.6.0 warnings for b43: CC [M] drivers/net/wireless/b43/lo.o drivers/net/wireless/b43/lo.c: In function ‘lo_measure_gain_values’: drivers/net/wireless/b43/lo.c:304:7: warning: variable ‘trsw_rx’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/b43/dma.o drivers/net/wireless/b43/dma.c: In function ‘free_all_descbuffers’: drivers/net/wireless/b43/dma.c:760:30: warning: variable ‘desc’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/b43/dma.c: In function ‘b43_dma_handle_txstatus’: drivers/net/wireless/b43/dma.c:1391:30: warning: variable ‘desc’ set but not used [-Wunused-but-set-variable] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43/dma.c | 8 ++++---- drivers/net/wireless/b43/lo.c | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 11e66cd2e26..d02cf8300e3 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -757,14 +757,14 @@ static void dmacontroller_cleanup(struct b43_dmaring *ring) static void free_all_descbuffers(struct b43_dmaring *ring) { - struct b43_dmadesc_generic *desc; struct b43_dmadesc_meta *meta; int i; if (!ring->used_slots) return; for (i = 0; i < ring->nr_slots; i++) { - desc = ring->ops->idx2desc(ring, i, &meta); + /* get meta - ignore returned value */ + ring->ops->idx2desc(ring, i, &meta); if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) { B43_WARN_ON(!ring->tx); @@ -1388,7 +1388,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, { const struct b43_dma_ops *ops; struct b43_dmaring *ring; - struct b43_dmadesc_generic *desc; struct b43_dmadesc_meta *meta; int slot, firstused; bool frame_succeed; @@ -1416,7 +1415,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, ops = ring->ops; while (1) { B43_WARN_ON(slot < 0 || slot >= ring->nr_slots); - desc = ops->idx2desc(ring, slot, &meta); + /* get meta - ignore returned value */ + ops->idx2desc(ring, slot, &meta); if (b43_dma_ptr_is_poisoned(meta->skb)) { b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) " diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index b32efd45c08..a3dc8bb8ca9 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c @@ -301,14 +301,12 @@ static void lo_measure_gain_values(struct b43_wldev *dev, max_rx_gain = 0; if (has_loopback_gain(phy)) { - int trsw_rx = 0; int trsw_rx_gain; if (use_trsw_rx) { trsw_rx_gain = gphy->trsw_rx_gain / 2; if (max_rx_gain >= trsw_rx_gain) { trsw_rx_gain = max_rx_gain - trsw_rx_gain; - trsw_rx = 0x20; } } else trsw_rx_gain = max_rx_gain; -- cgit v1.2.3-70-g09d2 From 19086fcef1de1fa7350d8122910a506481acf94b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 22 May 2011 20:54:31 -0500 Subject: rtlwifi: Fix warnings from gcc 4.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.6.0 warnings for rtlwifi: CC [M] drivers/net/wireless/rtlwifi/base.o drivers/net/wireless/rtlwifi/base.c: In function ‘rtl_tx_agg_stop’: drivers/net/wireless/rtlwifi/base.c:891:23: warning: variable ‘tid_data’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/base.c: In function ‘rtl_tx_agg_oper’: drivers/net/wireless/rtlwifi/base.c:921:23: warning: variable ‘tid_data’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/efuse.o drivers/net/wireless/rtlwifi/efuse.c: In function ‘efuse_pg_packet_write’: drivers/net/wireless/rtlwifi/efuse.c:928:24: warning: variable ‘dataempty’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/efuse.c: In function ‘efuse_get_current_size’: drivers/net/wireless/rtlwifi/efuse.c:1179:5: warning: variable ‘hoffset’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/ps.o drivers/net/wireless/rtlwifi/ps.c: In function ‘rtl_ps_set_rf_state’: drivers/net/wireless/rtlwifi/ps.c:85:19: warning: variable ‘rtstate’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/regd.o drivers/net/wireless/rtlwifi/regd.c: In function ‘_rtl_dump_channel_map’: drivers/net/wireless/rtlwifi/regd.c:310:28: warning: variable ‘ch’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/usb.o drivers/net/wireless/rtlwifi/usb.c: In function ‘_rtl_usb_transmit’: drivers/net/wireless/rtlwifi/usb.c:826:21: warning: variable ‘urb_list’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/usb.c:825:23: warning: variable ‘skb_list’ set but not used [-Wunused-but-set-variable] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 4 ---- drivers/net/wireless/rtlwifi/efuse.c | 6 ++---- drivers/net/wireless/rtlwifi/ps.c | 3 --- drivers/net/wireless/rtlwifi/regd.c | 18 ------------------ 4 files changed, 2 insertions(+), 29 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index ccb6da38fe2..fb5e43bd7c3 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -888,7 +888,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_tid_data *tid_data; struct rtl_sta_info *sta_entry = NULL; if (sta == NULL) @@ -906,7 +905,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, return -EINVAL; sta_entry = (struct rtl_sta_info *)sta->drv_priv; - tid_data = &sta_entry->tids[tid]; sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); @@ -918,7 +916,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u16 tid) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_tid_data *tid_data; struct rtl_sta_info *sta_entry = NULL; if (sta == NULL) @@ -936,7 +933,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, return -EINVAL; sta_entry = (struct rtl_sta_info *)sta->drv_priv; - tid_data = &sta_entry->tids[tid]; sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL; return 0; diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 50de6f5d8a5..0b562322f13 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -925,7 +925,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct pgpkt_struct target_pkt; u8 write_state = PG_STATE_HEADER; - int continual = true, dataempty = true, result = true; + int continual = true, result = true; u16 efuse_addr = 0; u8 efuse_data; u8 target_word_cnts = 0; @@ -953,7 +953,6 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { if (write_state == PG_STATE_HEADER) { - dataempty = true; badworden = 0x0F; RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER\n")); @@ -1176,13 +1175,12 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw) { int continual = true; u16 efuse_addr = 0; - u8 hoffset, hworden; + u8 hworden; u8 efuse_data, word_cnts; while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_addr < EFUSE_MAX_SIZE)) { if (efuse_data != 0xFF) { - hoffset = (efuse_data >> 4) & 0x0F; hworden = efuse_data & 0x0F; word_cnts = efuse_calculate_word_cnts(hworden); efuse_addr = efuse_addr + (word_cnts * 2) + 1; diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 39b0297ce92..a73ffbe68ba 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -82,7 +82,6 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - enum rf_pwrstate rtstate; bool actionallowed = false; u16 rfwait_cnt = 0; unsigned long flag; @@ -129,8 +128,6 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, } no_protect: - rtstate = ppsc->rfpwr_state; - switch (state_toset) { case ERFON: ppsc->rfoff_reason &= (~changesource); diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index 8f6718f163e..9fedb1f7091 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -303,22 +303,6 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, return; } -static void _rtl_dump_channel_map(struct wiphy *wiphy) -{ - enum ieee80211_band band; - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - unsigned int i; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!wiphy->bands[band]) - continue; - sband = wiphy->bands[band]; - for (i = 0; i < sband->n_channels; i++) - ch = &sband->channels[i]; - } -} - static int _rtl_reg_notifier_apply(struct wiphy *wiphy, struct regulatory_request *request, struct rtl_regulatory *reg) @@ -336,8 +320,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy, break; } - _rtl_dump_channel_map(wiphy); - return 0; } -- cgit v1.2.3-70-g09d2 From c0fda68d00a72895c4ad0871c6f57074b0e4292c Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 22 May 2011 20:54:34 -0500 Subject: rtl8192c-common: Fix warnings from gcc 4.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.6.0 warnings for rtl8192c-common: CC [M] drivers/net/wireless/rtlwifi/rtl8192c/fw_common.o drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c: In function ‘_rtl92c_cmd_send_packet’: drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c:549:5: warning: variable ‘own’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/rtl8192c/phy_common.o drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c: In function ‘_rtl92c_phy_iq_calibrate’: drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c:1256:6: warning: variable ‘bbvalue’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c: In function ‘rtl92c_phy_iq_calibrate’: drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c:1766:6: warning: variable ‘reg_ecc’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c:1765:34: warning: variable ‘reg_eac’ set but not used [-Wunused-but-set-variable] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 12 +++--------- 2 files changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 50303e1adff..f9f2370e925 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -546,7 +546,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl8192_tx_ring *ring; struct rtl_tx_desc *pdesc; - u8 own; unsigned long flags; struct sk_buff *pskb = NULL; @@ -559,7 +558,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); pdesc = &ring->desc[0]; - own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index d2cc81586a6..3b11642d3f7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -1253,10 +1253,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, const u32 retrycount = 2; - u32 bbvalue; - if (t == 0) { - bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); + /* dummy read */ + rtl_get_bbreg(hw, 0x800, MASKDWORD); _rtl92c_phy_save_adda_registers(hw, adda_reg, rtlphy->adda_backup, 16); @@ -1762,8 +1761,7 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) long result[4][8]; u8 i, final_candidate; bool patha_ok, pathb_ok; - long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, - reg_ecc, reg_tmp = 0; + long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, reg_tmp = 0; bool is12simular, is13simular, is23simular; bool start_conttx = false, singletone = false; u32 iqk_bb_reg[10] = { @@ -1841,21 +1839,17 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) reg_e94 = result[i][0]; reg_e9c = result[i][1]; reg_ea4 = result[i][2]; - reg_eac = result[i][3]; reg_eb4 = result[i][4]; reg_ebc = result[i][5]; reg_ec4 = result[i][6]; - reg_ecc = result[i][7]; } if (final_candidate != 0xff) { rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; reg_ea4 = result[final_candidate][2]; - reg_eac = result[final_candidate][3]; rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; reg_ec4 = result[final_candidate][6]; - reg_ecc = result[final_candidate][7]; patha_ok = pathb_ok = true; } else { rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; -- cgit v1.2.3-70-g09d2 From 6c0d4988c7dc23e5e8b22e99ab140e47c716848e Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 22 May 2011 20:54:37 -0500 Subject: rtl8192ce: Fix warnings from gcc 4.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.6.0 warnings for rtl8192ce: CC [M] drivers/net/wireless/rtlwifi/rtl8192ce/hw.o drivers/net/wireless/rtlwifi/rtl8192ce/hw.c: In function ‘_rtl92ce_hw_configure’: drivers/net/wireless/rtlwifi/rtl8192ce/hw.c:766:6: warning: variable ‘reg_ratr’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/rtl8192ce/hw.c: In function ‘rtl92ce_gpio_radio_on_off_checking’: drivers/net/wireless/rtlwifi/rtl8192ce/hw.c:1972:41: warning: variable ‘cur_rfstate’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/rtl8192ce/phy.o drivers/net/wireless/rtlwifi/rtl8192ce/phy.c: In function ‘rtl92c_phy_config_rf_with_headerfile’: drivers/net/wireless/rtlwifi/rtl8192ce/phy.c:284:7: warning: variable ‘rtstatus’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/rtl8192ce/trx.o drivers/net/wireless/rtlwifi/rtl8192ce/trx.c: In function ‘_rtl92ce_translate_rx_signal_stuff’: drivers/net/wireless/rtlwifi/rtl8192ce/trx.c:595:6: warning: variable ‘psaddr’ set but not used [-Wunused-but-set-variable] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 8 ++------ drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 -- 3 files changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index defb4370cf7..d5d3c8a572c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -763,11 +763,9 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); u8 reg_bw_opmode; - u32 reg_ratr, reg_prsr; + u32 reg_prsr; reg_bw_opmode = BW_OPMODE_20MHZ; - reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); @@ -1969,7 +1967,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; + enum rf_pwrstate e_rfpowerstate_toset; u8 u1tmp; bool actuallyset = false; unsigned long flag; @@ -1989,8 +1987,6 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); } - cur_rfstate = ppsc->rfpwr_state; - rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG)&~(BIT(3))); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index abe0fcc7536..c5be547ad71 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -281,7 +281,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, { int i; - bool rtstatus = true; u32 *radioa_array_table; u32 *radiob_array_table; u16 radioa_arraylen, radiob_arraylen; @@ -308,7 +307,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); } RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); - rtstatus = true; switch (rfpath) { case RF90_PATH_A: for (i = 0; i < radioa_arraylen; i = i + 2) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 54b2bd53d36..ac95dc44374 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -592,7 +592,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr; u8 *tmp_buf; u8 *praddr; - u8 *psaddr; __le16 fc; u16 type, c_fc; bool packet_matchbssid, packet_toself, packet_beacon; @@ -604,7 +603,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, c_fc = le16_to_cpu(fc); type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; - psaddr = hdr->addr2; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && -- cgit v1.2.3-70-g09d2 From 52722592b1702687bf24fe69d75f2ef97360fd59 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 22 May 2011 20:54:40 -0500 Subject: rtl8192cu: Fix warnings from gcc 4.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.6.0 warnings for rtl8192cu: CC [M] drivers/net/wireless/rtlwifi/rtl8192cu/mac.o drivers/net/wireless/rtlwifi/rtl8192cu/mac.c: In function ‘rtl92c_translate_rx_signal_stuff’: drivers/net/wireless/rtlwifi/rtl8192cu/mac.c:1116:6: warning: variable ‘psaddr’ set but not used [-Wunused-but-set-variable] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index f8514cba17b..4e057df6f48 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -1113,7 +1113,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr; u8 *tmp_buf; u8 *praddr; - u8 *psaddr; __le16 fc; u16 type, cpu_fc; bool packet_matchbssid, packet_toself, packet_beacon; @@ -1124,7 +1123,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, cpu_fc = le16_to_cpu(fc); type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; - psaddr = hdr->addr2; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && (!compare_ether_addr(mac->bssid, -- cgit v1.2.3-70-g09d2 From 78d57372cc781c69a97700cac1f181ec42433fca Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 22 May 2011 20:54:43 -0500 Subject: rtl8192se: Fix warnings from gcc 4.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.6.0 warnings for rtl8192se: CC [M] drivers/net/wireless/rtlwifi/rtl8192se/dm.o drivers/net/wireless/rtlwifi/rtl8192se/dm.c: In function ‘_rtl92s_dm_refresh_rateadaptive_mask’: drivers/net/wireless/rtlwifi/rtl8192se/dm.c:225:5: warning: variable ‘rssi_level’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/rtl8192se/fw.o drivers/net/wireless/rtlwifi/rtl8192se/fw.c: In function ‘rtl92s_download_fw’: drivers/net/wireless/rtlwifi/rtl8192se/fw.c:361:6: warning: variable ‘file_length’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/rtl8192se/hw.o drivers/net/wireless/rtlwifi/rtl8192se/hw.c: In function ‘_rtl92se_hw_configure’: drivers/net/wireless/rtlwifi/rtl8192se/hw.c:887:6: warning: variable ‘reg_ratr’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/rtl8192se/hw.c: In function ‘_rtl92se_set_media_status’: drivers/net/wireless/rtlwifi/rtl8192se/hw.c:1125:20: warning: variable ‘ledaction’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/rtlwifi/rtl8192se/hw.c: In function ‘rtl92se_gpio_radio_on_off_checking’: drivers/net/wireless/rtlwifi/rtl8192se/hw.c:2274:32: warning: variable ‘cur_rfstate’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/rtl8192se/phy.o drivers/net/wireless/rtlwifi/rtl8192se/phy.c: In function ‘rtl92s_phy_set_bw_mode’: drivers/net/wireless/rtlwifi/rtl8192se/phy.c:266:5: warning: variable ‘reg_prsr_rsc’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/rtlwifi/rtl8192se/trx.o drivers/net/wireless/rtlwifi/rtl8192se/trx.c: In function ‘_rtl92se_translate_rx_signal_stuff’: drivers/net/wireless/rtlwifi/rtl8192se/trx.c:584:6: warning: variable ‘psaddr’ set but not used [-Wunused-but-set-variable] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/dm.c | 5 ----- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 11 +++-------- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 -- 5 files changed, 5 insertions(+), 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index da86db86fa4..609c7ec7e66 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -222,7 +222,6 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) u32 low_rssi_thresh = 0; u32 middle_rssi_thresh = 0; u32 high_rssi_thresh = 0; - u8 rssi_level; struct ieee80211_sta *sta = NULL; if (is_hal_stop(rtlhal)) @@ -272,18 +271,14 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) if (rtlpriv->dm.undecorated_smoothed_pwdb > (long)high_rssi_thresh) { ra->ratr_state = DM_RATR_STA_HIGH; - rssi_level = 1; } else if (rtlpriv->dm.undecorated_smoothed_pwdb > (long)middle_rssi_thresh) { ra->ratr_state = DM_RATR_STA_LOW; - rssi_level = 3; } else if (rtlpriv->dm.undecorated_smoothed_pwdb > (long)low_rssi_thresh) { ra->ratr_state = DM_RATR_STA_LOW; - rssi_level = 5; } else { ra->ratr_state = DM_RATR_STA_ULTRALOW; - rssi_level = 6; } if (ra->pre_ratr_state != ra->ratr_state) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 3b5af0113d7..6f91a148c22 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -358,7 +358,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) struct fw_priv *pfw_priv = NULL; u8 *puc_mappedfile = NULL; u32 ul_filelength = 0; - u32 file_length = 0; u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; u8 fwstatus = FW_STATUS_INIT; bool rtstatus = true; @@ -370,7 +369,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) firmware->fwstatus = FW_STATUS_INIT; puc_mappedfile = firmware->sz_fw_tmpbuffer; - file_length = firmware->sz_fw_tmpbufferlen; /* 1. Retrieve FW header. */ firmware->pfwheader = (struct fw_hdr *) puc_mappedfile; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 2e9005d0454..6ff0caca958 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -884,12 +884,10 @@ static void _rtl92se_hw_configure(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 reg_bw_opmode = 0; - u32 reg_ratr = 0, reg_rrsr = 0; + u32 reg_rrsr = 0; u8 regtmp = 0; reg_bw_opmode = BW_OPMODE_20MHZ; - reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | - RATE_ALL_OFDM_2SS; reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL); @@ -1122,14 +1120,12 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); u8 bt_msr = rtl_read_byte(rtlpriv, MSR); - enum led_ctl_mode ledaction = LED_CTL_NO_LINK; u32 temp; bt_msr &= ~MSR_LINK_MASK; switch (type) { case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); - ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Set Network type to NO LINK!\n")); break; @@ -1140,7 +1136,6 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_STATION: bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); - ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Set Network type to STA!\n")); break; @@ -2271,7 +2266,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - enum rf_pwrstate rfpwr_toset, cur_rfstate; + enum rf_pwrstate rfpwr_toset /*, cur_rfstate */; unsigned long flag = 0; bool actuallyset = false; bool turnonbypowerdomain = false; @@ -2292,7 +2287,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); } - cur_rfstate = ppsc->rfpwr_state; + /* cur_rfstate = ppsc->rfpwr_state;*/ /* because after _rtl92s_phy_set_rfhalt, all power * closed, so we must open some power for GPIO check, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 63b45e60a95..a26713b5afb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -263,7 +263,6 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u8 reg_bw_opmode; - u8 reg_prsr_rsc; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? @@ -277,7 +276,8 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, rtlphy->set_bwmode_inprogress = true; reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE); - reg_prsr_rsc = rtl_read_byte(rtlpriv, RRSR + 2); + /* dummy read */ + rtl_read_byte(rtlpriv, RRSR + 2); switch (rtlphy->current_chan_bw) { case HT_CHANNEL_WIDTH_20: diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 5cf442373d4..14a8b7866c0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -581,7 +581,6 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr; u8 *tmp_buf; u8 *praddr; - u8 *psaddr; __le16 fc; u16 type, cfc; bool packet_matchbssid, packet_toself, packet_beacon; @@ -593,7 +592,6 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, cfc = le16_to_cpu(fc); type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; - psaddr = hdr->addr2; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? -- cgit v1.2.3-70-g09d2 From 0541ac4cb47a31f44bf841a4dade539395c146ee Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 22 May 2011 20:57:03 -0500 Subject: b43legacy: Fix warnings from gcc 4.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.6.0 warnings for b43legacy: CC [M] drivers/net/wireless/b43legacy/main.o drivers/net/wireless/b43legacy/main.c: In function ‘b43legacy_request_firmware’: drivers/net/wireless/b43legacy/main.c:1567:6: warning: variable ‘tmshigh’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/b43legacy/main.c: In function ‘b43legacy_op_dev_config’: drivers/net/wireless/b43legacy/main.c:2637:6: warning: variable ‘antenna_rx’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/b43legacy/main.c: In function ‘b43legacy_op_bss_info_changed’: drivers/net/wireless/b43legacy/main.c:2778:24: warning: variable ‘phy’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/b43legacy/xmit.c: In function ‘generate_txhdr_fw3’: drivers/net/wireless/b43legacy/xmit.c:324:7: warning: variable ‘rts_rate_ofdm’ set but not used [-Wunused-but-set-variable] CC [M] drivers/net/wireless/b43legacy/dma.o drivers/net/wireless/b43legacy/dma.c: In function ‘free_all_descbuffers’: drivers/net/wireless/b43legacy/dma.c:820:36: warning: variable ‘desc’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/b43legacy/dma.c: In function ‘b43legacy_dma_tx’: drivers/net/wireless/b43legacy/dma.c:1377:28: warning: variable ‘info’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/b43legacy/dma.c:1374:24: warning: variable ‘hdr’ set but not used [-Wunused-but-set-variable] drivers/net/wireless/b43legacy/dma.c: In function ‘b43legacy_dma_handle_txstatus’: drivers/net/wireless/b43legacy/dma.c:1438:36: warning: variable ‘desc’ set but not used [-Wunused-but-set-variable] Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/dma.c | 10 ++-------- drivers/net/wireless/b43legacy/main.c | 8 ++------ drivers/net/wireless/b43legacy/xmit.c | 2 -- 3 files changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index e03e01d0bc3..c33934ad6cd 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -817,14 +817,13 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring) static void free_all_descbuffers(struct b43legacy_dmaring *ring) { - struct b43legacy_dmadesc_generic *desc; struct b43legacy_dmadesc_meta *meta; int i; if (!ring->used_slots) return; for (i = 0; i < ring->nr_slots; i++) { - desc = ring->ops->idx2desc(ring, i, &meta); + ring->ops->idx2desc(ring, i, &meta); if (!meta->skb) { B43legacy_WARN_ON(!ring->tx); @@ -1371,10 +1370,8 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, struct sk_buff *skb) { struct b43legacy_dmaring *ring; - struct ieee80211_hdr *hdr; int err = 0; unsigned long flags; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); spin_lock_irqsave(&ring->lock, flags); @@ -1401,8 +1398,6 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing * into the skb data or cb now. */ - hdr = NULL; - info = NULL; err = dma_tx_fragment(ring, &skb); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key @@ -1435,7 +1430,6 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, { const struct b43legacy_dma_ops *ops; struct b43legacy_dmaring *ring; - struct b43legacy_dmadesc_generic *desc; struct b43legacy_dmadesc_meta *meta; int retry_limit; int slot; @@ -1450,7 +1444,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, ops = ring->ops; while (1) { B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); - desc = ops->idx2desc(ring, slot, &meta); + ops->idx2desc(ring, slot, &meta); if (meta->skb) unmap_descbuffer(ring, meta->dmaaddr, diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1ab8861dd43..ffa46717323 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1564,10 +1564,10 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) struct b43legacy_firmware *fw = &dev->fw; const u8 rev = dev->dev->id.revision; const char *filename; - u32 tmshigh; int err; - tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); + /* do dummy read */ + ssb_read32(dev->dev, SSB_TMSHIGH); if (!fw->ucode) { if (rev == 2) filename = "ucode2"; @@ -2634,11 +2634,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, unsigned long flags; unsigned int new_phymode = 0xFFFF; int antenna_tx; - int antenna_rx; int err = 0; antenna_tx = B43legacy_ANTENNA_DEFAULT; - antenna_rx = B43legacy_ANTENNA_DEFAULT; mutex_lock(&wl->mutex); dev = wl->current_dev; @@ -2775,14 +2773,12 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw, { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev; - struct b43legacy_phy *phy; unsigned long flags; mutex_lock(&wl->mutex); B43legacy_WARN_ON(wl->vif != vif); dev = wl->current_dev; - phy = &dev->phy; /* Disable IRQs while reconfiguring the device. * This makes it possible to drop the spinlock throughout diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 3a95541708a..6c174f38ca3 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -321,11 +321,9 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, struct ieee80211_hdr *hdr; int rts_rate; int rts_rate_fb; - int rts_rate_ofdm; int rts_rate_fb_ofdm; rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value; - rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); if (rts_rate_fb_ofdm) -- cgit v1.2.3-70-g09d2 From 4a7f5db19c0d8783f700cb606597c4c7b1364db5 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 23 May 2011 18:00:17 -0700 Subject: mwifiex: remove support for old chipsets W0/W1 For SD8787 A0/A1 chipsets we use the default firmware image file 'mrvl/sd8787_uapsta.bin'. So the chip rev id variable is removed. The global variable fw_name is moved to adapter structure so that we can support a different interface, such as PCIe, in future. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 18 ++---------------- drivers/net/wireless/mwifiex/main.h | 11 +---------- drivers/net/wireless/mwifiex/sdio.c | 8 ++------ drivers/net/wireless/mwifiex/sdio.h | 2 ++ 4 files changed, 7 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index f0582259c93..4f43443036f 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -35,8 +35,6 @@ static struct mwifiex_bss_attr mwifiex_bss_sta[] = { static int drv_mode = DRV_MODE_STA; -static char fw_name[32] = DEFAULT_FW_NAME; - /* Supported drv_mode table */ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { { @@ -384,20 +382,8 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) memset(&fw, 0, sizeof(struct mwifiex_fw_image)); - switch (adapter->revision_id) { - case SD8787_W0: - case SD8787_W1: - strcpy(fw_name, SD8787_W1_FW_NAME); - break; - case SD8787_A0: - case SD8787_A1: - strcpy(fw_name, SD8787_AX_FW_NAME); - break; - default: - break; - } - - err = request_firmware(&adapter->firmware, fw_name, adapter->dev); + err = request_firmware(&adapter->firmware, adapter->fw_name, + adapter->dev); if (err < 0) { dev_err(adapter->dev, "request_firmware() returned" " error code %#x\n", err); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 8316b3cd92c..89f98701b70 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -48,15 +48,6 @@ enum { #define DRV_MODE_STA 0x1 -#define SD8787_W0 0x30 -#define SD8787_W1 0x31 -#define SD8787_A0 0x40 -#define SD8787_A1 0x41 - -#define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" -#define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin" -#define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin" - struct mwifiex_drv_mode { u16 drv_mode; u16 intf_num; @@ -576,10 +567,10 @@ struct mwifiex_adapter { u8 priv_num; struct mwifiex_drv_mode *drv_mode; const struct firmware *firmware; + char fw_name[32]; struct device *dev; bool surprise_removed; u32 fw_release_number; - u32 revision_id; u16 init_wait_q_woken; wait_queue_head_t init_wait_q; void *card; diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d425dbd91d1..4327b6d099c 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -1531,6 +1531,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) sdio_set_drvdata(func, card); adapter->dev = &func->dev; + strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME); return 0; @@ -1552,7 +1553,6 @@ disable_func: * the first interrupt got from bootloader * - Disable host interrupt mask register * - Get SDIO port - * - Get revision ID * - Initialize SDIO variables in card * - Allocate MP registers * - Allocate MPA Tx and Rx buffers @@ -1576,10 +1576,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) /* Get SDIO ioport */ mwifiex_init_sdio_ioport(adapter); - /* Get revision ID */ -#define REV_ID_REG 0x5c - mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id); - /* Initialize SDIO variables in card */ card->mp_rd_bitmap = 0; card->mp_wr_bitmap = 0; @@ -1751,4 +1747,4 @@ MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); MODULE_VERSION(SDIO_VERSION); MODULE_LICENSE("GPL v2"); -MODULE_FIRMWARE("sd8787.bin"); +MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index 4e97e90aa39..c925376fcaa 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h @@ -28,6 +28,8 @@ #include "main.h" +#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" + #define BLOCK_MODE 1 #define BYTE_MODE 0 -- cgit v1.2.3-70-g09d2 From 5111dd3e422d08435164fc6d405d849ff6421eec Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 23 May 2011 20:37:31 -0500 Subject: rtlwifi: rtl8192se: Use write barrier when assigning ownership As noted by Mike McCormack for rtl8192ce, make sure all updates to a descriptor are flushed to memory before assigning ownship to hardware. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 14a8b7866c0..d509cf6a1e4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -873,6 +873,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); + wmb(); SET_TX_DESC_OWN(pdesc, 1); } else { /* H2C Command Desc format (Host TXCMD) */ /* 92SE must set as 1 for firmware download HW DMA error */ @@ -891,6 +892,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); + wmb(); SET_TX_DESC_OWN(pdesc, 1); } @@ -901,6 +903,7 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) if (istx == true) { switch (desc_name) { case HW_DESC_OWN: + wmb(); SET_TX_DESC_OWN(pdesc, 1); break; case HW_DESC_TX_NEXTDESC_ADDR: @@ -914,6 +917,7 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) } else { switch (desc_name) { case HW_DESC_RXOWN: + wmb(); SET_RX_STATUS_DESC_OWN(pdesc, 1); break; case HW_DESC_RXBUFF_ADDR: -- cgit v1.2.3-70-g09d2 From 049436b9804394e4d6caf7da5f3507bd8f4caa6e Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 23 May 2011 20:38:52 -0500 Subject: rtlwifi: rtl8192se: Synchronize IRQ after disabling it As suggested by Mike McCormack for rtl8192ce, make sure any IRQ handlers running on other CPUs complete. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 6ff0caca958..35dd12d0dcf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1226,6 +1226,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); rtlpci->irq_enabled = false; + synchronize_irq(rtlpci->pdev->irq); } -- cgit v1.2.3-70-g09d2 From b942471bfcda207a51379628379aa821216486e7 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 24 May 2011 15:29:52 +0530 Subject: ath9k: wake up chip before initializing PAPRD table In PAPRD table initialization path we do some register read, so make sure the chip is awake during that. Currently PAPRD is disabled. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 0c545d38f9d..5cf2dc3c65f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -392,12 +392,14 @@ void ath_paprd_calibrate(struct work_struct *work) if (!caldata) return; + ath9k_ps_wakeup(sc); + if (ar9003_paprd_init_table(ah) < 0) - return; + goto fail_paprd; skb = alloc_skb(len, GFP_KERNEL); if (!skb) - return; + goto fail_paprd; skb_put(skb, len); memset(skb->data, 0, len); @@ -409,7 +411,6 @@ void ath_paprd_calibrate(struct work_struct *work) memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); - ath9k_ps_wakeup(sc); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { if (!(common->tx_chainmask & BIT(chain))) continue; -- cgit v1.2.3-70-g09d2 From 81168e509f06aa205b240c1804ec2b9b5add4772 Mon Sep 17 00:00:00 2001 From: Fabrice Deyber Date: Tue, 24 May 2011 08:44:35 -0500 Subject: ath9k: Further fix for mesh beaconing This fix ensure the timers to be set at beacon interval boundaries. Without this change timers can be set improperly resulting in the absence of beacons. Signed-off-by: Fabrice Deyber Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 8b85d7c1d38..0174cdb65a8 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -652,22 +652,13 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - u32 tsf, delta, intval, nexttbtt; + u32 tsf, intval, nexttbtt; ath9k_reset_beacon_status(sc); - tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); intval = TU_TO_USEC(conf->beacon_interval); - - if (!sc->beacon.bc_tstamp) - nexttbtt = tsf + intval; - else { - if (tsf > sc->beacon.bc_tstamp) - delta = (tsf - sc->beacon.bc_tstamp); - else - delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); - nexttbtt = tsf + intval - (delta % intval); - } + tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); + nexttbtt = tsf + intval; ath_dbg(common, ATH_DBG_BEACON, "IBSS nexttbtt %u intval %u (%u)\n", -- cgit v1.2.3-70-g09d2 From 05c0be2f7f10404e5b3bc4105f9206096e9b8767 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 26 May 2011 10:56:15 +0530 Subject: ath9k: Add a debug entry to start/stop ANI this helps the user to start/stop ANI dynamically. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 + drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/debug.c | 52 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/init.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 33 +++++++++++++++------ 5 files changed, 79 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 7cf4317a2a8..17c4b56c387 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -161,6 +161,7 @@ struct ath_common { const struct ath_bus_ops *bus_ops; bool btcoex_enabled; + bool disable_ani; }; struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4cc78449ed9..3bf1d83ab41 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -427,6 +427,7 @@ void ath_hw_check(struct work_struct *work); void ath_hw_pll_work(struct work_struct *work); void ath_paprd_calibrate(struct work_struct *work); void ath_ani_calibrate(unsigned long data); +void ath_start_ani(struct ath_common *common); /**********/ /* BTCOEX */ diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 202399d4fe1..7230d6578b1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -176,6 +176,56 @@ static const struct file_operations fops_rx_chainmask = { .llseek = default_llseek, }; +static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + char buf[32]; + unsigned int len; + + len = sprintf(buf, "%d\n", common->disable_ani); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t write_file_disable_ani(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + unsigned long disable_ani; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (strict_strtoul(buf, 0, &disable_ani)) + return -EINVAL; + + common->disable_ani = !!disable_ani; + + if (disable_ani) { + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); + } else { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + + return count; +} + +static const struct file_operations fops_disable_ani = { + .read = read_file_disable_ani, + .write = write_file_disable_ani, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; static ssize_t read_file_dma(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1159,6 +1209,8 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.debugfs_phy, sc, &fops_rx_chainmask); debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_tx_chainmask); + debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_disable_ani); debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regidx); debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 45c585a337e..d4b166cfdf6 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -519,7 +519,6 @@ static void ath9k_init_misc(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; - setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; @@ -585,6 +584,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, common->priv = sc; common->debug_mask = ath9k_debug; common->btcoex_enabled = ath9k_btcoex_enable == 1; + common->disable_ani = false; spin_lock_init(&common->cc_lock); spin_lock_init(&sc->sc_serial_rw); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5cf2dc3c65f..7f945333e2d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -134,7 +134,7 @@ void ath9k_ps_restore(struct ath_softc *sc) spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } -static void ath_start_ani(struct ath_common *common) +void ath_start_ani(struct ath_common *common) { struct ath_hw *ah = common->ah; unsigned long timestamp = jiffies_to_msecs(jiffies); @@ -300,7 +300,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath_set_beacon(sc); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); - ath_start_ani(common); + if (!common->disable_ani) + ath_start_ani(common); } ps_restore: @@ -968,6 +969,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) sc->hw_busy_count = 0; /* Stop ANI */ + del_timer_sync(&common->ani.timer); ath9k_ps_wakeup(sc); @@ -1017,7 +1019,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) spin_unlock_bh(&sc->sc_pcu_lock); /* Start ANI */ - ath_start_ani(common); + if (!common->disable_ani) + ath_start_ani(common); + ath9k_ps_restore(sc); return r; @@ -1408,8 +1412,12 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, /* Set up ANI */ if (iter_data.naps > 0) { sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); + + if (!common->disable_ani) { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + } else { sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); @@ -1973,8 +1981,11 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) sc->last_rssi = ATH_RSSI_DUMMY_MARKER; sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); + if (!common->disable_ani) { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + } } @@ -2043,8 +2054,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if (bss_conf->ibss_joined) { sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); + + if (!common->disable_ani) { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + } else { sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); -- cgit v1.2.3-70-g09d2 From 84288044dc9a50d2c0b0f1a024d7cd87ab3dd131 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 26 May 2011 11:41:13 +0530 Subject: ath9k: better position PAPRD debug message the training power calculation indirectly depends on target power under some scenarios, unless we have a valid training power, the PAPRD frames won't be sent out. so when we get an invalid training power, its better to display them before returning back. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index e4d6a87ec53..fee38cebdcd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -119,15 +119,16 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) else training_power = ar9003_get_training_power_5g(ah); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Training power: %d, Target power: %d\n", + training_power, ah->paprd_target_power); + if (training_power < 0) { ath_dbg(common, ATH_DBG_CALIBRATE, "PAPRD target power delta out of range"); return -ERANGE; } ah->paprd_training_power = training_power; - ath_dbg(common, ATH_DBG_CALIBRATE, - "Training power: %d, Target power: %d\n", - ah->paprd_training_power, ah->paprd_target_power); REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, ah->paprd_ratemask); -- cgit v1.2.3-70-g09d2 From 891db88112b604db054d9575d200271ad97634a4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 27 May 2011 08:40:24 -0700 Subject: iwlagn: send tx power command if defer cause by RXON not match During channge channel, tx power will not send to uCode, the tx power command should send after scan complete. but should also can send after RXON command. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a95ad84c537..58c095c00c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -362,6 +362,11 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } memcpy(active, &ctx->staging, sizeof(*active)); + /* + * We do not commit tx power settings while channel changing, + * do it now if after settings changed. + */ + iwl_set_tx_power(priv, priv->tx_power_next, false); return 0; } -- cgit v1.2.3-70-g09d2 From 5beaaf3756aef42f31747d81b0676c8ccf59c6c4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 27 May 2011 08:40:25 -0700 Subject: iwlagn: remove un-necessary tx power ops All agn devices use the same tx power function, remove the ops Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-core.c | 5 +---- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 6 files changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 61d4a11f566..99409501ad4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -174,7 +174,6 @@ static struct iwl_lib_ops iwl1000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .apm_ops = { .init = iwl_apm_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 86feec86d13..a37c41b405c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -256,7 +256,6 @@ static struct iwl_lib_ops iwl2000_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl2030_hw_channel_switch, .apm_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index a70b8cfafda..a8dbbd08279 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -342,7 +342,6 @@ static struct iwl_lib_ops iwl5000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { @@ -373,7 +372,6 @@ static struct iwl_lib_ops iwl5150_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f8c710db6e6..eabf3b8495c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -281,7 +281,6 @@ static struct iwl_lib_ops iwl6000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { @@ -314,7 +313,6 @@ static struct iwl_lib_ops iwl6030_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4653deada05..52e941382e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1131,9 +1131,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) if (priv->tx_power_user_lmt == tx_power && !force) return 0; - if (!priv->cfg->ops->lib->send_tx_power) - return -EOPNOTSUPP; - if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n", @@ -1167,7 +1164,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) prev_tx_power = priv->tx_power_user_lmt; priv->tx_power_user_lmt = tx_power; - ret = priv->cfg->ops->lib->send_tx_power(priv); + ret = iwlagn_send_tx_power(priv); /* if fail to set tx_power, restore the orig. tx power */ if (ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3bb76f6ea41..a87b54fb9e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -141,7 +141,6 @@ struct iwl_lib_ops { struct iwl_apm_ops apm_ops; /* power */ - int (*send_tx_power) (struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv); /* eeprom operations (as defined in iwl-eeprom.h) */ -- cgit v1.2.3-70-g09d2 From 2b9253d2a0439bd247d9384921ff23e7ac6bba52 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 May 2011 08:40:26 -0700 Subject: iwlagn: fix dual-mode RXON The PAN context has three states: disabled, disassociated and associated. It seems that wasn't quite as much of an issue in previous versions of the microcode, but now we really have to use all the three states properly. So add code to switch accordingly. Additionally, PAN parameters need to be sent differently and the timing for PAN RXON needs to be inbetween. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 52 ++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 58c095c00c0..afb2f202afb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -81,6 +81,21 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, return ret; } +static int iwlagn_disconn_pan(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct iwl_rxon_cmd *send) +{ + __le32 old_filter = send->filter_flags; + int ret; + + send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); + + send->filter_flags = old_filter; + + return ret; +} + static void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { @@ -175,10 +190,21 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv, int ret; struct iwl_rxon_cmd *active = (void *)&ctx->active; - if (ctx->ctxid == IWL_RXON_CTX_BSS) + if (ctx->ctxid == IWL_RXON_CTX_BSS) { ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); - else + } else { ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); + if (ret) + return ret; + if (ctx->vif) { + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); + return ret; + } + ret = iwlagn_disconn_pan(priv, ctx, &ctx->staging); + } + } if (ret) return ret; @@ -205,10 +231,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, struct iwl_rxon_cmd *active = (void *)&ctx->active; /* RXON timing must be before associated RXON */ - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); - return ret; + if (ctx->ctxid == IWL_RXON_CTX_BSS) { + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); + return ret; + } } /* QoS info may be cleared by previous un-assoc RXON */ iwlagn_update_qos(priv, ctx); @@ -370,12 +398,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } - if (priv->cfg->ops->hcmd->set_pan_params) { - ret = priv->cfg->ops->hcmd->set_pan_params(priv); - if (ret) - return ret; - } - iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto); IWL_DEBUG_INFO(priv, @@ -397,6 +419,12 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (ret) return ret; + if (priv->cfg->ops->hcmd->set_pan_params) { + ret = priv->cfg->ops->hcmd->set_pan_params(priv); + if (ret) + return ret; + } + if (new_assoc) return iwlagn_rxon_connect(priv, ctx); -- cgit v1.2.3-70-g09d2 From 3d82b15608ad97627ced4d3bd42ae10297c2f87d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 27 May 2011 08:40:27 -0700 Subject: iwlagn: solve sparse warning Remove local variable that was shadowing another one sta_priv hasn't changed since the beginning of the function, so don't define another pointer with the same name to the same variable Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 11c6c1169e7..291ceb53c91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2711,12 +2711,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, ret = 0; if (priv->cfg->ht_params && priv->cfg->ht_params->use_rts_for_aggregation) { - struct iwl_station_priv *sta_priv = - (void *) sta->drv_priv; /* * switch off RTS/CTS if it was previously enabled */ - sta_priv->lq_sta.lq.general_params.flags &= ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), -- cgit v1.2.3-70-g09d2 From 2e5d04dad1934d97057cbecce59834f78dafc067 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Fri, 27 May 2011 08:40:28 -0700 Subject: iwlwifi: disambiguate invalid DMA index warnings The exact same error message is used in three different functions in iwlagn. Add the function name to the error string to disambiguate where the error is coming from. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-tx.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f803fb62f8b..4ab77c8a584 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -408,9 +408,9 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, unsigned long flags; if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { - IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " - "is out of range [0-%d] %d %d\n", txq_id, - index, txq->q.n_bd, txq->q.write_ptr, + IWL_ERR(priv, "%s: Read index for DMA queue txq_id (%d) " + "index %d is out of range [0-%d] %d %d\n", __func__, + txq_id, index, txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr); return; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 4974cd7837c..ce7b4913903 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1236,9 +1236,9 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) struct ieee80211_hdr *hdr; if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { - IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " - "is out of range [0-%d] %d %d.\n", txq_id, - index, q->n_bd, q->write_ptr, q->read_ptr); + IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), " + "index %d is out of range [0-%d] %d %d.\n", __func__, + txq_id, index, q->n_bd, q->write_ptr, q->read_ptr); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 686e176b5eb..1084fe0e8a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -753,9 +753,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx) int nfreed = 0; if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { - IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " - "is out of range [0-%d] %d %d.\n", txq_id, - idx, q->n_bd, q->write_ptr, q->read_ptr); + IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), " + "index %d is out of range [0-%d] %d %d.\n", __func__, + txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr); return; } -- cgit v1.2.3-70-g09d2 From 93cce6f0adff92238965eadb3c046db58552087b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 27 May 2011 08:40:29 -0700 Subject: iwlagn: free the ICT ISR when the request_irq failed Fix a memory leak in case request_irq fails. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 291ceb53c91..76b333624a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3615,8 +3615,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) destroy_workqueue(priv->workqueue); priv->workqueue = NULL; free_irq(priv->pci_dev->irq, priv); - iwl_free_isr_ict(priv); out_disable_msi: + iwl_free_isr_ict(priv); pci_disable_msi(priv->pci_dev); iwl_uninit_drv(priv); out_free_eeprom: -- cgit v1.2.3-70-g09d2 From 0fd095024b7bc023c7afac107732dac961ee690d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 May 2011 08:40:30 -0700 Subject: iwlagn: advertise interface combinations With this, iwlwifi will advertise the limits on concurrency of virtual interfaces. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 83 ++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 76b333624a2..de0830dba1f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2420,6 +2420,77 @@ unlock: * *****************************************************************************/ +static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP), + }, +}; + +static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION), + }, +}; + +static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_AP), + }, +}; + +static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_CLIENT), + }, +}; + +static const struct ieee80211_iface_combination +iwlagn_iface_combinations_dualmode[] = { + { .num_different_channels = 1, + .max_interfaces = 2, + .beacon_int_infra_match = true, + .limits = iwlagn_sta_ap_limits, + .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits), + }, + { .num_different_channels = 1, + .max_interfaces = 2, + .limits = iwlagn_2sta_limits, + .n_limits = ARRAY_SIZE(iwlagn_2sta_limits), + }, +}; + +static const struct ieee80211_iface_combination +iwlagn_iface_combinations_p2p[] = { + { .num_different_channels = 1, + .max_interfaces = 2, + .beacon_int_infra_match = true, + .limits = iwlagn_p2p_sta_go_limits, + .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits), + }, + { .num_different_channels = 1, + .max_interfaces = 2, + .limits = iwlagn_p2p_2sta_limits, + .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits), + }, +}; + /* * Not a mac80211 entry point function, but it fits in with all the * other mac80211 functions grouped here. @@ -2460,6 +2531,18 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; } + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); + + if (hw->wiphy->interface_modes & NL80211_IFTYPE_P2P_CLIENT) { + hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p; + hw->wiphy->n_iface_combinations = + ARRAY_SIZE(iwlagn_iface_combinations_p2p); + } else if (hw->wiphy->interface_modes & NL80211_IFTYPE_AP) { + hw->wiphy->iface_combinations = iwlagn_iface_combinations_dualmode; + hw->wiphy->n_iface_combinations = + ARRAY_SIZE(iwlagn_iface_combinations_dualmode); + } + hw->wiphy->max_remain_on_channel_duration = 1000; hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | -- cgit v1.2.3-70-g09d2 From 5f88ac2d72a7f8e1cadab6d9cbc0fe1837cbcd7a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 27 May 2011 08:40:31 -0700 Subject: iwlagn: change the logging level for aggregation enable check Aggregation will not enable if the traffic is lower than the threshold, this is not an error condition, so change the logging level. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 592b0cfcf71..85e082830c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -426,7 +426,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, ieee80211_stop_tx_ba_session(sta, tid); } } else { - IWL_ERR(priv, "Aggregation not enabled for tid %d " + IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d " "because load = %u\n", tid, load); } return ret; -- cgit v1.2.3-70-g09d2 From 5bc9890ff114cdd39de8561610f6af3bb4b08cfb Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 27 May 2011 08:40:32 -0700 Subject: iwlagn: change log to better represent the state of aggregation process Multiple A-MPDU actions will received from mac80211 while setting up the aggregation queue, change the message log to better represent the states. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index ce7b4913903..8bd48f61a9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1033,8 +1033,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, if (unlikely(tx_fifo < 0)) return tx_fifo; - IWL_WARN(priv, "%s on ra = %pM tid = %d\n", - __func__, sta->addr, tid); + IWL_DEBUG_HT(priv, "TX AGG request on ra = %pM tid = %d\n", + sta->addr, tid); sta_id = iwl_sta_id(sta); if (sta_id == IWL_INVALID_STATION) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index de0830dba1f..5d2bd88101f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2844,6 +2844,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), &sta_priv->lq_sta.lq, CMD_ASYNC, false); + + IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", + sta->addr, tid); ret = 0; break; } -- cgit v1.2.3-70-g09d2 From e4d78f120c039bbd18ae449a6b2af3df83ca02bf Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:25:55 +0000 Subject: bnx2x: Add new phy BCM8722 Add support for new phy BCM8722. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 2 + drivers/net/bnx2x/bnx2x_link.c | 85 +++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index cdf19fe7c7f..6ee6160ce95 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -417,6 +417,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8722 0x00000f00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00 @@ -473,6 +474,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC 0x00000a00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823 0x00000b00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833 0x00000d00 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722 0x00000f00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 076e11f5769..56b5ed8f634 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -3146,8 +3146,10 @@ u8 bnx2x_set_led(struct link_params *params, if (!vars->link_up) break; case LED_MODE_ON: - if (params->phy[EXT_PHY1].type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 && + if (((params->phy[EXT_PHY1].type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) || + (params->phy[EXT_PHY1].type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) && CHIP_IS_E2(bp) && params->num_phys == 2) { /* * This is a work-around for E2+8727 Configurations @@ -4657,13 +4659,19 @@ u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf); - else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf); - return -EINVAL; + u8 rc = -EINVAL; + switch (phy->type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, + byte_cnt, o_buf); + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: + rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, + byte_cnt, o_buf); + break; + } + return rc; } static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, @@ -5021,6 +5029,38 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params, } } +static void bnx2x_power_sfp_module(struct link_params *params, + struct bnx2x_phy *phy, + u8 power) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power); + + switch (phy->type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: + bnx2x_8727_power_module(params->bp, phy, power); + break; + default: + break; + } +} + +static void bnx2x_set_limiting_mode(struct link_params *params, + struct bnx2x_phy *phy, + u16 edc_mode) +{ + switch (phy->type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode); + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: + bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode); + break; + } +} + static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, struct link_params *params) { @@ -5034,7 +5074,8 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", params->port); - + /* Power up module */ + bnx2x_power_sfp_module(params, phy, 1); if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) { DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); return -EINVAL; @@ -5046,12 +5087,11 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH); - if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && - ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { - /* Shutdown SFP+ module */ + /* Check if need to power down the SFP+ module */ + if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) { DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); - bnx2x_8727_power_module(bp, phy, 0); + bnx2x_power_sfp_module(params, phy, 0); return rc; } } else { @@ -5059,18 +5099,12 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW); } - /* power up the SFP module */ - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - bnx2x_8727_power_module(bp, phy, 1); - /* * Check and set limiting mode / LRM mode on 8726. On 8727 it * is done automatically */ - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - bnx2x_8726_set_limiting_mode(bp, phy, edc_mode); - else - bnx2x_8727_set_limiting_mode(bp, phy, edc_mode); + bnx2x_set_limiting_mode(params, phy, edc_mode); + /* * Enable transmit for this module if the module is approved, or * if unapproved modules should also enable the Tx laser @@ -5100,7 +5134,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) /* Call the handling function in case module is detected */ if (gpio_val == 0) { - + bnx2x_power_sfp_module(params, phy, 1); bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, port); @@ -7336,6 +7370,7 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, *phy = phy_8727; phy->flags |= FLAGS_NOC; break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; *phy = phy_8727; @@ -8135,7 +8170,7 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], shmem2_base_path, phy_index, chip_id); break; - + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: rc = bnx2x_8727_common_init_phy(bp, shmem_base_path, -- cgit v1.2.3-70-g09d2 From 1ac9e4286dc9e64dd2d937df7f8660bb5f260792 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:26:11 +0000 Subject: bnx2x: Fix port type display Display the current media type connected to the port in ethtool. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 2 +- drivers/net/bnx2x/bnx2x_cmn.c | 49 ++++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_cmn.h | 2 + drivers/net/bnx2x/bnx2x_ethtool.c | 34 ++++++++++++++--- drivers/net/bnx2x/bnx2x_hsi.h | 12 +++++- drivers/net/bnx2x/bnx2x_link.c | 80 +++++++++++++++++++++++++++++++++------ drivers/net/bnx2x/bnx2x_link.h | 2 + drivers/net/bnx2x/bnx2x_main.c | 39 ------------------- 8 files changed, 162 insertions(+), 58 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 668a578c49e..480e02df86e 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1492,7 +1492,7 @@ void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp); void bnx2x_invalidate_uc_list(struct bnx2x *bp); void bnx2x_update_coalesce(struct bnx2x *bp); -int bnx2x_get_link_cfg_idx(struct bnx2x *bp); +int bnx2x_get_cur_phy_idx(struct bnx2x *bp); static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int wait) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 289044332ed..9b248348c0e 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2803,6 +2803,55 @@ static int bnx2x_reload_if_running(struct net_device *dev) return bnx2x_nic_load(bp, LOAD_NORMAL); } +int bnx2x_get_cur_phy_idx(struct bnx2x *bp) +{ + u32 sel_phy_idx = 0; + if (bp->link_params.num_phys <= 1) + return INT_PHY; + + if (bp->link_vars.link_up) { + sel_phy_idx = EXT_PHY1; + /* In case link is SERDES, check if the EXT_PHY2 is the one */ + if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) && + (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE)) + sel_phy_idx = EXT_PHY2; + } else { + + switch (bnx2x_phy_selection(&bp->link_params)) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + sel_phy_idx = EXT_PHY1; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + sel_phy_idx = EXT_PHY2; + break; + } + } + + return sel_phy_idx; + +} +int bnx2x_get_link_cfg_idx(struct bnx2x *bp) +{ + u32 sel_phy_idx = bnx2x_get_cur_phy_idx(bp); + /* + * The selected actived PHY is always after swapping (in case PHY + * swapping is enabled). So when swapping is enabled, we need to reverse + * the configuration + */ + + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) { + if (sel_phy_idx == EXT_PHY1) + sel_phy_idx = EXT_PHY2; + else if (sel_phy_idx == EXT_PHY2) + sel_phy_idx = EXT_PHY1; + } + return LINK_CONFIG_IDX(sel_phy_idx); +} + /* called with rtnl_lock */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 1a3545bd8a9..19f8638ed51 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1063,6 +1063,8 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) } #endif +int bnx2x_get_link_cfg_idx(struct bnx2x *bp); + static inline void __storm_memset_struct(struct bnx2x *bp, u32 addr, size_t size, u32 *data) { diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 727fe89ff37..2957353f7c2 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -162,6 +162,33 @@ static const struct { }; #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) +static int bnx2x_get_port_type(struct bnx2x *bp) +{ + int port_type; + u32 phy_idx = bnx2x_get_cur_phy_idx(bp); + switch (bp->link_params.phy[phy_idx].media_type) { + case ETH_PHY_SFP_FIBER: + case ETH_PHY_XFP_FIBER: + case ETH_PHY_KR: + case ETH_PHY_CX4: + port_type = PORT_FIBRE; + break; + case ETH_PHY_DA_TWINAX: + port_type = PORT_DA; + break; + case ETH_PHY_BASE_T: + port_type = PORT_TP; + break; + case ETH_PHY_NOT_PRESENT: + port_type = PORT_NONE; + break; + case ETH_PHY_UNSPECIFIED: + default: + port_type = PORT_OTHER; + break; + } + return port_type; +} static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -188,12 +215,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (IS_MF(bp)) ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp)); - if (bp->port.supported[cfg_idx] & SUPPORTED_TP) - cmd->port = PORT_TP; - else if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE) - cmd->port = PORT_FIBRE; - else - BNX2X_ERR("XGXS PHY Failure detected\n"); + cmd->port = bnx2x_get_port_type(bp); cmd->phy_address = bp->mdio.prtad; cmd->transceiver = XCVR_INTERNAL; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 6ee6160ce95..5bfdbcc94a7 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -263,7 +263,17 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_FAULT_MODULE_LED_GPIO2 0x00000200 #define PORT_HW_CFG_FAULT_MODULE_LED_GPIO3 0x00000300 #define PORT_HW_CFG_FAULT_MODULE_LED_DISABLED 0x00000400 - u32 Reserved01[12]; /* 0x158 */ + u32 Reserved01[11]; /* 0x158 */ + + u32 media_type; /* 0x194 */ +#define PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK 0x000000FF +#define PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT 0 + +#define PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK 0x0000FF00 +#define PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT 8 + +#define PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK 0x00FF0000 +#define PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT 16 /* for external PHY, or forced mode or during AN */ u16 xgxs_config_rx[4]; /* 0x198 */ diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 56b5ed8f634..8a7d7d6b1dd 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1618,7 +1618,7 @@ void bnx2x_link_status_update(struct link_params *params, struct bnx2x *bp = params->bp; u8 link_10g; u8 port = params->port; - + u32 sync_offset, media_types; vars->link_status = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, port_mb[port].link_status)); @@ -1731,6 +1731,23 @@ void bnx2x_link_status_update(struct link_params *params, vars->mac_type = MAC_TYPE_NONE; } + /* Sync media type */ + sync_offset = params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].media_type); + media_types = REG_RD(bp, sync_offset); + + params->phy[INT_PHY].media_type = + (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >> + PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT; + params->phy[EXT_PHY1].media_type = + (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >> + PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT; + params->phy[EXT_PHY2].media_type = + (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >> + PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT; + DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types); + DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", vars->link_status, vars->phy_link_up); DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", @@ -3247,7 +3264,9 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, serdes_phy_type = ((params->phy[phy_index].media_type == ETH_PHY_SFP_FIBER) || (params->phy[phy_index].media_type == - ETH_PHY_XFP_FIBER)); + ETH_PHY_XFP_FIBER) || + (params->phy[phy_index].media_type == + ETH_PHY_DA_TWINAX)); if (is_serdes != serdes_phy_type) continue; @@ -4679,9 +4698,11 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, u16 *edc_mode) { struct bnx2x *bp = params->bp; + u32 sync_offset = 0, phy_idx, media_types; u8 val, check_limiting_mode = 0; *edc_mode = EDC_MODE_LIMITING; + phy->media_type = ETH_PHY_UNSPECIFIED; /* First check for copper cable */ if (bnx2x_read_sfp_module_eeprom(phy, params, @@ -4696,7 +4717,7 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, case SFP_EEPROM_CON_TYPE_VAL_COPPER: { u8 copper_module_type; - + phy->media_type = ETH_PHY_DA_TWINAX; /* * Check if its active cable (includes SFP+ module) * of passive cable @@ -4731,6 +4752,7 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, break; } case SFP_EEPROM_CON_TYPE_VAL_LC: + phy->media_type = ETH_PHY_SFP_FIBER; DP(NETIF_MSG_LINK, "Optic module detected\n"); check_limiting_mode = 1; break; @@ -4739,7 +4761,22 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, val); return -EINVAL; } - + sync_offset = params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].media_type); + media_types = REG_RD(bp, sync_offset); + /* Update media type for non-PMF sync */ + for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { + if (&(params->phy[phy_idx]) == phy) { + media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK << + (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx)); + media_types |= ((phy->media_type & + PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) << + (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx)); + break; + } + } + REG_WR(bp, sync_offset, media_types); if (check_limiting_mode) { u8 options[SFP_EEPROM_OPTIONS_SIZE]; if (bnx2x_read_sfp_module_eeprom(phy, @@ -5156,6 +5193,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) * Module was plugged out. * Disable transmit for this module */ + phy->media_type = ETH_PHY_NOT_PRESENT; if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) bnx2x_sfp_set_transmitter(params, phy, 0); @@ -5764,7 +5802,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, /* Module is absent */ DP(NETIF_MSG_LINK, "MOD_ABS indication " "show module is absent\n"); - + phy->media_type = ETH_PHY_NOT_PRESENT; /* * 1. Set mod_abs to detect next module * presence event @@ -6877,7 +6915,7 @@ static struct bnx2x_phy phy_serdes = { SUPPORTED_Autoneg | SUPPORTED_Pause | SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_UNSPECIFIED, + .media_type = ETH_PHY_BASE_T, .ver_addr = 0, .req_flow_ctrl = 0, .req_line_speed = 0, @@ -6914,7 +6952,7 @@ static struct bnx2x_phy phy_xgxs = { SUPPORTED_Autoneg | SUPPORTED_Pause | SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_UNSPECIFIED, + .media_type = ETH_PHY_CX4, .ver_addr = 0, .req_flow_ctrl = 0, .req_line_speed = 0, @@ -6977,7 +7015,7 @@ static struct bnx2x_phy phy_8073 = { SUPPORTED_Autoneg | SUPPORTED_Pause | SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_UNSPECIFIED, + .media_type = ETH_PHY_KR, .ver_addr = 0, .req_flow_ctrl = 0, .req_line_speed = 0, @@ -7069,7 +7107,7 @@ static struct bnx2x_phy phy_8726 = { SUPPORTED_FIBRE | SUPPORTED_Pause | SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_SFP_FIBER, + .media_type = ETH_PHY_NOT_PRESENT, .ver_addr = 0, .req_flow_ctrl = 0, .req_line_speed = 0, @@ -7100,7 +7138,7 @@ static struct bnx2x_phy phy_8727 = { SUPPORTED_FIBRE | SUPPORTED_Pause | SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_SFP_FIBER, + .media_type = ETH_PHY_NOT_PRESENT, .ver_addr = 0, .req_flow_ctrl = 0, .req_line_speed = 0, @@ -7565,7 +7603,7 @@ u32 bnx2x_phy_selection(struct link_params *params) u8 bnx2x_phy_probe(struct link_params *params) { u8 phy_index, actual_phy_idx, link_cfg_idx; - u32 phy_config_swapped; + u32 phy_config_swapped, sync_offset, media_types; struct bnx2x *bp = params->bp; struct bnx2x_phy *phy; params->num_phys = 0; @@ -7602,6 +7640,26 @@ u8 bnx2x_phy_probe(struct link_params *params) if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) break; + sync_offset = params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].media_type); + media_types = REG_RD(bp, sync_offset); + + /* + * Update media type for non-PMF sync only for the first time + * In case the media type changes afterwards, it will be updated + * using the update_status function + */ + if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK << + (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * + actual_phy_idx))) == 0) { + media_types |= ((phy->media_type & + PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) << + (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * + actual_phy_idx)); + } + REG_WR(bp, sync_offset, media_types); + bnx2x_phy_def_cfg(params, phy, phy_index); params->num_phys++; } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 92f36b6950d..ac348daae2f 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -153,6 +153,8 @@ struct bnx2x_phy { #define ETH_PHY_XFP_FIBER 0x2 #define ETH_PHY_DA_TWINAX 0x3 #define ETH_PHY_BASE_T 0x4 +#define ETH_PHY_KR 0xf0 +#define ETH_PHY_CX4 0xf1 #define ETH_PHY_NOT_PRESENT 0xff /* The address in which version is located*/ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 4b70311a11e..c6591c46ebd 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1732,45 +1732,6 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) return 0; } -int bnx2x_get_link_cfg_idx(struct bnx2x *bp) -{ - u32 sel_phy_idx = 0; - if (bp->link_vars.link_up) { - sel_phy_idx = EXT_PHY1; - /* In case link is SERDES, check if the EXT_PHY2 is the one */ - if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) && - (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE)) - sel_phy_idx = EXT_PHY2; - } else { - - switch (bnx2x_phy_selection(&bp->link_params)) { - case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: - case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: - case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: - sel_phy_idx = EXT_PHY1; - break; - case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: - case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: - sel_phy_idx = EXT_PHY2; - break; - } - } - /* - * The selected actived PHY is always after swapping (in case PHY - * swapping is enabled). So when swapping is enabled, we need to reverse - * the configuration - */ - - if (bp->link_params.multi_phy_config & - PORT_HW_CFG_PHY_SWAPPED_ENABLED) { - if (sel_phy_idx == EXT_PHY1) - sel_phy_idx = EXT_PHY2; - else if (sel_phy_idx == EXT_PHY2) - sel_phy_idx = EXT_PHY1; - } - return LINK_CONFIG_IDX(sel_phy_idx); -} - void bnx2x_calc_fc_adv(struct bnx2x *bp) { u8 cfg_idx = bnx2x_get_link_cfg_idx(bp); -- cgit v1.2.3-70-g09d2 From fcf5b650832996bd857bb8f0b0b42097218f7fb8 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:26:28 +0000 Subject: bnx2x: Change return status type Change return status from u8 to int. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 332 +++++++++++++++++++++-------------------- drivers/net/bnx2x/bnx2x_link.h | 44 +++--- 2 files changed, 192 insertions(+), 184 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 8a7d7d6b1dd..7705e79945e 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -342,7 +342,7 @@ void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight); } -u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) +int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) { /* ETS disabled configuration*/ struct bnx2x *bp = params->bp; @@ -508,8 +508,8 @@ static void bnx2x_emac_init(struct link_params *params, EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val); } -static u8 bnx2x_emac_enable(struct link_params *params, - struct link_vars *vars, u8 lb) +static int bnx2x_emac_enable(struct link_params *params, + struct link_vars *vars, u8 lb) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -1002,9 +1002,9 @@ void bnx2x_update_pfc(struct link_params *params, REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val); } -static u8 bnx2x_bmac1_enable(struct link_params *params, - struct link_vars *vars, - u8 is_lb) +static int bnx2x_bmac1_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -1066,9 +1066,9 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, return 0; } -static u8 bnx2x_bmac2_enable(struct link_params *params, - struct link_vars *vars, - u8 is_lb) +static int bnx2x_bmac2_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -1131,11 +1131,12 @@ static u8 bnx2x_bmac2_enable(struct link_params *params, return 0; } -static u8 bnx2x_bmac_enable(struct link_params *params, - struct link_vars *vars, - u8 is_lb) +static int bnx2x_bmac_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) { - u8 rc, port = params->port; + int rc = 0; + u8 port = params->port; struct bnx2x *bp = params->bp; u32 val; /* reset and unreset the BigMac */ @@ -1218,8 +1219,8 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) } } -static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, - u32 line_speed) +static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, + u32 line_speed) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -1351,11 +1352,12 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, /******************************************************************/ /* CL45 access functions */ /******************************************************************/ -static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 val) +static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val) { u32 tmp, saved_mode; - u8 i, rc = 0; + u8 i; + int rc = 0; /* * Set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off @@ -1420,12 +1422,12 @@ static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, return rc; } -static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 *ret_val) +static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val) { u32 val, saved_mode; u16 i; - u8 rc = 0; + int rc = 0; /* * Set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off @@ -1492,8 +1494,8 @@ static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, return rc; } -u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, - u8 devad, u16 reg, u16 *ret_val) +int bnx2x_phy_read(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 *ret_val) { u8 phy_index; /* @@ -1510,8 +1512,8 @@ u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, return -EINVAL; } -u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, - u8 devad, u16 reg, u16 val) +int bnx2x_phy_write(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 val) { u8 phy_index; /* @@ -1776,9 +1778,9 @@ static void bnx2x_set_master_ln(struct link_params *params, (new_master_ln | ser_lane)); } -static u8 bnx2x_reset_unicore(struct link_params *params, - struct bnx2x_phy *phy, - u8 set_serdes) +static int bnx2x_reset_unicore(struct link_params *params, + struct bnx2x_phy *phy, + u8 set_serdes) { struct bnx2x *bp = params->bp; u16 mii_control; @@ -2296,8 +2298,8 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE; } -static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, - struct link_params *params) +static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 pd_10g, status2_1000x; @@ -2480,13 +2482,13 @@ static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy, LINK_STATUS_PARALLEL_DETECTION_USED; } -static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_link_settings_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 new_line_speed, gp_status; - u8 rc = 0; + int rc = 0; /* Read gp_status */ CL22_RD_OVER_CL45(bp, phy, @@ -2659,8 +2661,8 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) } } -static u8 bnx2x_emac_program(struct link_params *params, - struct link_vars *vars) +static int bnx2x_emac_program(struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -2779,11 +2781,11 @@ static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, } } -static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_init_serdes(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { - u8 rc; + int rc; vars->phy_flags |= PHY_SGMII_FLAG; bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); bnx2x_set_aer_mmd_serdes(params->bp, phy); @@ -2796,11 +2798,11 @@ static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, return rc; } -static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_init_xgxs(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { - u8 rc; + int rc; vars->phy_flags = PHY_XGXS_FLAG; if ((phy->req_line_speed && ((phy->req_line_speed == SPEED_100) || @@ -2989,7 +2991,7 @@ static void bnx2x_link_int_ack(struct link_params *params, } } -static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) +static int bnx2x_format_ver(u32 num, u8 *str, u16 *len) { u8 *str_ptr = str; u32 mask = 0xf0000000; @@ -3028,19 +3030,19 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) } -static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) +static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) { str[0] = '\0'; (*len)--; return 0; } -u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, - u8 *version, u16 len) +int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, + u8 *version, u16 len) { struct bnx2x *bp; u32 spirom_ver = 0; - u8 status = 0; + int status = 0; u8 *ver_p = version; u16 remain_len = len; if (version == NULL || params == NULL) @@ -3124,12 +3126,13 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, } } -u8 bnx2x_set_led(struct link_params *params, - struct link_vars *vars, u8 mode, u32 speed) +int bnx2x_set_led(struct link_params *params, + struct link_vars *vars, u8 mode, u32 speed) { u8 port = params->port; u16 hw_led_mode = params->hw_led_mode; - u8 rc = 0, phy_idx; + int rc = 0; + u8 phy_idx; u32 tmp; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; struct bnx2x *bp = params->bp; @@ -3233,8 +3236,8 @@ u8 bnx2x_set_led(struct link_params *params, * This function comes to reflect the actual link state read DIRECTLY from the * HW */ -u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, - u8 is_serdes) +int bnx2x_test_link(struct link_params *params, struct link_vars *vars, + u8 is_serdes) { struct bnx2x *bp = params->bp; u16 gp_status = 0, phy_index = 0; @@ -3284,10 +3287,10 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, return -ESRCH; } -static u8 bnx2x_link_initialize(struct link_params *params, - struct link_vars *vars) +static int bnx2x_link_initialize(struct link_params *params, + struct link_vars *vars) { - u8 rc = 0; + int rc = 0; u8 phy_index, non_ext_phy; struct bnx2x *bp = params->bp; /* @@ -3380,8 +3383,8 @@ static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "reset external PHY\n"); } -static u8 bnx2x_update_link_down(struct link_params *params, - struct link_vars *vars) +static int bnx2x_update_link_down(struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -3412,13 +3415,13 @@ static u8 bnx2x_update_link_down(struct link_params *params, return 0; } -static u8 bnx2x_update_link_up(struct link_params *params, - struct link_vars *vars, - u8 link_10g) +static int bnx2x_update_link_up(struct link_params *params, + struct link_vars *vars, + u8 link_10g) { struct bnx2x *bp = params->bp; u8 port = params->port; - u8 rc = 0; + int rc = 0; vars->link_status |= LINK_STATUS_LINK_UP; @@ -3472,13 +3475,14 @@ static u8 bnx2x_update_link_up(struct link_params *params, * external phy needs to be up, and at least one of the 2 * external phy link must be up. */ -u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) +int bnx2x_link_update(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; struct link_vars phy_vars[MAX_PHYS]; u8 port = params->port; u8 link_10g, phy_index; - u8 ext_phy_link_up = 0, cur_link_up, rc = 0; + u8 ext_phy_link_up = 0, cur_link_up; + int rc = 0; u8 is_mi_int = 0; u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; u8 active_external_phy = INT_PHY; @@ -3866,13 +3870,13 @@ static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, pause_result); } } -static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, - struct bnx2x_phy *phy, - u8 port) +static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port) { u32 count = 0; u16 fw_ver1, fw_msgout; - u8 rc = 0; + int rc = 0; /* Boot port from external ROM */ /* EDC grst */ @@ -3947,7 +3951,7 @@ static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, /******************************************************************/ /* BCM8073 PHY SECTION */ /******************************************************************/ -static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) +static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) { /* This is only required for 8073A1, version 102 only */ u16 val; @@ -3973,7 +3977,7 @@ static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) return 1; } -static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) +static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) { u16 val, cnt, cnt1 ; @@ -4080,9 +4084,9 @@ static void bnx2x_8073_set_pause_cl37(struct link_params *params, msleep(500); } -static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_8073_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 val = 0, tmp1; @@ -4388,9 +4392,9 @@ static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, /******************************************************************/ /* BCM8705 PHY SECTION */ /******************************************************************/ -static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_8705_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "init 8705\n"); @@ -4521,9 +4525,9 @@ static void bnx2x_sfp_set_transmitter(struct link_params *params, } } -static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, - u16 addr, u8 byte_cnt, u8 *o_buf) +static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, + u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val = 0; @@ -4587,9 +4591,9 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } -static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, - u16 addr, u8 byte_cnt, u8 *o_buf) +static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, + u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val, i; @@ -4674,11 +4678,11 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } -u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, u16 addr, - u8 byte_cnt, u8 *o_buf) +int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, + u8 byte_cnt, u8 *o_buf) { - u8 rc = -EINVAL; + int rc = -EINVAL; switch (phy->type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, @@ -4693,9 +4697,9 @@ u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, return rc; } -static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, - struct link_params *params, - u16 *edc_mode) +static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, + struct link_params *params, + u16 *edc_mode) { struct bnx2x *bp = params->bp; u32 sync_offset = 0, phy_idx, media_types; @@ -4800,8 +4804,8 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, * This function read the relevant field from the module (SFP+), and verify it * is compliant with this board */ -static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, - struct link_params *params) +static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u32 val, cmd; @@ -4870,8 +4874,8 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, return -EINVAL; } -static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, - struct link_params *params) +static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, + struct link_params *params) { u8 val; @@ -4929,9 +4933,9 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, val); } -static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, - struct bnx2x_phy *phy, - u16 edc_mode) +static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 edc_mode) { u16 cur_limiting_mode; @@ -4979,9 +4983,9 @@ static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, return 0; } -static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, - struct bnx2x_phy *phy, - u16 edc_mode) +static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 edc_mode) { u16 phy_identifier; u16 rom_ver2_val; @@ -5098,12 +5102,12 @@ static void bnx2x_set_limiting_mode(struct link_params *params, } } -static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, - struct link_params *params) +int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 edc_mode; - u8 rc = 0; + int rc = 0; u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. @@ -5353,9 +5357,9 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, return 0; } -static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_8706_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { return bnx2x_8706_8726_read_status(phy, params, vars); } @@ -5430,9 +5434,9 @@ static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, } -static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_8726_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u32 val; @@ -5620,9 +5624,9 @@ static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } -static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_8727_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { u32 tx_en_mode; u16 tmp1, val, mod_abs, tmp2; @@ -6142,9 +6146,9 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp, 0xFFFB, 0xFFFD); } -static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; @@ -6270,9 +6274,9 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, return 0; } -static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_8481_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; /* Restore normal power mode*/ @@ -6287,16 +6291,16 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, return bnx2x_848xx_cmn_config_init(phy, params, vars); } -static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 port, initialize = 1; u16 val, adj; u16 temp; u32 actual_phy_selection, cms_enable; - u8 rc = 0; + int rc = 0; /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ adj = 0; @@ -6475,9 +6479,10 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, return link_up; } -static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) + +static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) { - u8 status = 0; + int status = 0; u32 spirom_ver; spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F); status = bnx2x_format_ver(spirom_ver, str, len); @@ -6718,9 +6723,9 @@ static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); } -static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_7101_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { u16 fw_ver1, fw_ver2, val; struct bnx2x *bp = params->bp; @@ -6793,8 +6798,7 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, return link_up; } - -static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len) +static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len) { if (*len < 5) return -EINVAL; @@ -7331,8 +7335,8 @@ static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, return ext_phy_config; } -static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, - struct bnx2x_phy *phy) +static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, + struct bnx2x_phy *phy) { u32 phy_addr; u32 chip_id; @@ -7374,12 +7378,12 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, return 0; } -static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, - u8 phy_index, - u32 shmem_base, - u32 shmem2_base, - u8 port, - struct bnx2x_phy *phy) +static int bnx2x_populate_ext_phy(struct bnx2x *bp, + u8 phy_index, + u32 shmem_base, + u32 shmem2_base, + u8 port, + struct bnx2x_phy *phy) { u32 ext_phy_config, phy_type, config2; u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH; @@ -7483,10 +7487,10 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, return 0; } -static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, - u32 shmem2_base, u8 port, struct bnx2x_phy *phy) +static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, + u32 shmem2_base, u8 port, struct bnx2x_phy *phy) { - u8 status = 0; + int status = 0; phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; if (phy_index == INT_PHY) return bnx2x_populate_int_phy(bp, shmem_base, port, phy); @@ -7600,7 +7604,7 @@ u32 bnx2x_phy_selection(struct link_params *params) } -u8 bnx2x_phy_probe(struct link_params *params) +int bnx2x_phy_probe(struct link_params *params) { u8 phy_index, actual_phy_idx, link_cfg_idx; u32 phy_config_swapped, sync_offset, media_types; @@ -7704,7 +7708,7 @@ static void set_phy_vars(struct link_params *params) } } -u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) +int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "Phy Initialization started\n"); @@ -7827,8 +7831,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) } return 0; } -u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, - u8 reset_ext_phy) + +int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, + u8 reset_ext_phy) { struct bnx2x *bp = params->bp; u8 phy_index, port = params->port, clear_latch_ind = 0; @@ -7900,10 +7905,10 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /****************************************************************************/ /* Common function */ /****************************************************************************/ -static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, - u32 shmem_base_path[], - u32 shmem2_base_path[], u8 phy_index, - u32 chip_id) +static int bnx2x_8073_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; @@ -8026,10 +8031,10 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, } return 0; } -static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, - u32 shmem_base_path[], - u32 shmem2_base_path[], u8 phy_index, - u32 chip_id) +static int bnx2x_8726_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { u32 val; s8 port; @@ -8120,10 +8125,11 @@ static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base, break; } } -static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, - u32 shmem_base_path[], - u32 shmem2_base_path[], u8 phy_index, - u32 chip_id) + +static int bnx2x_8727_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { s8 port, reset_gpio; u32 swap_val, swap_override; @@ -8216,11 +8222,11 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, return 0; } -static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], - u32 shmem2_base_path[], u8 phy_index, - u32 ext_phy_type, u32 chip_id) +static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 ext_phy_type, u32 chip_id) { - u8 rc = 0; + int rc = 0; switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: @@ -8262,10 +8268,10 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], return rc; } -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], - u32 shmem2_base_path[], u32 chip_id) +int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u32 chip_id) { - u8 rc = 0; + int rc = 0; u32 phy_ver; u8 phy_index; u32 ext_phy_type, ext_phy_config; diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index ac348daae2f..418bef472e0 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -281,40 +281,41 @@ struct link_vars { /***********************************************************/ /* Functions */ /***********************************************************/ -u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output); +int bnx2x_phy_init(struct link_params *params, struct link_vars *vars); /* Reset the link. Should be called when driver or interface goes down Before calling phy firmware upgrade, the reset_ext_phy should be set to 0 */ -u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, - u8 reset_ext_phy); +int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, + u8 reset_ext_phy); /* bnx2x_link_update should be called upon link interrupt */ -u8 bnx2x_link_update(struct link_params *input, struct link_vars *output); +int bnx2x_link_update(struct link_params *params, struct link_vars *vars); /* use the following phy functions to read/write from external_phy In order to use it to read/write internal phy registers, use DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as the register */ -u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, - u8 devad, u16 reg, u16 *ret_val); +int bnx2x_phy_read(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 *ret_val); + +int bnx2x_phy_write(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 val); -u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, - u8 devad, u16 reg, u16 val); /* Reads the link_status from the shmem, and update the link vars accordingly */ void bnx2x_link_status_update(struct link_params *input, struct link_vars *output); /* returns string representing the fw_version of the external phy */ -u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, - u8 *version, u16 len); +int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, + u8 *version, u16 len); /* Set/Unset the led Basically, the CLC takes care of the led for the link, but in case one needs to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to blink the led, and LED_MODE_OFF to set the led off.*/ -u8 bnx2x_set_led(struct link_params *params, struct link_vars *vars, - u8 mode, u32 speed); +int bnx2x_set_led(struct link_params *params, + struct link_vars *vars, u8 mode, u32 speed); #define LED_MODE_OFF 0 #define LED_MODE_ON 1 #define LED_MODE_OPER 2 @@ -326,12 +327,12 @@ void bnx2x_handle_module_detect_int(struct link_params *params); /* Get the actual link status. In case it returns 0, link is up, otherwise link is down*/ -u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars, - u8 is_serdes); +int bnx2x_test_link(struct link_params *params, struct link_vars *vars, + u8 is_serdes); /* One-time initialization for external phy after power up */ -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], - u32 shmem2_base_path[], u32 chip_id); +int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u32 chip_id); /* Reset the external PHY using GPIO */ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); @@ -340,9 +341,9 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy); /* Read "byte_cnt" bytes from address "addr" from the SFP+ EEPROM */ -u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, u16 addr, - u8 byte_cnt, u8 *o_buf); +int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, + u8 byte_cnt, u8 *o_buf); void bnx2x_hw_reset_phy(struct link_params *params); @@ -354,7 +355,8 @@ u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 bnx2x_phy_selection(struct link_params *params); /* Probe the phys on board, and populate them in "params" */ -u8 bnx2x_phy_probe(struct link_params *params); +int bnx2x_phy_probe(struct link_params *params); + /* Checks if fan failure detection is required on one of the phys on board */ u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 port); @@ -392,7 +394,7 @@ void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, const u32 cos1_bw); /* Used to configure the ETS to strict */ -u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); +int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); /* Read pfc statistic*/ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, -- cgit v1.2.3-70-g09d2 From c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39ba Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:27:06 +0000 Subject: bnx2x: Add TX fault check for fiber PHYs In case TX fault is detected on Fiber PHYs, declare the link as down until TX fault is gone. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 72 +++++++++++++++++++++++++++++++++++++++--- drivers/net/bnx2x/bnx2x_link.h | 3 ++ drivers/net/bnx2x/bnx2x_reg.h | 1 + 3 files changed, 72 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 7705e79945e..87c5d9ff816 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -3495,6 +3495,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) phy_vars[phy_index].duplex = DUPLEX_FULL; phy_vars[phy_index].phy_link_up = 0; phy_vars[phy_index].link_up = 0; + phy_vars[phy_index].fault_detected = 0; } DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", @@ -3707,7 +3708,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) */ vars->link_up = (vars->phy_link_up && (ext_phy_link_up || - SINGLE_MEDIA_DIRECT(params))); + SINGLE_MEDIA_DIRECT(params)) && + (phy_vars[active_external_phy].fault_detected == 0)); if (vars->link_up) rc = bnx2x_update_link_up(params, vars, link_10g); @@ -5204,6 +5206,29 @@ void bnx2x_handle_module_detect_int(struct link_params *params) } } +/******************************************************************/ +/* Used by 8706 and 8727 */ +/******************************************************************/ +static void bnx2x_sfp_mask_fault(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 alarm_status_offset, + u16 alarm_ctrl_offset) +{ + u16 alarm_status, val; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, alarm_status_offset, + &alarm_status); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, alarm_status_offset, + &alarm_status); + /* Mask or enable the fault event. */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val); + if (alarm_status & (1<<0)) + val &= ~(1<<0); + else + val |= (1<<0); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val); +} /******************************************************************/ /* common BCM8706/BCM8726 PHY SECTION */ /******************************************************************/ @@ -5218,6 +5243,10 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, /* Clear RX Alarm*/ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + + bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM, + MDIO_PMA_REG_TX_ALARM_CTRL); + /* clear LASI indication*/ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); @@ -5249,6 +5278,17 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, bnx2x_ext_phy_resolve_fc(phy, params, vars); vars->duplex = DUPLEX_FULL; } + + /* Capture 10G link fault. Read twice to clear stale value. */ + if (vars->line_speed == SPEED_10000) { + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_ALARM, &val1); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_ALARM, &val1); + if (val1 & (1<<0)) + vars->fault_detected = 1; + } + return link_up; } @@ -5304,7 +5344,11 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, 0x400); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); + MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL, + 0); + /* Arm LASI for link and Tx fault. */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 3); } else { /* Force 1Gbps using autoneg with 1G advertisement */ @@ -5637,14 +5681,17 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_wait_reset_complete(bp, phy, params); rx_alarm_ctrl_val = (1<<2) | (1<<5) ; - lasi_ctrl_val = 0x0004; + /* Should be 0x6 to enable XS on Tx side. */ + lasi_ctrl_val = 0x0006; DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); /* enable LASI */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, rx_alarm_ctrl_val); - + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL, + 0); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); @@ -5899,6 +5946,9 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, vars->line_speed = 0; DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); + bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM, + MDIO_PMA_REG_TX_ALARM_CTRL); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); @@ -5991,6 +6041,20 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "port %x: External link is down\n", params->port); } + + /* Capture 10G link fault. */ + if (vars->line_speed == SPEED_10000) { + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_ALARM, &val1); + + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_ALARM, &val1); + + if (val1 & (1<<0)) { + vars->fault_detected = 1; + } + } + if (link_up) { bnx2x_ext_phy_resolve_fc(phy, params, vars); vars->duplex = DUPLEX_FULL; diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 418bef472e0..4d5509bf87a 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -276,6 +276,9 @@ struct link_vars { /* The same definitions as the shmem parameter */ u32 link_status; + u8 fault_detected; + u8 rsrv1; + u16 rsrv2; }; /***********************************************************/ diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 86bba25d2d3..7260d09cf25 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6037,6 +6037,7 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_BCM_CTRL 0x0096 #define MDIO_PMA_REG_FEC_CTRL 0x00ab #define MDIO_PMA_REG_RX_ALARM_CTRL 0x9000 +#define MDIO_PMA_REG_TX_ALARM_CTRL 0x9001 #define MDIO_PMA_REG_LASI_CTRL 0x9002 #define MDIO_PMA_REG_RX_ALARM 0x9003 #define MDIO_PMA_REG_TX_ALARM 0x9004 -- cgit v1.2.3-70-g09d2 From 27d024321cf4fc0a96c41c3b0f3c123796734a63 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:27:48 +0000 Subject: bnx2x: Fix over current port display On 57712 chip, port number is enumerated per engine, so it requires adjustment in port display to the user. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 87c5d9ff816..ffc3c16166d 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -4919,15 +4919,14 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, */ if (phy->flags & FLAGS_NOC) return; - if (!(phy->flags & - FLAGS_NOC) && is_power_up) + if (is_power_up) val = (1<<4); else /* * Set GPIO control to OUTPUT, and set the power bit * to according to the is_power_up */ - val = ((!(is_power_up)) << 1); + val = (1<<1); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, @@ -5928,7 +5927,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; - u8 link_up = 0; + u8 link_up = 0, oc_port = params->port; u16 link_status = 0; u16 rx_alarm_status, lasi_ctrl, val1; @@ -5969,8 +5968,10 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, &val1); if ((val1 & (1<<8)) == 0) { + if (!CHIP_IS_E1x(bp)) + oc_port = BP_PATH(bp) + (params->port << 1); DP(NETIF_MSG_LINK, "8727 Power fault has been detected" - " on port %d\n", params->port); + " on port %d\n", oc_port); netdev_err(bp->dev, "Error: Power fault on Port %d has" " been detected and the power to " "that SFP+ module has been removed" @@ -5978,7 +5979,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, " Please remove the SFP+ module and" " restart the system to clear this" " error.\n", - params->port); + oc_port); /* Disable all RX_ALARMs except for mod_abs */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, -- cgit v1.2.3-70-g09d2 From bac27bd941454aaf40f7876ce3b487e303c4953d Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:28:10 +0000 Subject: bnx2x: Fix BCM84833 settings Fix BCM84833 register settings. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 206 +++++++++++++++++++++++++++++------------ drivers/net/bnx2x/bnx2x_reg.h | 23 +++++ 2 files changed, 171 insertions(+), 58 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index ffc3c16166d..6c70e86fad2 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -6099,111 +6099,106 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, struct link_params *params) { - u16 val, fw_ver1, fw_ver2, cnt, adj; + u16 val, fw_ver1, fw_ver2, cnt; + u8 port; struct bnx2x *bp = params->bp; - adj = 0; - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) - adj = -1; + port = params->port; /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0014); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, 0x0300); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x0009); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); if (val & 1) break; udelay(5); } if (cnt == 100) { DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); - bnx2x_save_spirom_version(bp, params->port, 0, + bnx2x_save_spirom_version(bp, port, 0, phy->ver_addr); return; } /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x000A); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); if (val & 1) break; udelay(5); } if (cnt == 100) { DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); - bnx2x_save_spirom_version(bp, params->port, 0, + bnx2x_save_spirom_version(bp, port, 0, phy->ver_addr); return; } /* lower 16 bits of the register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, &fw_ver1); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); /* upper 16 bits of register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, &fw_ver2); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); - bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, + bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1, phy->ver_addr); } static void bnx2x_848xx_set_led(struct bnx2x *bp, struct bnx2x_phy *phy) { - u16 val, adj; - - adj = 0; - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) - adj = -1; + u16 val; /* PHYC_CTL_LED_CTL */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL + adj, &val); + MDIO_PMA_REG_8481_LINK_SIGNAL, &val); val &= 0xFE00; val |= 0x0092; bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL + adj, val); + MDIO_PMA_REG_8481_LINK_SIGNAL, val); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK + adj, + MDIO_PMA_REG_8481_LED1_MASK, 0x80); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK + adj, + MDIO_PMA_REG_8481_LED2_MASK, 0x18); /* Select activity source by Tx and Rx, as suggested by PHY AE */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK + adj, + MDIO_PMA_REG_8481_LED3_MASK, 0x0006); /* Select the closest activity blink rate to that in 10/100/1000 */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_BLINK + adj, + MDIO_PMA_REG_8481_LED3_BLINK, 0); bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, &val); + MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val); val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, val); + MDIO_PMA_REG_84823_CTL_LED_CTL_1, val); /* 'Interrupt Mask' */ bnx2x_cl45_write(bp, phy, @@ -6217,6 +6212,13 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; + u16 tmp_req_line_speed; + + tmp_req_line_speed = phy->req_line_speed; + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) + if (phy->req_line_speed == SPEED_10000) + phy->req_line_speed = SPEED_AUTO_NEG; + /* * This phy uses the NIG latch mechanism since link indication * arrives through its LED4 and not via its LASI signal, so we @@ -6336,6 +6338,8 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, /* Save spirom version */ bnx2x_save_848xx_spirom_version(phy, params); + phy->req_line_speed = tmp_req_line_speed; + return 0; } @@ -6356,33 +6360,109 @@ static int bnx2x_8481_config_init(struct bnx2x_phy *phy, return bnx2x_848xx_cmn_config_init(phy, params, vars); } + +#define PHY84833_HDSHK_WAIT 300 +static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u32 idx; + u16 val; + u16 data = 0x01b1; + struct bnx2x *bp = params->bp; + /* Do pair swap */ + + + /* Write CMD_OPEN_OVERRIDE to STATUS reg */ + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG2, + PHY84833_CMD_OPEN_OVERRIDE); + for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) { + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG2, &val); + if (val == PHY84833_CMD_OPEN_FOR_CMDS) + break; + msleep(1); + } + if (idx >= PHY84833_HDSHK_WAIT) { + DP(NETIF_MSG_LINK, "Pairswap: FW not ready.\n"); + return -EINVAL; + } + + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG4, + data); + /* Issue pair swap command */ + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG0, + PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE); + for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) { + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG2, &val); + if ((val == PHY84833_CMD_COMPLETE_PASS) || + (val == PHY84833_CMD_COMPLETE_ERROR)) + break; + msleep(1); + } + if ((idx >= PHY84833_HDSHK_WAIT) || + (val == PHY84833_CMD_COMPLETE_ERROR)) { + DP(NETIF_MSG_LINK, "Pairswap: override failed.\n"); + return -EINVAL; + } + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG2, + PHY84833_CMD_CLEAR_COMPLETE); + DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data); + return 0; +} + static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 port, initialize = 1; - u16 val, adj; + u16 val; u16 temp; u32 actual_phy_selection, cms_enable; int rc = 0; - /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ - adj = 0; - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) - adj = 3; - msleep(1); - if (CHIP_IS_E2(bp)) + + if (!(CHIP_IS_E1(bp))) port = BP_PATH(bp); else port = params->port; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - port); + + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, + port); + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, 0x8000); + } + bnx2x_wait_reset_complete(bp, phy, params); /* Wait for GPHY to come out of reset */ msleep(50); + + /* Bring PHY out of super isolate mode */ + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { + bnx2x_cl45_read(bp, phy, + MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); + val &= ~MDIO_84833_SUPER_ISOLATE; + bnx2x_cl45_write(bp, phy, + MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); + bnx2x_wait_reset_complete(bp, phy, params); + } + + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) + bnx2x_84833_pair_swap_cfg(phy, params, vars); + /* * BCM84823 requires that XGXS links up first @ 10G for normal behavior */ @@ -6395,7 +6475,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, /* Set dual-media configuration according to configuration */ bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, - MDIO_CTL_REG_84823_MEDIA + adj, &val); + MDIO_CTL_REG_84823_MEDIA, &val); val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | MDIO_CTL_REG_84823_MEDIA_LINE_MASK | MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN | @@ -6428,7 +6508,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G; bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, - MDIO_CTL_REG_84823_MEDIA + adj, val); + MDIO_CTL_REG_84823_MEDIA, val); DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", params->multi_phy_config, val); @@ -6459,20 +6539,16 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val, val1, val2, adj; + u16 val, val1, val2; u8 link_up = 0; - /* Reg offset adjustment for 84833 */ - adj = 0; - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) - adj = -1; /* Check 10G-BaseT link status */ /* Check PMD signal ok */ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, 0xFFFA, &val1); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL + adj, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, &val2); DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2); @@ -6577,13 +6653,21 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u8 port; - if (CHIP_IS_E2(bp)) + + if (!(CHIP_IS_E1(bp))) port = BP_PATH(bp); else port = params->port; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); + + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + port); + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, 0x800); + } } static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, @@ -6591,11 +6675,17 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 val; + u8 port; + + if (!(CHIP_IS_E1(bp))) + port = BP_PATH(bp); + else + port = params->port; switch (mode) { case LED_MODE_OFF: - DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port); + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port); if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == SHARED_HW_CFG_LED_EXTPHY1) { @@ -6631,7 +6721,7 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, case LED_MODE_FRONT_PANEL_OFF: DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n", - params->port); + port); if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == SHARED_HW_CFG_LED_EXTPHY1) { @@ -6666,7 +6756,7 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, break; case LED_MODE_ON: - DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port); + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port); if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == SHARED_HW_CFG_LED_EXTPHY1) { @@ -6713,7 +6803,7 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, case LED_MODE_OPER: - DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port); + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port); if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == SHARED_HW_CFG_LED_EXTPHY1) { diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 7260d09cf25..11d35250b09 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6202,6 +6202,29 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_84823_CTL_LED_CTL_1 0xa8e3 #define MDIO_PMA_REG_84823_LED3_STRETCH_EN 0x0080 +/* BCM84833 only */ +#define MDIO_84833_TOP_CFG_XGPHY_STRAP1 0x401a +#define MDIO_84833_SUPER_ISOLATE 0x8000 +/* These are mailbox register set used by 84833. */ +#define MDIO_84833_TOP_CFG_SCRATCH_REG0 0x4005 +#define MDIO_84833_TOP_CFG_SCRATCH_REG1 0x4006 +#define MDIO_84833_TOP_CFG_SCRATCH_REG2 0x4007 +#define MDIO_84833_TOP_CFG_SCRATCH_REG3 0x4008 +#define MDIO_84833_TOP_CFG_SCRATCH_REG4 0x4009 + +/* Mailbox command set used by 84833. */ +#define PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE 0x2 +/* Mailbox status set used by 84833. */ +#define PHY84833_CMD_RECEIVED 0x0001 +#define PHY84833_CMD_IN_PROGRESS 0x0002 +#define PHY84833_CMD_COMPLETE_PASS 0x0004 +#define PHY84833_CMD_COMPLETE_ERROR 0x0008 +#define PHY84833_CMD_OPEN_FOR_CMDS 0x0010 +#define PHY84833_CMD_SYSTEM_BOOT 0x0020 +#define PHY84833_CMD_NOT_OPEN_FOR_CMDS 0x0040 +#define PHY84833_CMD_CLEAR_COMPLETE 0x0080 +#define PHY84833_CMD_OPEN_OVERRIDE 0xa5a5 + #define IGU_FUNC_BASE 0x0400 #define IGU_ADDR_MSIX 0x0000 -- cgit v1.2.3-70-g09d2 From 9045f6b44a01737a84c5bb79f580dccce6806d80 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:28:27 +0000 Subject: bnx2x: Fix grammar and relocate code This patch relocates some functions as a preparation for next patches, and also fixes some grammar mistakes. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 536 +++++++++++++++++++++-------------------- drivers/net/bnx2x/bnx2x_link.h | 6 +- 2 files changed, 276 insertions(+), 266 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 6c70e86fad2..81bcd614106 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -509,7 +509,7 @@ static void bnx2x_emac_init(struct link_params *params, } static int bnx2x_emac_enable(struct link_params *params, - struct link_vars *vars, u8 lb) + struct link_vars *vars, u8 lb) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -1613,7 +1613,172 @@ static void bnx2x_xgxs_deassert(struct link_params *params) params->phy[INT_PHY].def_md_devad); } +static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, + struct link_params *params, u16 *ieee_fc) +{ + struct bnx2x *bp = params->bp; + *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; + /** + * resolve pause mode and advertisement Please refer to Table + * 28B-3 of the 802.3ab-1999 spec + */ + + switch (phy->req_flow_ctrl) { + case BNX2X_FLOW_CTRL_AUTO: + if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) + *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + else + *ieee_fc |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + break; + + case BNX2X_FLOW_CTRL_TX: + *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + break; + + case BNX2X_FLOW_CTRL_RX: + case BNX2X_FLOW_CTRL_BOTH: + *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + break; + + case BNX2X_FLOW_CTRL_NONE: + default: + *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + break; + } + DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc); +} + +static void set_phy_vars(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 actual_phy_idx, phy_index, link_cfg_idx; + u8 phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; + for (phy_index = INT_PHY; phy_index < params->num_phys; + phy_index++) { + link_cfg_idx = LINK_CONFIG_IDX(phy_index); + actual_phy_idx = phy_index; + if (phy_config_swapped) { + if (phy_index == EXT_PHY1) + actual_phy_idx = EXT_PHY2; + else if (phy_index == EXT_PHY2) + actual_phy_idx = EXT_PHY1; + } + params->phy[actual_phy_idx].req_flow_ctrl = + params->req_flow_ctrl[link_cfg_idx]; + + params->phy[actual_phy_idx].req_line_speed = + params->req_line_speed[link_cfg_idx]; + + params->phy[actual_phy_idx].speed_cap_mask = + params->speed_cap_mask[link_cfg_idx]; + params->phy[actual_phy_idx].req_duplex = + params->req_duplex[link_cfg_idx]; + + if (params->req_line_speed[link_cfg_idx] == + SPEED_AUTO_NEG) + vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; + + DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," + " speed_cap_mask %x\n", + params->phy[actual_phy_idx].req_flow_ctrl, + params->phy[actual_phy_idx].req_line_speed, + params->phy[actual_phy_idx].speed_cap_mask); + } +} + +static void bnx2x_ext_phy_set_pause(struct link_params *params, + struct bnx2x_phy *phy, + struct link_vars *vars) +{ + u16 val; + struct bnx2x *bp = params->bp; + /* read modify write pause advertizing */ + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); + + val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; + + /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { + val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; + } + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { + val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; + } + DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); +} + +static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) +{ /* LD LP */ + switch (pause_result) { /* ASYM P ASYM P */ + case 0xb: /* 1 0 1 1 */ + vars->flow_ctrl = BNX2X_FLOW_CTRL_TX; + break; + + case 0xe: /* 1 1 1 0 */ + vars->flow_ctrl = BNX2X_FLOW_CTRL_RX; + break; + + case 0x5: /* 0 1 0 1 */ + case 0x7: /* 0 1 1 1 */ + case 0xd: /* 1 1 0 1 */ + case 0xf: /* 1 1 1 1 */ + vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH; + break; + + default: + break; + } + if (pause_result & (1<<0)) + vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE; + if (pause_result & (1<<1)) + vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE; +} + +static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 ld_pause; /* local */ + u16 lp_pause; /* link partner */ + u16 pause_result; + u8 ret = 0; + /* read twice */ + + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) + vars->flow_ctrl = phy->req_flow_ctrl; + else if (phy->req_line_speed != SPEED_AUTO_NEG) + vars->flow_ctrl = params->req_fc_auto_adv; + else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { + ret = 1; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_ADV_PAUSE, &ld_pause); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); + pause_result = (ld_pause & + MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; + pause_result |= (lp_pause & + MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; + DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", + pause_result); + bnx2x_pause_resolve(vars, pause_result); + } + return ret; +} void bnx2x_link_status_update(struct link_params *params, struct link_vars *vars) { @@ -2078,8 +2243,8 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, } -static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 val = 0; @@ -2100,44 +2265,9 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy, MDIO_OVER_1G_UP3, 0x400); } -static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, - struct link_params *params, u16 *ieee_fc) -{ - struct bnx2x *bp = params->bp; - *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; - /* - * Resolve pause mode and advertisement. - * Please refer to Table 28B-3 of the 802.3ab-1999 spec - */ - - switch (phy->req_flow_ctrl) { - case BNX2X_FLOW_CTRL_AUTO: - if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) - *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; - else - *ieee_fc |= - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; - break; - case BNX2X_FLOW_CTRL_TX: - *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; - break; - - case BNX2X_FLOW_CTRL_RX: - case BNX2X_FLOW_CTRL_BOTH: - *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; - break; - - case BNX2X_FLOW_CTRL_NONE: - default: - *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; - break; - } - DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc); -} - -static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy, - struct link_params *params, - u16 ieee_fc) +static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy, + struct link_params *params, + u16 ieee_fc) { struct bnx2x *bp = params->bp; u16 val; @@ -2271,33 +2401,6 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, * link management */ -static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) -{ /* LD LP */ - switch (pause_result) { /* ASYM P ASYM P */ - case 0xb: /* 1 0 1 1 */ - vars->flow_ctrl = BNX2X_FLOW_CTRL_TX; - break; - - case 0xe: /* 1 1 1 0 */ - vars->flow_ctrl = BNX2X_FLOW_CTRL_RX; - break; - - case 0x5: /* 0 1 0 1 */ - case 0x7: /* 0 1 1 1 */ - case 0xd: /* 1 1 0 1 */ - case 0xf: /* 1 1 1 1 */ - vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH; - break; - - default: - break; - } - if (pause_result & (1<<0)) - vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE; - if (pause_result & (1<<1)) - vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE; -} - static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, struct link_params *params) { @@ -2402,7 +2505,7 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u16 rx_status, ustat_val, cl37_fsm_recieved; + u16 rx_status, ustat_val, cl37_fsm_received; DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n"); /* Step 1: Make sure signal is detected */ CL22_RD_OVER_CL45(bp, phy, @@ -2440,15 +2543,15 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_REMOTE_PHY, MDIO_REMOTE_PHY_MISC_RX_STATUS, - &cl37_fsm_recieved); - if ((cl37_fsm_recieved & + &cl37_fsm_received); + if ((cl37_fsm_received & (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG | MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) != (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG | MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) { DP(NETIF_MSG_LINK, "No CL37 FSM were received. " "misc_rx_status(0x8330) = 0x%x\n", - cl37_fsm_recieved); + cl37_fsm_received); return; } /* @@ -2761,11 +2864,11 @@ static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "not SGMII, AN\n"); /* AN enabled */ - bnx2x_set_brcm_cl37_advertisment(phy, params); + bnx2x_set_brcm_cl37_advertisement(phy, params); /* program duplex & pause advertisement (for aneg) */ - bnx2x_set_ieee_aneg_advertisment(phy, params, - vars->ieee_fc); + bnx2x_set_ieee_aneg_advertisement(phy, params, + vars->ieee_fc); /* enable autoneg */ bnx2x_set_autoneg(phy, params, vars, enable_cl73); @@ -3338,7 +3441,8 @@ static int bnx2x_link_initialize(struct link_params *params, if (phy_index == EXT_PHY2 && (bnx2x_phy_selection(params) == PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { - DP(NETIF_MSG_LINK, "Ignoring second phy\n"); + DP(NETIF_MSG_LINK, "Not initializing" + " second phy\n"); continue; } params->phy[phy_index].config_init( @@ -3520,7 +3624,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) * Step 1: * Check external link change only for external phys, and apply * priority selection between them in case the link on both phys - * is up. Note that the instead of the common vars, a temporary + * is up. Note that instead of the common vars, a temporary * vars argument is used since each phy may have different link/ * speed/duplex result */ @@ -3704,7 +3808,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) } /* * Link is up only if both local phy and external phy (in case of - * non-direct board) are up + * non-direct board) are up and no fault detected on active PHY. */ vars->link_up = (vars->phy_link_up && (ext_phy_link_up || @@ -3756,69 +3860,6 @@ static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, phy->ver_addr); } -static void bnx2x_ext_phy_set_pause(struct link_params *params, - struct bnx2x_phy *phy, - struct link_vars *vars) -{ - u16 val; - struct bnx2x *bp = params->bp; - /* read modify write pause advertizing */ - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); - - val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; - - /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ - bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { - val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; - } - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { - val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; - } - DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); -} - -static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u16 ld_pause; /* local */ - u16 lp_pause; /* link partner */ - u16 pause_result; - u8 ret = 0; - /* read twice */ - - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) - vars->flow_ctrl = phy->req_flow_ctrl; - else if (phy->req_line_speed != SPEED_AUTO_NEG) - vars->flow_ctrl = params->req_fc_auto_adv; - else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { - ret = 1; - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &ld_pause); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); - pause_result = (ld_pause & - MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; - pause_result |= (lp_pause & - MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; - DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", - pause_result); - bnx2x_pause_resolve(vars, pause_result); - } - return ret; -} - static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp, struct bnx2x_phy *phy, struct link_vars *vars) @@ -4732,8 +4773,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy, params, SFP_EEPROM_FC_TX_TECH_ADDR, 1, - &copper_module_type) != - 0) { + &copper_module_type) != 0) { DP(NETIF_MSG_LINK, "Failed to read copper-cable-type" " from SFP+ EEPROM\n"); @@ -5938,7 +5978,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, if (!lasi_ctrl) return 0; - /* Check the LASI */ + /* Check the LASI on Rx */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); @@ -6322,10 +6362,10 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || (phy->req_line_speed == SPEED_10000)) { - DP(NETIF_MSG_LINK, "Advertising 10G\n"); - /* Restart autoneg for 10G*/ + DP(NETIF_MSG_LINK, "Advertising 10G\n"); + /* Restart autoneg for 10G*/ - bnx2x_cl45_write(bp, phy, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x3200); } else if (phy->req_line_speed != SPEED_10 && @@ -7031,9 +7071,8 @@ static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy, static struct bnx2x_phy phy_null = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN, .addr = 0, - .flags = FLAGS_INIT_XGXS_FIRST, .def_md_devad = 0, - .reserved = 0, + .flags = FLAGS_INIT_XGXS_FIRST, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7058,9 +7097,8 @@ static struct bnx2x_phy phy_null = { static struct bnx2x_phy phy_serdes = { .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT, .addr = 0xff, - .flags = 0, .def_md_devad = 0, - .reserved = 0, + .flags = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7094,9 +7132,8 @@ static struct bnx2x_phy phy_serdes = { static struct bnx2x_phy phy_xgxs = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, .addr = 0xff, - .flags = 0, .def_md_devad = 0, - .reserved = 0, + .flags = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7131,9 +7168,8 @@ static struct bnx2x_phy phy_xgxs = { static struct bnx2x_phy phy_7101 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, .addr = 0xff, - .flags = FLAGS_FAN_FAILURE_DET_REQ, .def_md_devad = 0, - .reserved = 0, + .flags = FLAGS_FAN_FAILURE_DET_REQ, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7161,9 +7197,8 @@ static struct bnx2x_phy phy_7101 = { static struct bnx2x_phy phy_8073 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, .addr = 0xff, - .flags = FLAGS_HW_LOCK_REQUIRED, .def_md_devad = 0, - .reserved = 0, + .flags = FLAGS_HW_LOCK_REQUIRED, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7193,9 +7228,8 @@ static struct bnx2x_phy phy_8073 = { static struct bnx2x_phy phy_8705 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705, .addr = 0xff, - .flags = FLAGS_INIT_XGXS_FIRST, .def_md_devad = 0, - .reserved = 0, + .flags = FLAGS_INIT_XGXS_FIRST, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7222,9 +7256,8 @@ static struct bnx2x_phy phy_8705 = { static struct bnx2x_phy phy_8706 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, .addr = 0xff, - .flags = FLAGS_INIT_XGXS_FIRST, .def_md_devad = 0, - .reserved = 0, + .flags = FLAGS_INIT_XGXS_FIRST, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7253,10 +7286,9 @@ static struct bnx2x_phy phy_8706 = { static struct bnx2x_phy phy_8726 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, .addr = 0xff, + .def_md_devad = 0, .flags = (FLAGS_HW_LOCK_REQUIRED | FLAGS_INIT_XGXS_FIRST), - .def_md_devad = 0, - .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7286,9 +7318,8 @@ static struct bnx2x_phy phy_8726 = { static struct bnx2x_phy phy_8727 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, .addr = 0xff, - .flags = FLAGS_FAN_FAILURE_DET_REQ, .def_md_devad = 0, - .reserved = 0, + .flags = FLAGS_FAN_FAILURE_DET_REQ, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7316,10 +7347,9 @@ static struct bnx2x_phy phy_8727 = { static struct bnx2x_phy phy_8481 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, .addr = 0xff, + .def_md_devad = 0, .flags = FLAGS_FAN_FAILURE_DET_REQ | FLAGS_REARM_LATCH_SIGNAL, - .def_md_devad = 0, - .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7353,10 +7383,9 @@ static struct bnx2x_phy phy_8481 = { static struct bnx2x_phy phy_84823 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, .addr = 0xff, + .def_md_devad = 0, .flags = FLAGS_FAN_FAILURE_DET_REQ | FLAGS_REARM_LATCH_SIGNAL, - .def_md_devad = 0, - .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7390,10 +7419,9 @@ static struct bnx2x_phy phy_84823 = { static struct bnx2x_phy phy_84833 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833, .addr = 0xff, + .def_md_devad = 0, .flags = FLAGS_FAN_FAILURE_DET_REQ | FLAGS_REARM_LATCH_SIGNAL, - .def_md_devad = 0, - .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -7827,77 +7855,10 @@ int bnx2x_phy_probe(struct link_params *params) return 0; } -static void set_phy_vars(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u8 actual_phy_idx, phy_index, link_cfg_idx; - u8 phy_config_swapped = params->multi_phy_config & - PORT_HW_CFG_PHY_SWAPPED_ENABLED; - for (phy_index = INT_PHY; phy_index < params->num_phys; - phy_index++) { - link_cfg_idx = LINK_CONFIG_IDX(phy_index); - actual_phy_idx = phy_index; - if (phy_config_swapped) { - if (phy_index == EXT_PHY1) - actual_phy_idx = EXT_PHY2; - else if (phy_index == EXT_PHY2) - actual_phy_idx = EXT_PHY1; - } - params->phy[actual_phy_idx].req_flow_ctrl = - params->req_flow_ctrl[link_cfg_idx]; - - params->phy[actual_phy_idx].req_line_speed = - params->req_line_speed[link_cfg_idx]; - - params->phy[actual_phy_idx].speed_cap_mask = - params->speed_cap_mask[link_cfg_idx]; - - params->phy[actual_phy_idx].req_duplex = - params->req_duplex[link_cfg_idx]; - - DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," - " speed_cap_mask %x\n", - params->phy[actual_phy_idx].req_flow_ctrl, - params->phy[actual_phy_idx].req_line_speed, - params->phy[actual_phy_idx].speed_cap_mask); - } -} - -int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) +void bnx2x_init_bmac_loopback(struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "Phy Initialization started\n"); - DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n", - params->req_line_speed[0], params->req_flow_ctrl[0]); - DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n", - params->req_line_speed[1], params->req_flow_ctrl[1]); - vars->link_status = 0; - vars->phy_link_up = 0; - vars->link_up = 0; - vars->line_speed = 0; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->mac_type = MAC_TYPE_NONE; - vars->phy_flags = 0; - - /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); - - bnx2x_emac_init(params, vars); - - if (params->num_phys == 0) { - DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); - return -EINVAL; - } - set_phy_vars(params); - - DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); - if (params->loopback_mode == LOOPBACK_BMAC) { - vars->link_up = 1; vars->line_speed = SPEED_10000; vars->duplex = DUPLEX_FULL; @@ -7912,9 +7873,12 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_bmac_enable(params, vars, 1); REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); +} - } else if (params->loopback_mode == LOOPBACK_EMAC) { - +void bnx2x_init_emac_loopback(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; vars->link_up = 1; vars->line_speed = SPEED_1000; vars->duplex = DUPLEX_FULL; @@ -7928,29 +7892,32 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_emac_enable(params, vars, 1); bnx2x_emac_program(params, vars); REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); +} - } else if ((params->loopback_mode == LOOPBACK_XGXS) || - (params->loopback_mode == LOOPBACK_EXT_PHY)) { - +void bnx2x_init_xgxs_loopback(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; vars->link_up = 1; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->duplex = DUPLEX_FULL; - if (params->req_line_speed[0] == SPEED_1000) { + if (params->req_line_speed[0] == SPEED_1000) vars->line_speed = SPEED_1000; - vars->mac_type = MAC_TYPE_EMAC; - } else { + else vars->line_speed = SPEED_10000; - vars->mac_type = MAC_TYPE_BMAC; - } - bnx2x_xgxs_deassert(params); - bnx2x_link_initialize(params, vars); - if (params->req_line_speed[0] == SPEED_1000) { - bnx2x_emac_program(params, vars); - bnx2x_emac_enable(params, vars, 0); - } else - bnx2x_bmac_enable(params, vars, 0); + bnx2x_xgxs_deassert(params); + bnx2x_link_initialize(params, vars); + + if (params->req_line_speed[0] == SPEED_1000) { + bnx2x_emac_program(params, vars); + bnx2x_emac_enable(params, vars, 0); + + } else + bnx2x_bmac_enable(params, vars, 0); + + if (params->loopback_mode == LOOPBACK_XGXS) { /* set 10G XGXS loopback */ params->phy[INT_PHY].config_loopback( @@ -7970,11 +7937,55 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) } REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); - bnx2x_set_led(params, vars, - LED_MODE_OPER, vars->line_speed); - } else - /* No loopback */ - { + bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); +} + +int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Phy Initialization started\n"); + DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[0], params->req_flow_ctrl[0]); + DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[1], params->req_flow_ctrl[1]); + vars->link_status = 0; + vars->phy_link_up = 0; + vars->link_up = 0; + vars->line_speed = 0; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->mac_type = MAC_TYPE_NONE; + vars->phy_flags = 0; + + /* disable attentions */ + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); + + bnx2x_emac_init(params, vars); + + if (params->num_phys == 0) { + DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); + return -EINVAL; + } + set_phy_vars(params, vars); + + DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); + switch (params->loopback_mode) { + case LOOPBACK_BMAC: + bnx2x_init_bmac_loopback(params, vars); + break; + case LOOPBACK_EMAC: + bnx2x_init_emac_loopback(params, vars); + break; + case LOOPBACK_XGXS: + case LOOPBACK_EXT_PHY: + bnx2x_init_xgxs_loopback(params, vars); + break; + default: + /* No loopback */ if (params->switch_cfg == SWITCH_CFG_10G) bnx2x_xgxs_deassert(params); else @@ -7983,6 +7994,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_link_initialize(params, vars); msleep(30); bnx2x_link_int_enable(params); + break; } return 0; } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 4d5509bf87a..906b5117083 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -121,8 +121,8 @@ struct bnx2x_phy { /* Loaded during init */ u8 addr; - - u8 flags; + u8 def_md_devad; + u16 flags; /* Require HW lock */ #define FLAGS_HW_LOCK_REQUIRED (1<<0) /* No Over-Current detection */ @@ -134,8 +134,6 @@ struct bnx2x_phy { #define FLAGS_REARM_LATCH_SIGNAL (1<<6) #define FLAGS_SFP_NOT_APPROVED (1<<7) - u8 def_md_devad; - u8 reserved; /* preemphasis values for the rx side */ u16 rx_preemphasis[4]; -- cgit v1.2.3-70-g09d2 From 020c7e3f3cd38d41104c7f55d3d5732c5ac939be Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:28:43 +0000 Subject: bnx2x: Adjust BCM8726 module detection settings Move BCM8726 module detection code into a separate function to be called only once during initialization. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 5 ++- drivers/net/bnx2x/bnx2x_link.c | 100 +++++++++++++++++++++++++++++------------ drivers/net/bnx2x/bnx2x_link.h | 4 ++ drivers/net/bnx2x/bnx2x_main.c | 4 ++ drivers/net/bnx2x/bnx2x_reg.h | 1 + 5 files changed, 85 insertions(+), 29 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 5bfdbcc94a7..c308a48c8f4 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -263,7 +263,10 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_FAULT_MODULE_LED_GPIO2 0x00000200 #define PORT_HW_CFG_FAULT_MODULE_LED_GPIO3 0x00000300 #define PORT_HW_CFG_FAULT_MODULE_LED_DISABLED 0x00000400 - u32 Reserved01[11]; /* 0x158 */ + + u32 Reserved01[10]; /* 0x158 */ + + u32 aeu_int_mask; /* 0x190 */ u32 media_type; /* 0x194 */ #define PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK 0x000000FF diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 81bcd614106..e44c19d86c3 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1915,8 +1915,15 @@ void bnx2x_link_status_update(struct link_params *params, PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT; DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types); - DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", - vars->link_status, vars->phy_link_up); + /* Sync AEU offset */ + sync_offset = params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].aeu_int_mask); + + vars->aeu_int_mask = REG_RD(bp, sync_offset); + + DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", + vars->link_status, vars->phy_link_up, vars->aeu_int_mask); DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", vars->line_speed, vars->duplex, vars->flow_ctrl); } @@ -5522,8 +5529,6 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 val; - u32 swap_val, swap_override, aeu_gpio_mask, offset; DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -5602,30 +5607,6 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, phy->tx_preemphasis[1]); } - /* Set GPIO3 to trigger SFP+ module insertion/removal */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); - - /* The GPIO should be swapped if the swap register is set and active */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - - /* Select function upon port-swap configuration */ - if (params->port == 0) { - offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; - } else { - offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; - } - val = REG_RD(bp, offset); - /* add GPIO3 to group */ - val |= aeu_gpio_mask; - REG_WR(bp, offset, val); return 0; } @@ -8521,3 +8502,66 @@ void bnx2x_hw_reset_phy(struct link_params *params) } } } + +void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, + u32 chip_id, u32 shmem_base, u32 shmem2_base, + u8 port) +{ + u8 gpio_num = 0xff, gpio_port = 0xff, phy_index; + u32 val; + u32 offset, aeu_mask, swap_val, swap_override, sync_offset; + + { + struct bnx2x_phy phy; + for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; + phy_index++) { + if (bnx2x_populate_phy(bp, phy_index, shmem_base, + shmem2_base, port, &phy) + != 0) { + DP(NETIF_MSG_LINK, "populate phy failed\n"); + return; + } + if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) { + gpio_num = MISC_REGISTERS_GPIO_3; + gpio_port = port; + break; + } + } + } + + if (gpio_num == 0xff) + return; + + /* Set GPIO3 to trigger SFP+ module insertion/removal */ + bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port); + + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + gpio_port ^= (swap_val && swap_override); + + vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 << + (gpio_num + (gpio_port << 2)); + + sync_offset = shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].aeu_int_mask); + REG_WR(bp, sync_offset, vars->aeu_int_mask); + + DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n", + gpio_num, gpio_port, vars->aeu_int_mask); + + if (port == 0) + offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; + else + offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; + + /* Open appropriate AEU for interrupts */ + aeu_mask = REG_RD(bp, offset); + aeu_mask |= vars->aeu_int_mask; + REG_WR(bp, offset, aeu_mask); + + /* Enable the GPIO to trigger interrupt */ + val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); + val |= 1 << (gpio_num + (gpio_port << 2)); + REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); +} diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 906b5117083..a106d8cbd69 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -277,6 +277,7 @@ struct link_vars { u8 fault_detected; u8 rsrv1; u16 rsrv2; + u32 aeu_int_mask; }; /***********************************************************/ @@ -401,4 +402,7 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, u32 pfc_frames_sent[2], u32 pfc_frames_received[2]); +void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, + u32 chip_id, u32 shmem_base, u32 shmem2_base, + u8 port); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index c6591c46ebd..2e89b6cf37a 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4452,6 +4452,10 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) #endif + /* Initialize MOD_ABS interrupts */ + bnx2x_init_mod_abs_int(bp, &bp->link_vars, bp->common.chip_id, + bp->common.shmem_base, bp->common.shmem2_base, + BP_PORT(bp)); /* ensure status block indices were read */ rmb(); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 11d35250b09..949e8bd7318 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5184,6 +5184,7 @@ #define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11) #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13) #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12) +#define AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 (1<<2) #define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (1<<5) #define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (1<<9) #define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12) -- cgit v1.2.3-70-g09d2 From fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:29:05 +0000 Subject: bnx2x: Fix link status sync Fix link status synchronization between the primary function, and rest functions. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index e44c19d86c3..1816b2d5b71 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1786,12 +1786,15 @@ void bnx2x_link_status_update(struct link_params *params, u8 link_10g; u8 port = params->port; u32 sync_offset, media_types; + /* Update PHY configuration */ + set_phy_vars(params, vars); + vars->link_status = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, port_mb[port].link_status)); vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); - + vars->phy_flags = PHY_XGXS_FLAG; if (vars->link_up) { DP(NETIF_MSG_LINK, "phy link up\n"); @@ -3436,7 +3439,11 @@ static int bnx2x_link_initialize(struct link_params *params, } /* Init external phy*/ - if (!non_ext_phy) + if (non_ext_phy) { + if (params->phy[INT_PHY].supported & + SUPPORTED_FIBRE) + vars->link_status |= LINK_STATUS_SERDES_LINK; + } else { for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { /* @@ -3445,6 +3452,10 @@ static int bnx2x_link_initialize(struct link_params *params, * need to initialize the first phy, since they are * connected. */ + if (params->phy[phy_index].supported & + SUPPORTED_FIBRE) + vars->link_status |= LINK_STATUS_SERDES_LINK; + if (phy_index == EXT_PHY2 && (bnx2x_phy_selection(params) == PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { @@ -3456,7 +3467,7 @@ static int bnx2x_link_initialize(struct link_params *params, ¶ms->phy[phy_index], params, vars); } - + } /* Reset the interrupt indication after phy was initialized */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + params->port*4, @@ -3464,6 +3475,7 @@ static int bnx2x_link_initialize(struct link_params *params, NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); + bnx2x_update_mng(params, vars->link_status); return rc; } @@ -3507,7 +3519,12 @@ static int bnx2x_update_link_down(struct link_params *params, vars->mac_type = MAC_TYPE_NONE; /* update shared memory */ - vars->link_status = 0; + vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | + LINK_STATUS_LINK_UP | + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | + LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK); vars->line_speed = 0; bnx2x_update_mng(params, vars->link_status); @@ -3597,7 +3614,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) u8 is_mi_int = 0; u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; u8 active_external_phy = INT_PHY; - vars->link_status = 0; + for (phy_index = INT_PHY; phy_index < params->num_phys; phy_index++) { phy_vars[phy_index].flow_ctrl = 0; @@ -3738,6 +3755,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) if (params->phy[active_external_phy].supported & SUPPORTED_FIBRE) vars->link_status |= LINK_STATUS_SERDES_LINK; + else + vars->link_status &= ~LINK_STATUS_SERDES_LINK; DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", active_external_phy); } -- cgit v1.2.3-70-g09d2 From ec146a6f019923819f5ca381980248b6d154ca1a Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:29:27 +0000 Subject: bnx2x: Modify XGXS functions Modify XGXS functions to follow rest of PHY scheme. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 1 + drivers/net/bnx2x/bnx2x_link.c | 89 +++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 53 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index c308a48c8f4..b8b4b2f0b60 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -467,6 +467,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_SHIFT 24 #define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT 0x00000000 #define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482 0x01000000 +#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD 0x02000000 #define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN 0xff000000 #define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK 0x00ff0000 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 1816b2d5b71..43e3663ab33 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1530,8 +1530,8 @@ int bnx2x_phy_write(struct link_params *params, u8 phy_addr, return -EINVAL; } -static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, - struct bnx2x_phy *phy) +static void bnx2x_set_aer_mmd(struct link_params *params, + struct bnx2x_phy *phy) { u32 ser_lane; u16 offset, aer_val; @@ -1540,20 +1540,17 @@ static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - offset = phy->addr + ser_lane; + offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? + (phy->addr + ser_lane) : 0; + if (CHIP_IS_E2(bp)) aer_val = 0x3800 + offset - 1; else aer_val = 0x3800 + offset; + DP(NETIF_MSG_LINK, "Set AER to 0x%x\n", aer_val); CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, aer_val); -} -static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp, - struct bnx2x_phy *phy) -{ - CL22_WR_OVER_CL45(bp, phy, - MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0x3800); + } /******************************************************************/ @@ -2845,9 +2842,9 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, } } -static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) || @@ -2894,29 +2891,12 @@ static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, } } -static int bnx2x_init_serdes(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - int rc; - vars->phy_flags |= PHY_SGMII_FLAG; - bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - bnx2x_set_aer_mmd_serdes(params->bp, phy); - rc = bnx2x_reset_unicore(params, phy, 1); - /* reset the SerDes and wait for reset bit return low */ - if (rc != 0) - return rc; - bnx2x_set_aer_mmd_serdes(params->bp, phy); - - return rc; -} - -static int bnx2x_init_xgxs(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { int rc; - vars->phy_flags = PHY_XGXS_FLAG; + vars->phy_flags |= PHY_XGXS_FLAG; if ((phy->req_line_speed && ((phy->req_line_speed == SPEED_100) || (phy->req_line_speed == SPEED_10))) || @@ -2924,26 +2904,28 @@ static int bnx2x_init_xgxs(struct bnx2x_phy *phy, (phy->speed_cap_mask >= PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && (phy->speed_cap_mask < - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) - )) + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || + (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD)) vars->phy_flags |= PHY_SGMII_FLAG; else vars->phy_flags &= ~PHY_SGMII_FLAG; bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - bnx2x_set_aer_mmd_xgxs(params, phy); - bnx2x_set_master_ln(params, phy); + bnx2x_set_aer_mmd(params, phy); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) + bnx2x_set_master_ln(params, phy); rc = bnx2x_reset_unicore(params, phy, 0); /* reset the SerDes and wait for reset bit return low */ if (rc != 0) return rc; - bnx2x_set_aer_mmd_xgxs(params, phy); - + bnx2x_set_aer_mmd(params, phy); /* setting the masterLn_def again after the reset */ - bnx2x_set_master_ln(params, phy); - bnx2x_set_swap_lanes(params, phy); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { + bnx2x_set_master_ln(params, phy); + bnx2x_set_swap_lanes(params, phy); + } return rc; } @@ -3220,7 +3202,7 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, 0x6041); msleep(200); /* set aer mmd back */ - bnx2x_set_aer_mmd_xgxs(params, phy); + bnx2x_set_aer_mmd(params, phy); /* and md_devad */ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad); @@ -3420,11 +3402,7 @@ static int bnx2x_link_initialize(struct link_params *params, * to first. */ - if (params->phy[INT_PHY].config_init) - params->phy[INT_PHY].config_init( - ¶ms->phy[INT_PHY], - params, vars); - + bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars); /* init ext phy and enable link state int */ non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || (params->loopback_mode == LOOPBACK_XGXS)); @@ -3435,7 +3413,10 @@ static int bnx2x_link_initialize(struct link_params *params, struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; if (vars->line_speed == SPEED_AUTO_NEG) bnx2x_set_parallel_detection(phy, params); - bnx2x_init_internal_phy(phy, params, vars); + if (params->phy[INT_PHY].config_init) + params->phy[INT_PHY].config_init(phy, + params, + vars); } /* Init external phy*/ @@ -3827,8 +3808,10 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) vars->phy_flags |= PHY_SGMII_FLAG; else vars->phy_flags &= ~PHY_SGMII_FLAG; - bnx2x_init_internal_phy(¶ms->phy[INT_PHY], - params, + + if (params->phy[INT_PHY].config_init) + params->phy[INT_PHY].config_init( + ¶ms->phy[INT_PHY], params, vars); } } @@ -7119,7 +7102,7 @@ static struct bnx2x_phy phy_serdes = { .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, - .config_init = (config_init_t)bnx2x_init_serdes, + .config_init = (config_init_t)bnx2x_xgxs_config_init, .read_status = (read_status_t)bnx2x_link_settings_status, .link_reset = (link_reset_t)bnx2x_int_link_reset, .config_loopback = (config_loopback_t)NULL, @@ -7155,7 +7138,7 @@ static struct bnx2x_phy phy_xgxs = { .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, - .config_init = (config_init_t)bnx2x_init_xgxs, + .config_init = (config_init_t)bnx2x_xgxs_config_init, .read_status = (read_status_t)bnx2x_link_settings_status, .link_reset = (link_reset_t)bnx2x_int_link_reset, .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback, -- cgit v1.2.3-70-g09d2 From a198c142aacf82acad29e1752191bda8b451a0c7 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 31 May 2011 21:29:42 +0000 Subject: bnx2x: Improve cl45 access methods Instead of setting CL45 mode for every CL45 access, apply it once during initialization. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 136 ++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 71 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 43e3663ab33..15b5bc17433 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -464,6 +464,29 @@ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, /******************************************************************/ /* MAC/PBF section */ /******************************************************************/ +static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port) +{ + u32 mode, emac_base; + /** + * Set clause 45 mode, slow down the MDIO clock to 2.5MHz + * (a value of 49==0x31) and make sure that the AUTO poll is off + */ + + if (CHIP_IS_E2(bp)) + emac_base = GRCBASE_EMAC0; + else + emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + mode &= ~(EMAC_MDIO_MODE_AUTO_POLL | + EMAC_MDIO_MODE_CLOCK_CNT); + mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); + + mode |= (EMAC_MDIO_MODE_CLAUSE_45); + REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode); + + udelay(40); +} + static void bnx2x_emac_init(struct link_params *params, struct link_vars *vars) { @@ -495,7 +518,7 @@ static void bnx2x_emac_init(struct link_params *params, } timeout--; } while (val & EMAC_MODE_RESET); - + bnx2x_set_mdio_clk(bp, params->chip_id, port); /* Set mac address */ val = ((params->mac_addr[0] << 8) | params->mac_addr[1]); @@ -1352,144 +1375,113 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, /******************************************************************/ /* CL45 access functions */ /******************************************************************/ -static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 val) +static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val) { - u32 tmp, saved_mode; - u8 i; + u32 val; + u16 i; int rc = 0; - /* - * Set clause 45 mode, slow down the MDIO clock to 2.5MHz - * (a value of 49==0x31) and make sure that the AUTO poll is off - */ - - saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); - tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL | - EMAC_MDIO_MODE_CLOCK_CNT); - tmp |= (EMAC_MDIO_MODE_CLAUSE_45 | - (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); - REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); - udelay(40); /* address */ - - tmp = ((phy->addr << 21) | (devad << 16) | reg | + val = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); - if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { + val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + if (!(val & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; } } - if (tmp & EMAC_MDIO_COMM_START_BUSY) { - DP(NETIF_MSG_LINK, "write phy register failed\n"); + if (val & EMAC_MDIO_COMM_START_BUSY) { + DP(NETIF_MSG_LINK, "read phy register failed\n"); netdev_err(bp->dev, "MDC/MDIO access timeout\n"); + *ret_val = 0; rc = -EFAULT; } else { /* data */ - tmp = ((phy->addr << 21) | (devad << 16) | val | - EMAC_MDIO_COMM_COMMAND_WRITE_45 | + val = ((phy->addr << 21) | (devad << 16) | + EMAC_MDIO_COMM_COMMAND_READ_45 | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, phy->mdio_ctrl + + val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); - if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { - udelay(5); + if (!(val & EMAC_MDIO_COMM_START_BUSY)) { + *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); break; } } - if (tmp & EMAC_MDIO_COMM_START_BUSY) { - DP(NETIF_MSG_LINK, "write phy register failed\n"); + if (val & EMAC_MDIO_COMM_START_BUSY) { + DP(NETIF_MSG_LINK, "read phy register failed\n"); netdev_err(bp->dev, "MDC/MDIO access timeout\n"); + *ret_val = 0; rc = -EFAULT; } } - /* Restore the saved mode */ - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); - return rc; } -static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 *ret_val) +static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val) { - u32 val, saved_mode; - u16 i; + u32 tmp; + u8 i; int rc = 0; - /* - * Set clause 45 mode, slow down the MDIO clock to 2.5MHz - * (a value of 49==0x31) and make sure that the AUTO poll is off - */ - - saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); - val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL | - EMAC_MDIO_MODE_CLOCK_CNT)); - val |= (EMAC_MDIO_MODE_CLAUSE_45 | - (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); - REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); - udelay(40); /* address */ - val = ((phy->addr << 21) | (devad << 16) | reg | + + tmp = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); - if (!(val & EMAC_MDIO_COMM_START_BUSY)) { + tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; } } - if (val & EMAC_MDIO_COMM_START_BUSY) { - DP(NETIF_MSG_LINK, "read phy register failed\n"); + if (tmp & EMAC_MDIO_COMM_START_BUSY) { + DP(NETIF_MSG_LINK, "write phy register failed\n"); netdev_err(bp->dev, "MDC/MDIO access timeout\n"); - *ret_val = 0; rc = -EFAULT; } else { /* data */ - val = ((phy->addr << 21) | (devad << 16) | - EMAC_MDIO_COMM_COMMAND_READ_45 | + tmp = ((phy->addr << 21) | (devad << 16) | val | + EMAC_MDIO_COMM_COMMAND_WRITE_45 | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, phy->mdio_ctrl + + tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); - if (!(val & EMAC_MDIO_COMM_START_BUSY)) { - *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); + if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); break; } } - if (val & EMAC_MDIO_COMM_START_BUSY) { - DP(NETIF_MSG_LINK, "read phy register failed\n"); + if (tmp & EMAC_MDIO_COMM_START_BUSY) { + DP(NETIF_MSG_LINK, "write phy register failed\n"); netdev_err(bp->dev, "MDC/MDIO access timeout\n"); - *ret_val = 0; rc = -EFAULT; } } - /* Restore the saved mode */ - REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); return rc; } @@ -8425,6 +8417,8 @@ int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], u32 phy_ver; u8 phy_index; u32 ext_phy_type, ext_phy_config; + bnx2x_set_mdio_clk(bp, chip_id, PORT_0); + bnx2x_set_mdio_clk(bp, chip_id, PORT_1); DP(NETIF_MSG_LINK, "Begin common phy init\n"); /* Check if common init was already done */ -- cgit v1.2.3-70-g09d2 From 40d69043fce579378eb185d31445b6ff66abbd93 Mon Sep 17 00:00:00 2001 From: "Dmitry.Tarnyagin" Date: Wed, 1 Jun 2011 03:29:18 +0000 Subject: caif: Add CAIF HSI Link layer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch introduces the CAIF HSI Protocol Driver for the CAIF Link Layer. This driver implements a platform driver to accommodate for a platform specific HSI devices. A general platform driver is not possible as there are no HSI side Kernel API defined. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/Kconfig | 9 + drivers/net/caif/Makefile | 3 + drivers/net/caif/caif_hsi.c | 1220 +++++++++++++++++++++++++++++++++++++++++++ include/net/caif/caif_hsi.h | 145 +++++ 4 files changed, 1377 insertions(+) create mode 100644 drivers/net/caif/caif_hsi.c create mode 100644 include/net/caif/caif_hsi.h (limited to 'drivers/net') diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index 09ed3f42d67..abf4d7a9dcc 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig @@ -38,3 +38,12 @@ config CAIF_SHM default n ---help--- The CAIF shared memory protocol driver for the STE UX5500 platform. + +config CAIF_HSI + tristate "CAIF HSI transport driver" + depends on CAIF + default n + ---help--- + The caif low level driver for CAIF over HSI. + Be aware that if you enable this then you also need to + enable a low-level HSI driver. diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile index 9560b9d624b..91dff861560 100644 --- a/drivers/net/caif/Makefile +++ b/drivers/net/caif/Makefile @@ -10,3 +10,6 @@ obj-$(CONFIG_CAIF_SPI_SLAVE) += cfspi_slave.o # Shared memory caif_shm-objs := caif_shmcore.o caif_shm_u5500.o obj-$(CONFIG_CAIF_SHM) += caif_shm.o + +# HSI interface +obj-$(CONFIG_CAIF_HSI) += caif_hsi.o diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c new file mode 100644 index 00000000000..7a8ce61234a --- /dev/null +++ b/drivers/net/caif/caif_hsi.c @@ -0,0 +1,1220 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com + * Author: Daniel Martensson / daniel.martensson@stericsson.com + * Dmitry.Tarnyagin / dmitry.tarnyagin@stericsson.com + * License terms: GNU General Public License (GPL) version 2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Daniel Martensson"); +MODULE_DESCRIPTION("CAIF HSI driver"); + +/* Returns the number of padding bytes for alignment. */ +#define PAD_POW2(x, pow) ((((x)&((pow)-1)) == 0) ? 0 :\ + (((pow)-((x)&((pow)-1))))) + +/* + * HSI padding options. + * Warning: must be a base of 2 (& operation used) and can not be zero ! + */ +static int hsi_head_align = 4; +module_param(hsi_head_align, int, S_IRUGO); +MODULE_PARM_DESC(hsi_head_align, "HSI head alignment."); + +static int hsi_tail_align = 4; +module_param(hsi_tail_align, int, S_IRUGO); +MODULE_PARM_DESC(hsi_tail_align, "HSI tail alignment."); + +/* + * HSI link layer flowcontrol thresholds. + * Warning: A high threshold value migth increase throughput but it will at + * the same time prevent channel prioritization and increase the risk of + * flooding the modem. The high threshold should be above the low. + */ +static int hsi_high_threshold = 100; +module_param(hsi_high_threshold, int, S_IRUGO); +MODULE_PARM_DESC(hsi_high_threshold, "HSI high threshold (FLOW OFF)."); + +static int hsi_low_threshold = 50; +module_param(hsi_low_threshold, int, S_IRUGO); +MODULE_PARM_DESC(hsi_low_threshold, "HSI high threshold (FLOW ON)."); + +#define ON 1 +#define OFF 0 + +/* + * Threshold values for the HSI packet queue. Flowcontrol will be asserted + * when the number of packets exceeds HIGH_WATER_MARK. It will not be + * de-asserted before the number of packets drops below LOW_WATER_MARK. + */ +#define LOW_WATER_MARK hsi_low_threshold +#define HIGH_WATER_MARK hsi_high_threshold + +static LIST_HEAD(cfhsi_list); +static spinlock_t cfhsi_list_lock; + +static void cfhsi_inactivity_tout(unsigned long arg) +{ + struct cfhsi *cfhsi = (struct cfhsi *)arg; + + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + /* Schedule power down work queue. */ + if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + queue_work(cfhsi->wq, &cfhsi->wake_down_work); +} + +static void cfhsi_abort_tx(struct cfhsi *cfhsi) +{ + struct sk_buff *skb; + + for (;;) { + spin_lock_bh(&cfhsi->lock); + skb = skb_dequeue(&cfhsi->qhead); + if (!skb) + break; + + cfhsi->ndev->stats.tx_errors++; + cfhsi->ndev->stats.tx_dropped++; + spin_unlock_bh(&cfhsi->lock); + kfree_skb(skb); + } + cfhsi->tx_state = CFHSI_TX_STATE_IDLE; + if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + mod_timer(&cfhsi->timer, jiffies + CFHSI_INACTIVITY_TOUT); + spin_unlock_bh(&cfhsi->lock); +} + +static int cfhsi_flush_fifo(struct cfhsi *cfhsi) +{ + char buffer[32]; /* Any reasonable value */ + size_t fifo_occupancy; + int ret; + + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + + ret = cfhsi->dev->cfhsi_wake_up(cfhsi->dev); + if (ret) { + dev_warn(&cfhsi->ndev->dev, + "%s: can't wake up HSI interface: %d.\n", + __func__, ret); + return ret; + } + + do { + ret = cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, + &fifo_occupancy); + if (ret) { + dev_warn(&cfhsi->ndev->dev, + "%s: can't get FIFO occupancy: %d.\n", + __func__, ret); + break; + } else if (!fifo_occupancy) + /* No more data, exitting normally */ + break; + + fifo_occupancy = min(sizeof(buffer), fifo_occupancy); + set_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits); + ret = cfhsi->dev->cfhsi_rx(buffer, fifo_occupancy, + cfhsi->dev); + if (ret) { + clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits); + dev_warn(&cfhsi->ndev->dev, + "%s: can't read data: %d.\n", + __func__, ret); + break; + } + + ret = 5 * HZ; + wait_event_interruptible_timeout(cfhsi->flush_fifo_wait, + !test_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits), ret); + + if (ret < 0) { + dev_warn(&cfhsi->ndev->dev, + "%s: can't wait for flush complete: %d.\n", + __func__, ret); + break; + } else if (!ret) { + ret = -ETIMEDOUT; + dev_warn(&cfhsi->ndev->dev, + "%s: timeout waiting for flush complete.\n", + __func__); + break; + } + } while (1); + + cfhsi->dev->cfhsi_wake_down(cfhsi->dev); + + return ret; +} + +static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi) +{ + int nfrms = 0; + int pld_len = 0; + struct sk_buff *skb; + u8 *pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ; + + skb = skb_dequeue(&cfhsi->qhead); + if (!skb) + return 0; + + /* Check if we can embed a CAIF frame. */ + if (skb->len < CFHSI_MAX_EMB_FRM_SZ) { + struct caif_payload_info *info; + int hpad = 0; + int tpad = 0; + + /* Calculate needed head alignment and tail alignment. */ + info = (struct caif_payload_info *)&skb->cb; + + hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align); + tpad = PAD_POW2((skb->len + hpad), hsi_tail_align); + + /* Check if frame still fits with added alignment. */ + if ((skb->len + hpad + tpad) <= CFHSI_MAX_EMB_FRM_SZ) { + u8 *pemb = desc->emb_frm; + desc->offset = CFHSI_DESC_SHORT_SZ; + *pemb = (u8)(hpad - 1); + pemb += hpad; + + /* Update network statistics. */ + cfhsi->ndev->stats.tx_packets++; + cfhsi->ndev->stats.tx_bytes += skb->len; + + /* Copy in embedded CAIF frame. */ + skb_copy_bits(skb, 0, pemb, skb->len); + consume_skb(skb); + skb = NULL; + } + } else + /* Clear offset. */ + desc->offset = 0; + + /* Create payload CAIF frames. */ + pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ; + while (nfrms < CFHSI_MAX_PKTS) { + struct caif_payload_info *info; + int hpad = 0; + int tpad = 0; + + if (!skb) + skb = skb_dequeue(&cfhsi->qhead); + + if (!skb) + break; + + /* Calculate needed head alignment and tail alignment. */ + info = (struct caif_payload_info *)&skb->cb; + + hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align); + tpad = PAD_POW2((skb->len + hpad), hsi_tail_align); + + /* Fill in CAIF frame length in descriptor. */ + desc->cffrm_len[nfrms] = hpad + skb->len + tpad; + + /* Fill head padding information. */ + *pfrm = (u8)(hpad - 1); + pfrm += hpad; + + /* Update network statistics. */ + cfhsi->ndev->stats.tx_packets++; + cfhsi->ndev->stats.tx_bytes += skb->len; + + /* Copy in CAIF frame. */ + skb_copy_bits(skb, 0, pfrm, skb->len); + + /* Update payload length. */ + pld_len += desc->cffrm_len[nfrms]; + + /* Update frame pointer. */ + pfrm += skb->len + tpad; + consume_skb(skb); + skb = NULL; + + /* Update number of frames. */ + nfrms++; + } + + /* Unused length fields should be zero-filled (according to SPEC). */ + while (nfrms < CFHSI_MAX_PKTS) { + desc->cffrm_len[nfrms] = 0x0000; + nfrms++; + } + + /* Check if we can piggy-back another descriptor. */ + skb = skb_peek(&cfhsi->qhead); + if (skb) + desc->header |= CFHSI_PIGGY_DESC; + else + desc->header &= ~CFHSI_PIGGY_DESC; + + return CFHSI_DESC_SZ + pld_len; +} + +static void cfhsi_tx_done_work(struct work_struct *work) +{ + struct cfhsi *cfhsi = NULL; + struct cfhsi_desc *desc = NULL; + int len = 0; + int res; + + cfhsi = container_of(work, struct cfhsi, tx_done_work); + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + return; + + desc = (struct cfhsi_desc *)cfhsi->tx_buf; + + do { + /* + * Send flow on if flow off has been previously signalled + * and number of packets is below low water mark. + */ + spin_lock_bh(&cfhsi->lock); + if (cfhsi->flow_off_sent && + cfhsi->qhead.qlen <= cfhsi->q_low_mark && + cfhsi->cfdev.flowctrl) { + + cfhsi->flow_off_sent = 0; + cfhsi->cfdev.flowctrl(cfhsi->ndev, ON); + } + spin_unlock_bh(&cfhsi->lock); + + /* Create HSI frame. */ + len = cfhsi_tx_frm(desc, cfhsi); + if (!len) { + cfhsi->tx_state = CFHSI_TX_STATE_IDLE; + /* Start inactivity timer. */ + mod_timer(&cfhsi->timer, + jiffies + CFHSI_INACTIVITY_TOUT); + break; + } + + /* Set up new transfer. */ + res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); + if (WARN_ON(res < 0)) { + dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n", + __func__, res); + } + } while (res < 0); +} + +static void cfhsi_tx_done_cb(struct cfhsi_drv *drv) +{ + struct cfhsi *cfhsi; + + cfhsi = container_of(drv, struct cfhsi, drv); + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + return; + + queue_work(cfhsi->wq, &cfhsi->tx_done_work); +} + +static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi) +{ + int xfer_sz = 0; + int nfrms = 0; + u16 *plen = NULL; + u8 *pfrm = NULL; + + if ((desc->header & ~CFHSI_PIGGY_DESC) || + (desc->offset > CFHSI_MAX_EMB_FRM_SZ)) { + dev_err(&cfhsi->ndev->dev, "%s: Invalid descriptor.\n", + __func__); + return 0; + } + + /* Check for embedded CAIF frame. */ + if (desc->offset) { + struct sk_buff *skb; + u8 *dst = NULL; + int len = 0, retries = 0; + pfrm = ((u8 *)desc) + desc->offset; + + /* Remove offset padding. */ + pfrm += *pfrm + 1; + + /* Read length of CAIF frame (little endian). */ + len = *pfrm; + len |= ((*(pfrm+1)) << 8) & 0xFF00; + len += 2; /* Add FCS fields. */ + + + /* Allocate SKB (OK even in IRQ context). */ + skb = alloc_skb(len + 1, GFP_KERNEL); + while (!skb) { + retries++; + schedule_timeout(1); + skb = alloc_skb(len + 1, GFP_KERNEL); + if (skb) { + printk(KERN_WARNING "%s: slept for %u " + "before getting memory\n", + __func__, retries); + break; + } + if (retries > HZ) { + printk(KERN_ERR "%s: slept for 1HZ and " + "did not get memory\n", + __func__); + cfhsi->ndev->stats.rx_dropped++; + goto drop_frame; + } + } + caif_assert(skb != NULL); + + dst = skb_put(skb, len); + memcpy(dst, pfrm, len); + + skb->protocol = htons(ETH_P_CAIF); + skb_reset_mac_header(skb); + skb->dev = cfhsi->ndev; + + /* + * We are called from a arch specific platform device. + * Unfortunately we don't know what context we're + * running in. + */ + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + + /* Update network statistics. */ + cfhsi->ndev->stats.rx_packets++; + cfhsi->ndev->stats.rx_bytes += len; + } + +drop_frame: + /* Calculate transfer length. */ + plen = desc->cffrm_len; + while (nfrms < CFHSI_MAX_PKTS && *plen) { + xfer_sz += *plen; + plen++; + nfrms++; + } + + /* Check for piggy-backed descriptor. */ + if (desc->header & CFHSI_PIGGY_DESC) + xfer_sz += CFHSI_DESC_SZ; + + if (xfer_sz % 4) { + dev_err(&cfhsi->ndev->dev, + "%s: Invalid payload len: %d, ignored.\n", + __func__, xfer_sz); + xfer_sz = 0; + } + + return xfer_sz; +} + +static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) +{ + int rx_sz = 0; + int nfrms = 0; + u16 *plen = NULL; + u8 *pfrm = NULL; + + /* Sanity check header and offset. */ + if (WARN_ON((desc->header & ~CFHSI_PIGGY_DESC) || + (desc->offset > CFHSI_MAX_EMB_FRM_SZ))) { + dev_err(&cfhsi->ndev->dev, "%s: Invalid descriptor.\n", + __func__); + return -EINVAL; + } + + /* Set frame pointer to start of payload. */ + pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ; + plen = desc->cffrm_len; + while (nfrms < CFHSI_MAX_PKTS && *plen) { + struct sk_buff *skb; + u8 *dst = NULL; + u8 *pcffrm = NULL; + int len = 0, retries = 0; + + if (WARN_ON(desc->cffrm_len[nfrms] > CFHSI_MAX_PAYLOAD_SZ)) { + dev_err(&cfhsi->ndev->dev, "%s: Invalid payload.\n", + __func__); + return -EINVAL; + } + + /* CAIF frame starts after head padding. */ + pcffrm = pfrm + *pfrm + 1; + + /* Read length of CAIF frame (little endian). */ + len = *pcffrm; + len |= ((*(pcffrm + 1)) << 8) & 0xFF00; + len += 2; /* Add FCS fields. */ + + /* Allocate SKB (OK even in IRQ context). */ + skb = alloc_skb(len + 1, GFP_KERNEL); + while (!skb) { + retries++; + schedule_timeout(1); + skb = alloc_skb(len + 1, GFP_KERNEL); + if (skb) { + printk(KERN_WARNING "%s: slept for %u " + "before getting memory\n", + __func__, retries); + break; + } + if (retries > HZ) { + printk(KERN_ERR "%s: slept for 1HZ " + "and did not get memory\n", + __func__); + cfhsi->ndev->stats.rx_dropped++; + goto drop_frame; + } + } + caif_assert(skb != NULL); + + dst = skb_put(skb, len); + memcpy(dst, pcffrm, len); + + skb->protocol = htons(ETH_P_CAIF); + skb_reset_mac_header(skb); + skb->dev = cfhsi->ndev; + + /* + * We're called from a platform device, + * and don't know the context we're running in. + */ + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + + /* Update network statistics. */ + cfhsi->ndev->stats.rx_packets++; + cfhsi->ndev->stats.rx_bytes += len; + +drop_frame: + pfrm += *plen; + rx_sz += *plen; + plen++; + nfrms++; + } + + return rx_sz; +} + +static void cfhsi_rx_done_work(struct work_struct *work) +{ + int res; + int desc_pld_len = 0; + struct cfhsi *cfhsi = NULL; + struct cfhsi_desc *desc = NULL; + + cfhsi = container_of(work, struct cfhsi, rx_done_work); + desc = (struct cfhsi_desc *)cfhsi->rx_buf; + + dev_dbg(&cfhsi->ndev->dev, "%s: Kick timer if pending.\n", + __func__); + + if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + return; + + /* Update inactivity timer if pending. */ + mod_timer_pending(&cfhsi->timer, jiffies + CFHSI_INACTIVITY_TOUT); + + if (cfhsi->rx_state == CFHSI_RX_STATE_DESC) { + desc_pld_len = cfhsi_rx_desc(desc, cfhsi); + } else { + int pld_len; + + pld_len = cfhsi_rx_pld(desc, cfhsi); + + if ((pld_len > 0) && (desc->header & CFHSI_PIGGY_DESC)) { + struct cfhsi_desc *piggy_desc; + piggy_desc = (struct cfhsi_desc *) + (desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ + + pld_len); + + /* Extract piggy-backed descriptor. */ + desc_pld_len = cfhsi_rx_desc(piggy_desc, cfhsi); + + /* + * Copy needed information from the piggy-backed + * descriptor to the descriptor in the start. + */ + memcpy((u8 *)desc, (u8 *)piggy_desc, + CFHSI_DESC_SHORT_SZ); + } + } + + if (desc_pld_len) { + cfhsi->rx_state = CFHSI_RX_STATE_PAYLOAD; + cfhsi->rx_ptr = cfhsi->rx_buf + CFHSI_DESC_SZ; + cfhsi->rx_len = desc_pld_len; + } else { + cfhsi->rx_state = CFHSI_RX_STATE_DESC; + cfhsi->rx_ptr = cfhsi->rx_buf; + cfhsi->rx_len = CFHSI_DESC_SZ; + } + clear_bit(CFHSI_PENDING_RX, &cfhsi->bits); + + if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) { + /* Set up new transfer. */ + dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n", + __func__); + res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, + cfhsi->dev); + if (WARN_ON(res < 0)) { + dev_err(&cfhsi->ndev->dev, "%s: RX error %d.\n", + __func__, res); + cfhsi->ndev->stats.rx_errors++; + cfhsi->ndev->stats.rx_dropped++; + } + } +} + +static void cfhsi_rx_done_cb(struct cfhsi_drv *drv) +{ + struct cfhsi *cfhsi; + + cfhsi = container_of(drv, struct cfhsi, drv); + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + return; + + set_bit(CFHSI_PENDING_RX, &cfhsi->bits); + + if (test_and_clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits)) + wake_up_interruptible(&cfhsi->flush_fifo_wait); + else + queue_work(cfhsi->wq, &cfhsi->rx_done_work); +} + +static void cfhsi_wake_up(struct work_struct *work) +{ + struct cfhsi *cfhsi = NULL; + int res; + int len; + long ret; + + cfhsi = container_of(work, struct cfhsi, wake_up_work); + + if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + return; + + if (unlikely(test_bit(CFHSI_AWAKE, &cfhsi->bits))) { + /* It happenes when wakeup is requested by + * both ends at the same time. */ + clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); + return; + } + + /* Activate wake line. */ + cfhsi->dev->cfhsi_wake_up(cfhsi->dev); + + dev_dbg(&cfhsi->ndev->dev, "%s: Start waiting.\n", + __func__); + + /* Wait for acknowledge. */ + ret = CFHSI_WAKEUP_TOUT; + wait_event_interruptible_timeout(cfhsi->wake_up_wait, + test_bit(CFHSI_WAKE_UP_ACK, + &cfhsi->bits), ret); + if (unlikely(ret < 0)) { + /* Interrupted by signal. */ + dev_info(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", + __func__, ret); + clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); + cfhsi->dev->cfhsi_wake_down(cfhsi->dev); + return; + } else if (!ret) { + /* Wakeup timeout */ + dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", + __func__); + clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); + cfhsi->dev->cfhsi_wake_down(cfhsi->dev); + return; + } + dev_dbg(&cfhsi->ndev->dev, "%s: Woken.\n", + __func__); + + /* Clear power up bit. */ + set_bit(CFHSI_AWAKE, &cfhsi->bits); + clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); + + /* Resume read operation. */ + if (!test_bit(CFHSI_PENDING_RX, &cfhsi->bits)) { + dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n", + __func__); + res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, + cfhsi->rx_len, cfhsi->dev); + if (WARN_ON(res < 0)) { + dev_err(&cfhsi->ndev->dev, "%s: RX error %d.\n", + __func__, res); + } + } + + /* Clear power up acknowledment. */ + clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits); + + spin_lock_bh(&cfhsi->lock); + + /* Resume transmit if queue is not empty. */ + if (!skb_peek(&cfhsi->qhead)) { + dev_dbg(&cfhsi->ndev->dev, "%s: Peer wake, start timer.\n", + __func__); + /* Start inactivity timer. */ + mod_timer(&cfhsi->timer, + jiffies + CFHSI_INACTIVITY_TOUT); + spin_unlock_bh(&cfhsi->lock); + return; + } + + dev_dbg(&cfhsi->ndev->dev, "%s: Host wake.\n", + __func__); + + spin_unlock_bh(&cfhsi->lock); + + /* Create HSI frame. */ + len = cfhsi_tx_frm((struct cfhsi_desc *)cfhsi->tx_buf, cfhsi); + + if (likely(len > 0)) { + /* Set up new transfer. */ + res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); + if (WARN_ON(res < 0)) { + dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n", + __func__, res); + cfhsi_abort_tx(cfhsi); + } + } else { + dev_err(&cfhsi->ndev->dev, + "%s: Failed to create HSI frame: %d.\n", + __func__, len); + } + +} + +static void cfhsi_wake_down(struct work_struct *work) +{ + long ret; + struct cfhsi *cfhsi = NULL; + size_t fifo_occupancy; + + cfhsi = container_of(work, struct cfhsi, wake_down_work); + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + return; + + /* Check if there is something in FIFO. */ + if (WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, + &fifo_occupancy))) + fifo_occupancy = 0; + + if (fifo_occupancy) { + dev_dbg(&cfhsi->ndev->dev, + "%s: %u words in RX FIFO, restart timer.\n", + __func__, (unsigned) fifo_occupancy); + spin_lock_bh(&cfhsi->lock); + mod_timer(&cfhsi->timer, + jiffies + CFHSI_INACTIVITY_TOUT); + spin_unlock_bh(&cfhsi->lock); + return; + } + + /* Cancel pending RX requests */ + cfhsi->dev->cfhsi_rx_cancel(cfhsi->dev); + + /* Deactivate wake line. */ + cfhsi->dev->cfhsi_wake_down(cfhsi->dev); + + /* Wait for acknowledge. */ + ret = CFHSI_WAKEUP_TOUT; + ret = wait_event_interruptible_timeout(cfhsi->wake_down_wait, + test_bit(CFHSI_WAKE_DOWN_ACK, + &cfhsi->bits), + ret); + if (ret < 0) { + /* Interrupted by signal. */ + dev_info(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n", + __func__, ret); + return; + } else if (!ret) { + /* Timeout */ + dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", + __func__); + } + + /* Clear power down acknowledment. */ + clear_bit(CFHSI_WAKE_DOWN_ACK, &cfhsi->bits); + clear_bit(CFHSI_AWAKE, &cfhsi->bits); + + /* Check if there is something in FIFO. */ + if (WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, + &fifo_occupancy))) + fifo_occupancy = 0; + + if (fifo_occupancy) { + dev_dbg(&cfhsi->ndev->dev, + "%s: %u words in RX FIFO, wakeup forced.\n", + __func__, (unsigned) fifo_occupancy); + if (!test_and_set_bit(CFHSI_WAKE_UP, &cfhsi->bits)) + queue_work(cfhsi->wq, &cfhsi->wake_up_work); + } else + dev_dbg(&cfhsi->ndev->dev, "%s: Done.\n", + __func__); +} + +static void cfhsi_wake_up_cb(struct cfhsi_drv *drv) +{ + struct cfhsi *cfhsi = NULL; + + cfhsi = container_of(drv, struct cfhsi, drv); + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + set_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits); + wake_up_interruptible(&cfhsi->wake_up_wait); + + if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits)) + return; + + /* Schedule wake up work queue if the peer initiates. */ + if (!test_and_set_bit(CFHSI_WAKE_UP, &cfhsi->bits)) + queue_work(cfhsi->wq, &cfhsi->wake_up_work); +} + +static void cfhsi_wake_down_cb(struct cfhsi_drv *drv) +{ + struct cfhsi *cfhsi = NULL; + + cfhsi = container_of(drv, struct cfhsi, drv); + dev_dbg(&cfhsi->ndev->dev, "%s.\n", + __func__); + + /* Initiating low power is only permitted by the host (us). */ + set_bit(CFHSI_WAKE_DOWN_ACK, &cfhsi->bits); + wake_up_interruptible(&cfhsi->wake_down_wait); +} + +static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct cfhsi *cfhsi = NULL; + int start_xfer = 0; + int timer_active; + + if (!dev) + return -EINVAL; + + cfhsi = netdev_priv(dev); + + spin_lock_bh(&cfhsi->lock); + + skb_queue_tail(&cfhsi->qhead, skb); + + /* Sanity check; xmit should not be called after unregister_netdev */ + if (WARN_ON(test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))) { + spin_unlock_bh(&cfhsi->lock); + cfhsi_abort_tx(cfhsi); + return -EINVAL; + } + + /* Send flow off if number of packets is above high water mark. */ + if (!cfhsi->flow_off_sent && + cfhsi->qhead.qlen > cfhsi->q_high_mark && + cfhsi->cfdev.flowctrl) { + cfhsi->flow_off_sent = 1; + cfhsi->cfdev.flowctrl(cfhsi->ndev, OFF); + } + + if (cfhsi->tx_state == CFHSI_TX_STATE_IDLE) { + cfhsi->tx_state = CFHSI_TX_STATE_XFER; + start_xfer = 1; + } + + spin_unlock_bh(&cfhsi->lock); + + if (!start_xfer) + return 0; + + /* Delete inactivity timer if started. */ +#ifdef CONFIG_SMP + timer_active = del_timer_sync(&cfhsi->timer); +#else + timer_active = del_timer(&cfhsi->timer); +#endif /* CONFIG_SMP */ + + if (timer_active) { + struct cfhsi_desc *desc = (struct cfhsi_desc *)cfhsi->tx_buf; + int len; + int res; + + /* Create HSI frame. */ + len = cfhsi_tx_frm(desc, cfhsi); + BUG_ON(!len); + + /* Set up new transfer. */ + res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev); + if (WARN_ON(res < 0)) { + dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n", + __func__, res); + cfhsi_abort_tx(cfhsi); + } + } else { + /* Schedule wake up work queue if the we initiate. */ + if (!test_and_set_bit(CFHSI_WAKE_UP, &cfhsi->bits)) + queue_work(cfhsi->wq, &cfhsi->wake_up_work); + } + + return 0; +} + +static int cfhsi_open(struct net_device *dev) +{ + netif_wake_queue(dev); + + return 0; +} + +static int cfhsi_close(struct net_device *dev) +{ + netif_stop_queue(dev); + + return 0; +} + +static const struct net_device_ops cfhsi_ops = { + .ndo_open = cfhsi_open, + .ndo_stop = cfhsi_close, + .ndo_start_xmit = cfhsi_xmit +}; + +static void cfhsi_setup(struct net_device *dev) +{ + struct cfhsi *cfhsi = netdev_priv(dev); + dev->features = 0; + dev->netdev_ops = &cfhsi_ops; + dev->type = ARPHRD_CAIF; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + dev->mtu = CFHSI_MAX_PAYLOAD_SZ; + dev->tx_queue_len = 0; + dev->destructor = free_netdev; + skb_queue_head_init(&cfhsi->qhead); + cfhsi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; + cfhsi->cfdev.use_frag = false; + cfhsi->cfdev.use_stx = false; + cfhsi->cfdev.use_fcs = false; + cfhsi->ndev = dev; +} + +int cfhsi_probe(struct platform_device *pdev) +{ + struct cfhsi *cfhsi = NULL; + struct net_device *ndev; + struct cfhsi_dev *dev; + int res; + + ndev = alloc_netdev(sizeof(struct cfhsi), "cfhsi%d", cfhsi_setup); + if (!ndev) { + dev_err(&pdev->dev, "%s: alloc_netdev failed.\n", + __func__); + return -ENODEV; + } + + cfhsi = netdev_priv(ndev); + cfhsi->ndev = ndev; + cfhsi->pdev = pdev; + + /* Initialize state vaiables. */ + cfhsi->tx_state = CFHSI_TX_STATE_IDLE; + cfhsi->rx_state = CFHSI_RX_STATE_DESC; + + /* Set flow info */ + cfhsi->flow_off_sent = 0; + cfhsi->q_low_mark = LOW_WATER_MARK; + cfhsi->q_high_mark = HIGH_WATER_MARK; + + /* Assign the HSI device. */ + dev = (struct cfhsi_dev *)pdev->dev.platform_data; + cfhsi->dev = dev; + + /* Assign the driver to this HSI device. */ + dev->drv = &cfhsi->drv; + + /* + * Allocate a TX buffer with the size of a HSI packet descriptors + * and the necessary room for CAIF payload frames. + */ + cfhsi->tx_buf = kzalloc(CFHSI_BUF_SZ_TX, GFP_KERNEL); + if (!cfhsi->tx_buf) { + dev_err(&ndev->dev, "%s: Failed to allocate TX buffer.\n", + __func__); + res = -ENODEV; + goto err_alloc_tx; + } + + /* + * Allocate a RX buffer with the size of two HSI packet descriptors and + * the necessary room for CAIF payload frames. + */ + cfhsi->rx_buf = kzalloc(CFHSI_BUF_SZ_RX, GFP_KERNEL); + if (!cfhsi->rx_buf) { + dev_err(&ndev->dev, "%s: Failed to allocate RX buffer.\n", + __func__); + res = -ENODEV; + goto err_alloc_rx; + } + + /* Initialize recieve vaiables. */ + cfhsi->rx_ptr = cfhsi->rx_buf; + cfhsi->rx_len = CFHSI_DESC_SZ; + + /* Initialize spin locks. */ + spin_lock_init(&cfhsi->lock); + + /* Set up the driver. */ + cfhsi->drv.tx_done_cb = cfhsi_tx_done_cb; + cfhsi->drv.rx_done_cb = cfhsi_rx_done_cb; + + /* Initialize the work queues. */ + INIT_WORK(&cfhsi->wake_up_work, cfhsi_wake_up); + INIT_WORK(&cfhsi->wake_down_work, cfhsi_wake_down); + INIT_WORK(&cfhsi->rx_done_work, cfhsi_rx_done_work); + INIT_WORK(&cfhsi->tx_done_work, cfhsi_tx_done_work); + + /* Clear all bit fields. */ + clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits); + clear_bit(CFHSI_WAKE_DOWN_ACK, &cfhsi->bits); + clear_bit(CFHSI_WAKE_UP, &cfhsi->bits); + clear_bit(CFHSI_AWAKE, &cfhsi->bits); + clear_bit(CFHSI_PENDING_RX, &cfhsi->bits); + + /* Create work thread. */ + cfhsi->wq = create_singlethread_workqueue(pdev->name); + if (!cfhsi->wq) { + dev_err(&ndev->dev, "%s: Failed to create work queue.\n", + __func__); + res = -ENODEV; + goto err_create_wq; + } + + /* Initialize wait queues. */ + init_waitqueue_head(&cfhsi->wake_up_wait); + init_waitqueue_head(&cfhsi->wake_down_wait); + init_waitqueue_head(&cfhsi->flush_fifo_wait); + + /* Setup the inactivity timer. */ + init_timer(&cfhsi->timer); + cfhsi->timer.data = (unsigned long)cfhsi; + cfhsi->timer.function = cfhsi_inactivity_tout; + + /* Add CAIF HSI device to list. */ + spin_lock(&cfhsi_list_lock); + list_add_tail(&cfhsi->list, &cfhsi_list); + spin_unlock(&cfhsi_list_lock); + + /* Activate HSI interface. */ + res = cfhsi->dev->cfhsi_up(cfhsi->dev); + if (res) { + dev_err(&cfhsi->ndev->dev, + "%s: can't activate HSI interface: %d.\n", + __func__, res); + goto err_activate; + } + + /* Flush FIFO */ + res = cfhsi_flush_fifo(cfhsi); + if (res) { + dev_err(&ndev->dev, "%s: Can't flush FIFO: %d.\n", + __func__, res); + goto err_net_reg; + } + + cfhsi->drv.wake_up_cb = cfhsi_wake_up_cb; + cfhsi->drv.wake_down_cb = cfhsi_wake_down_cb; + + /* Register network device. */ + res = register_netdev(ndev); + if (res) { + dev_err(&ndev->dev, "%s: Registration error: %d.\n", + __func__, res); + goto err_net_reg; + } + + netif_stop_queue(ndev); + + return res; + + err_net_reg: + cfhsi->dev->cfhsi_down(cfhsi->dev); + err_activate: + destroy_workqueue(cfhsi->wq); + err_create_wq: + kfree(cfhsi->rx_buf); + err_alloc_rx: + kfree(cfhsi->tx_buf); + err_alloc_tx: + free_netdev(ndev); + + return res; +} + +static void cfhsi_shutdown(struct cfhsi *cfhsi, bool remove_platform_dev) +{ + u8 *tx_buf, *rx_buf; + + /* Stop TXing */ + netif_tx_stop_all_queues(cfhsi->ndev); + + /* going to shutdown driver */ + set_bit(CFHSI_SHUTDOWN, &cfhsi->bits); + + if (remove_platform_dev) { + /* Flush workqueue */ + flush_workqueue(cfhsi->wq); + + /* Notify device. */ + platform_device_unregister(cfhsi->pdev); + } + + /* Flush workqueue */ + flush_workqueue(cfhsi->wq); + + /* Delete timer if pending */ +#ifdef CONFIG_SMP + del_timer_sync(&cfhsi->timer); +#else + del_timer(&cfhsi->timer); +#endif /* CONFIG_SMP */ + + /* Cancel pending RX request (if any) */ + cfhsi->dev->cfhsi_rx_cancel(cfhsi->dev); + + /* Flush again and destroy workqueue */ + destroy_workqueue(cfhsi->wq); + + /* Store bufferes: will be freed later. */ + tx_buf = cfhsi->tx_buf; + rx_buf = cfhsi->rx_buf; + + /* Flush transmit queues. */ + cfhsi_abort_tx(cfhsi); + + /* Deactivate interface */ + cfhsi->dev->cfhsi_down(cfhsi->dev); + + /* Finally unregister the network device. */ + unregister_netdev(cfhsi->ndev); + + /* Free buffers. */ + kfree(tx_buf); + kfree(rx_buf); +} + +int cfhsi_remove(struct platform_device *pdev) +{ + struct list_head *list_node; + struct list_head *n; + struct cfhsi *cfhsi = NULL; + struct cfhsi_dev *dev; + + dev = (struct cfhsi_dev *)pdev->dev.platform_data; + spin_lock(&cfhsi_list_lock); + list_for_each_safe(list_node, n, &cfhsi_list) { + cfhsi = list_entry(list_node, struct cfhsi, list); + /* Find the corresponding device. */ + if (cfhsi->dev == dev) { + /* Remove from list. */ + list_del(list_node); + spin_unlock(&cfhsi_list_lock); + + /* Shutdown driver. */ + cfhsi_shutdown(cfhsi, false); + + return 0; + } + } + spin_unlock(&cfhsi_list_lock); + return -ENODEV; +} + +struct platform_driver cfhsi_plat_drv = { + .probe = cfhsi_probe, + .remove = cfhsi_remove, + .driver = { + .name = "cfhsi", + .owner = THIS_MODULE, + }, +}; + +static void __exit cfhsi_exit_module(void) +{ + struct list_head *list_node; + struct list_head *n; + struct cfhsi *cfhsi = NULL; + + spin_lock(&cfhsi_list_lock); + list_for_each_safe(list_node, n, &cfhsi_list) { + cfhsi = list_entry(list_node, struct cfhsi, list); + + /* Remove from list. */ + list_del(list_node); + spin_unlock(&cfhsi_list_lock); + + /* Shutdown driver. */ + cfhsi_shutdown(cfhsi, true); + + spin_lock(&cfhsi_list_lock); + } + spin_unlock(&cfhsi_list_lock); + + /* Unregister platform driver. */ + platform_driver_unregister(&cfhsi_plat_drv); +} + +static int __init cfhsi_init_module(void) +{ + int result; + + /* Initialize spin lock. */ + spin_lock_init(&cfhsi_list_lock); + + /* Register platform driver. */ + result = platform_driver_register(&cfhsi_plat_drv); + if (result) { + printk(KERN_ERR "Could not register platform HSI driver: %d.\n", + result); + goto err_dev_register; + } + + return result; + + err_dev_register: + return result; +} + +module_init(cfhsi_init_module); +module_exit(cfhsi_exit_module); diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h new file mode 100644 index 00000000000..c5dedd87b4c --- /dev/null +++ b/include/net/caif/caif_hsi.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com + * Author: Daniel Martensson / daniel.martensson@stericsson.com + * Dmitry.Tarnyagin / dmitry.tarnyagin@stericsson.com + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CAIF_HSI_H_ +#define CAIF_HSI_H_ + +#include +#include +#include + +/* + * Maximum number of CAIF frames that can reside in the same HSI frame. + */ +#define CFHSI_MAX_PKTS 15 + +/* + * Maximum number of bytes used for the frame that can be embedded in the + * HSI descriptor. + */ +#define CFHSI_MAX_EMB_FRM_SZ 96 + +/* + * Decides if HSI buffers should be prefilled with 0xFF pattern for easier + * debugging. Both TX and RX buffers will be filled before the transfer. + */ +#define CFHSI_DBG_PREFILL 0 + +/* Structure describing a HSI packet descriptor. */ +#pragma pack(1) /* Byte alignment. */ +struct cfhsi_desc { + u8 header; + u8 offset; + u16 cffrm_len[CFHSI_MAX_PKTS]; + u8 emb_frm[CFHSI_MAX_EMB_FRM_SZ]; +}; +#pragma pack() /* Default alignment. */ + +/* Size of the complete HSI packet descriptor. */ +#define CFHSI_DESC_SZ (sizeof(struct cfhsi_desc)) + +/* + * Size of the complete HSI packet descriptor excluding the optional embedded + * CAIF frame. + */ +#define CFHSI_DESC_SHORT_SZ (CFHSI_DESC_SZ - CFHSI_MAX_EMB_FRM_SZ) + +/* + * Maximum bytes transferred in one transfer. + */ +/* TODO: 4096 is temporary... */ +#define CFHSI_MAX_PAYLOAD_SZ (CFHSI_MAX_PKTS * 4096) + +/* Size of the complete HSI TX buffer. */ +#define CFHSI_BUF_SZ_TX (CFHSI_DESC_SZ + CFHSI_MAX_PAYLOAD_SZ) + +/* Size of the complete HSI RX buffer. */ +#define CFHSI_BUF_SZ_RX ((2 * CFHSI_DESC_SZ) + CFHSI_MAX_PAYLOAD_SZ) + +/* Bitmasks for the HSI descriptor. */ +#define CFHSI_PIGGY_DESC (0x01 << 7) + +#define CFHSI_TX_STATE_IDLE 0 +#define CFHSI_TX_STATE_XFER 1 + +#define CFHSI_RX_STATE_DESC 0 +#define CFHSI_RX_STATE_PAYLOAD 1 + +/* Bitmasks for power management. */ +#define CFHSI_WAKE_UP 0 +#define CFHSI_WAKE_UP_ACK 1 +#define CFHSI_WAKE_DOWN_ACK 2 +#define CFHSI_AWAKE 3 +#define CFHSI_PENDING_RX 4 +#define CFHSI_SHUTDOWN 6 +#define CFHSI_FLUSH_FIFO 7 + +#ifndef CFHSI_INACTIVITY_TOUT +#define CFHSI_INACTIVITY_TOUT (1 * HZ) +#endif /* CFHSI_INACTIVITY_TOUT */ + +#ifndef CFHSI_WAKEUP_TOUT +#define CFHSI_WAKEUP_TOUT (3 * HZ) +#endif /* CFHSI_WAKEUP_TOUT */ + + +/* Structure implemented by the CAIF HSI driver. */ +struct cfhsi_drv { + void (*tx_done_cb) (struct cfhsi_drv *drv); + void (*rx_done_cb) (struct cfhsi_drv *drv); + void (*wake_up_cb) (struct cfhsi_drv *drv); + void (*wake_down_cb) (struct cfhsi_drv *drv); +}; + +/* Structure implemented by HSI device. */ +struct cfhsi_dev { + int (*cfhsi_up) (struct cfhsi_dev *dev); + int (*cfhsi_down) (struct cfhsi_dev *dev); + int (*cfhsi_tx) (u8 *ptr, int len, struct cfhsi_dev *dev); + int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_dev *dev); + int (*cfhsi_wake_up) (struct cfhsi_dev *dev); + int (*cfhsi_wake_down) (struct cfhsi_dev *dev); + int (*cfhsi_fifo_occupancy)(struct cfhsi_dev *dev, size_t *occupancy); + int (*cfhsi_rx_cancel)(struct cfhsi_dev *dev); + struct cfhsi_drv *drv; +}; + +/* Structure implemented by CAIF HSI drivers. */ +struct cfhsi { + struct caif_dev_common cfdev; + struct net_device *ndev; + struct platform_device *pdev; + struct sk_buff_head qhead; + struct cfhsi_drv drv; + struct cfhsi_dev *dev; + int tx_state; + int rx_state; + int rx_len; + u8 *rx_ptr; + u8 *tx_buf; + u8 *rx_buf; + spinlock_t lock; + int flow_off_sent; + u32 q_low_mark; + u32 q_high_mark; + struct list_head list; + struct work_struct wake_up_work; + struct work_struct wake_down_work; + struct work_struct rx_done_work; + struct work_struct tx_done_work; + struct workqueue_struct *wq; + wait_queue_head_t wake_up_wait; + wait_queue_head_t wake_down_wait; + wait_queue_head_t flush_fifo_wait; + struct timer_list timer; + unsigned long bits; +}; + +extern struct platform_driver cfhsi_driver; + +#endif /* CAIF_HSI_H_ */ -- cgit v1.2.3-70-g09d2 From f35490f909b7d535ff7f2f1a7df59be8c2824931 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 2 Jun 2011 19:38:43 +0200 Subject: iwlagn: fix interface combinations My patch to advertise interface combinations worked by pure luck in the P2P case, but all other cases are broken. This is due to a dumb mistake in the code that checks what should be advertised, fix that. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5d2bd88101f..6ad33765637 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2533,11 +2533,11 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); - if (hw->wiphy->interface_modes & NL80211_IFTYPE_P2P_CLIENT) { + if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) { hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p; hw->wiphy->n_iface_combinations = ARRAY_SIZE(iwlagn_iface_combinations_p2p); - } else if (hw->wiphy->interface_modes & NL80211_IFTYPE_AP) { + } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { hw->wiphy->iface_combinations = iwlagn_iface_combinations_dualmode; hw->wiphy->n_iface_combinations = ARRAY_SIZE(iwlagn_iface_combinations_dualmode); -- cgit v1.2.3-70-g09d2 From 6f92c66f7190b1677ea666249b72298723392115 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 1 Jun 2011 10:36:33 +0000 Subject: bonding: allow all slave speeds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to check for 10, 100, 1000, 10000 explicitly. Just make this generic and check for invalid values only (similar check is in ethtool userspace app). This enables correct speed handling for slave devices with "nonstandard" speeds. Signed-off-by: Jiri Pirko Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 17b4dd94da9..716c852a696 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -629,15 +629,8 @@ static int bond_update_speed_duplex(struct slave *slave) return -1; slave_speed = ethtool_cmd_speed(&etool); - switch (slave_speed) { - case SPEED_10: - case SPEED_100: - case SPEED_1000: - case SPEED_10000: - break; - default: + if (slave_speed == 0 || slave_speed == ((__u32) -1)) return -1; - } switch (etool.duplex) { case DUPLEX_FULL: -- cgit v1.2.3-70-g09d2 From fe09bb619096a0aa139210748ddc668c2dbe2308 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 1 Jun 2011 17:17:10 +1000 Subject: sungem: Spring cleaning and GRO support This patch simplifies the logic and locking in sungem significantly: - LLTX is gone, all private locks are gone, mutex is gone - We don't poll the PHY while the interface is down - The above allowed me to get rid of a pile of state flags using the proper interface state provided by the networking stack when needed and overall simplify the driver a lot - Allocate the bulk of RX skbs at init time using GFP_KERNEL - Fix a bug where the dev->features were set after register_netdev() - Added GRO while at it Signed-off-by: Benjamin Herrenschmidt Signed-off-by: David S. Miller --- drivers/net/sungem.c | 889 +++++++++++++++++++++------------------------------ drivers/net/sungem.h | 25 -- 2 files changed, 373 insertions(+), 541 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index ab593009926..f0bcbe4bce4 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -10,25 +10,6 @@ * NAPI and NETPOLL support * (C) 2004 by Eric Lemoine (eric.lemoine@gmail.com) * - * TODO: - * - Now that the driver was significantly simplified, I need to rework - * the locking. I'm sure we don't need _2_ spinlocks, and we probably - * can avoid taking most of them for so long period of time (and schedule - * instead). The main issues at this point are caused by the netdev layer - * though: - * - * gem_change_mtu() and gem_set_multicast() are called with a read_lock() - * help by net/core/dev.c, thus they can't schedule. That means they can't - * call napi_disable() neither, thus force gem_poll() to keep a spinlock - * where it could have been dropped. change_mtu especially would love also to - * be able to msleep instead of horrid locked delays when resetting the HW, - * but that read_lock() makes it impossible, unless I defer it's action to - * the reset task, which means it'll be asynchronous (won't take effect until - * the system schedules a bit). - * - * Also, it would probably be possible to also remove most of the long-life - * locking in open/resume code path (gem_reinit_chip) by beeing more careful - * about when we can start taking interrupts or get xmit() called... */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -57,7 +38,6 @@ #include #include #include -#include #include #include @@ -95,12 +75,11 @@ SUPPORTED_Pause | SUPPORTED_Autoneg) #define DRV_NAME "sungem" -#define DRV_VERSION "0.98" -#define DRV_RELDATE "8/24/03" -#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" +#define DRV_VERSION "1.0" +#define DRV_AUTHOR "David S. Miller " static char version[] __devinitdata = - DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; + DRV_NAME ".c:v" DRV_VERSION " " DRV_AUTHOR "\n"; MODULE_AUTHOR(DRV_AUTHOR); MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver"); @@ -218,6 +197,7 @@ static inline void gem_disable_ints(struct gem *gp) { /* Disable all interrupts, including TXDONE */ writel(GREG_STAT_NAPI | GREG_STAT_TXDONE, gp->regs + GREG_IMASK); + (void)readl(gp->regs + GREG_IMASK); /* write posting */ } static void gem_get_cell(struct gem *gp) @@ -247,6 +227,29 @@ static void gem_put_cell(struct gem *gp) #endif /* CONFIG_PPC_PMAC */ } +static inline void gem_netif_stop(struct gem *gp) +{ + gp->dev->trans_start = jiffies; /* prevent tx timeout */ + napi_disable(&gp->napi); + netif_tx_disable(gp->dev); +} + +static inline void gem_netif_start(struct gem *gp) +{ + /* NOTE: unconditional netif_wake_queue is only + * appropriate so long as all callers are assured to + * have free tx slots. + */ + netif_wake_queue(gp->dev); + napi_enable(&gp->napi); +} + +static void gem_schedule_reset(struct gem *gp) +{ + gp->reset_task_pending = 1; + schedule_work(&gp->reset_task); +} + static void gem_handle_mif_event(struct gem *gp, u32 reg_val, u32 changed_bits) { if (netif_msg_intr(gp)) @@ -604,56 +607,46 @@ static int gem_abnormal_irq(struct net_device *dev, struct gem *gp, u32 gem_stat gp->dev->name); dev->stats.rx_errors++; - goto do_reset; + return 1; } if (gem_status & GREG_STAT_PCS) { if (gem_pcs_interrupt(dev, gp, gem_status)) - goto do_reset; + return 1; } if (gem_status & GREG_STAT_TXMAC) { if (gem_txmac_interrupt(dev, gp, gem_status)) - goto do_reset; + return 1; } if (gem_status & GREG_STAT_RXMAC) { if (gem_rxmac_interrupt(dev, gp, gem_status)) - goto do_reset; + return 1; } if (gem_status & GREG_STAT_MAC) { if (gem_mac_interrupt(dev, gp, gem_status)) - goto do_reset; + return 1; } if (gem_status & GREG_STAT_MIF) { if (gem_mif_interrupt(dev, gp, gem_status)) - goto do_reset; + return 1; } if (gem_status & GREG_STAT_PCIERR) { if (gem_pci_interrupt(dev, gp, gem_status)) - goto do_reset; + return 1; } return 0; - -do_reset: - gp->reset_task_pending = 1; - schedule_work(&gp->reset_task); - - return 1; } static __inline__ void gem_tx(struct net_device *dev, struct gem *gp, u32 gem_status) { int entry, limit; - if (netif_msg_intr(gp)) - printk(KERN_DEBUG "%s: tx interrupt, gem_status: 0x%x\n", - gp->dev->name, gem_status); - entry = gp->tx_old; limit = ((gem_status & GREG_STAT_TXNR) >> GREG_STAT_TXNR_SHIFT); while (entry != limit) { @@ -697,13 +690,27 @@ static __inline__ void gem_tx(struct net_device *dev, struct gem *gp, u32 gem_st } dev->stats.tx_packets++; - dev_kfree_skb_irq(skb); + dev_kfree_skb(skb); } gp->tx_old = entry; - if (netif_queue_stopped(dev) && - TX_BUFFS_AVAIL(gp) > (MAX_SKB_FRAGS + 1)) - netif_wake_queue(dev); + /* Need to make the tx_old update visible to gem_start_xmit() + * before checking for netif_queue_stopped(). Without the + * memory barrier, there is a small possibility that gem_start_xmit() + * will miss it and cause the queue to be stopped forever. + */ + smp_mb(); + + if (unlikely(netif_queue_stopped(dev) && + TX_BUFFS_AVAIL(gp) > (MAX_SKB_FRAGS + 1))) { + struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + + __netif_tx_lock(txq, smp_processor_id()); + if (netif_queue_stopped(dev) && + TX_BUFFS_AVAIL(gp) > (MAX_SKB_FRAGS + 1)) + netif_wake_queue(dev); + __netif_tx_unlock(txq); + } } static __inline__ void gem_post_rxds(struct gem *gp, int limit) @@ -736,6 +743,21 @@ static __inline__ void gem_post_rxds(struct gem *gp, int limit) } } +#define ALIGNED_RX_SKB_ADDR(addr) \ + ((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr)) +static __inline__ struct sk_buff *gem_alloc_skb(struct net_device *dev, int size, + gfp_t gfp_flags) +{ + struct sk_buff *skb = alloc_skb(size + 64, gfp_flags); + + if (likely(skb)) { + unsigned long offset = ALIGNED_RX_SKB_ADDR(skb->data); + skb_reserve(skb, offset); + skb->dev = dev; + } + return skb; +} + static int gem_rx(struct gem *gp, int work_to_do) { struct net_device *dev = gp->dev; @@ -799,7 +821,7 @@ static int gem_rx(struct gem *gp, int work_to_do) if (len > RX_COPY_THRESHOLD) { struct sk_buff *new_skb; - new_skb = gem_alloc_skb(RX_BUF_ALLOC_SIZE(gp), GFP_ATOMIC); + new_skb = gem_alloc_skb(dev, RX_BUF_ALLOC_SIZE(gp), GFP_ATOMIC); if (new_skb == NULL) { drops++; goto drop_it; @@ -808,7 +830,6 @@ static int gem_rx(struct gem *gp, int work_to_do) RX_BUF_ALLOC_SIZE(gp), PCI_DMA_FROMDEVICE); gp->rx_skbs[entry] = new_skb; - new_skb->dev = gp->dev; skb_put(new_skb, (gp->rx_buf_sz + RX_OFFSET)); rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev, virt_to_page(new_skb->data), @@ -820,7 +841,7 @@ static int gem_rx(struct gem *gp, int work_to_do) /* Trim the original skb for the netif. */ skb_trim(skb, len); } else { - struct sk_buff *copy_skb = dev_alloc_skb(len + 2); + struct sk_buff *copy_skb = netdev_alloc_skb(dev, len + 2); if (copy_skb == NULL) { drops++; @@ -842,7 +863,7 @@ static int gem_rx(struct gem *gp, int work_to_do) skb->ip_summed = CHECKSUM_COMPLETE; skb->protocol = eth_type_trans(skb, gp->dev); - netif_receive_skb(skb); + napi_gro_receive(&gp->napi, skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; @@ -865,28 +886,32 @@ static int gem_poll(struct napi_struct *napi, int budget) { struct gem *gp = container_of(napi, struct gem, napi); struct net_device *dev = gp->dev; - unsigned long flags; int work_done; - /* - * NAPI locking nightmare: See comment at head of driver - */ - spin_lock_irqsave(&gp->lock, flags); - work_done = 0; do { /* Handle anomalies */ - if (gp->status & GREG_STAT_ABNORMAL) { - if (gem_abnormal_irq(dev, gp, gp->status)) - break; + if (unlikely(gp->status & GREG_STAT_ABNORMAL)) { + struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + int reset; + + /* We run the abnormal interrupt handling code with + * the Tx lock. It only resets the Rx portion of the + * chip, but we need to guard it against DMA being + * restarted by the link poll timer + */ + __netif_tx_lock(txq, smp_processor_id()); + reset = gem_abnormal_irq(dev, gp, gp->status); + __netif_tx_unlock(txq); + if (reset) { + gem_schedule_reset(gp); + napi_complete(napi); + return work_done; + } } /* Run TX completion thread */ - spin_lock(&gp->tx_lock); gem_tx(dev, gp, gp->status); - spin_unlock(&gp->tx_lock); - - spin_unlock_irqrestore(&gp->lock, flags); /* Run RX thread. We don't use any locking here, * code willing to do bad things - like cleaning the @@ -898,16 +923,12 @@ static int gem_poll(struct napi_struct *napi, int budget) if (work_done >= budget) return work_done; - spin_lock_irqsave(&gp->lock, flags); - gp->status = readl(gp->regs + GREG_STAT); } while (gp->status & GREG_STAT_NAPI); - __napi_complete(napi); + napi_complete(napi); gem_enable_ints(gp); - spin_unlock_irqrestore(&gp->lock, flags); - return work_done; } @@ -915,32 +936,23 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct gem *gp = netdev_priv(dev); - unsigned long flags; - - /* Swallow interrupts when shutting the chip down, though - * that shouldn't happen, we should have done free_irq() at - * this point... - */ - if (!gp->running) - return IRQ_HANDLED; - - spin_lock_irqsave(&gp->lock, flags); if (napi_schedule_prep(&gp->napi)) { u32 gem_status = readl(gp->regs + GREG_STAT); - if (gem_status == 0) { + if (unlikely(gem_status == 0)) { napi_enable(&gp->napi); - spin_unlock_irqrestore(&gp->lock, flags); return IRQ_NONE; } + if (netif_msg_intr(gp)) + printk(KERN_DEBUG "%s: gem_interrupt() gem_status: 0x%x\n", + gp->dev->name, gem_status); + gp->status = gem_status; gem_disable_ints(gp); __napi_schedule(&gp->napi); } - spin_unlock_irqrestore(&gp->lock, flags); - /* If polling was disabled at the time we received that * interrupt, we may return IRQ_HANDLED here while we * should return IRQ_NONE. No big deal... @@ -951,10 +963,11 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id) #ifdef CONFIG_NET_POLL_CONTROLLER static void gem_poll_controller(struct net_device *dev) { - /* gem_interrupt is safe to reentrance so no need - * to disable_irq here. - */ - gem_interrupt(dev->irq, dev); + struct gem *gp = netdev_priv(dev); + + disable_irq(gp->pdev->irq); + gem_interrupt(gp->pdev->irq, dev); + enable_irq(gp->pdev->irq); } #endif @@ -963,10 +976,7 @@ static void gem_tx_timeout(struct net_device *dev) struct gem *gp = netdev_priv(dev); netdev_err(dev, "transmit timed out, resetting\n"); - if (!gp->running) { - netdev_err(dev, "hrm.. hw not running !\n"); - return; - } + netdev_err(dev, "TX_STATE[%08x:%08x:%08x]\n", readl(gp->regs + TXDMA_CFG), readl(gp->regs + MAC_TXSTAT), @@ -976,14 +986,7 @@ static void gem_tx_timeout(struct net_device *dev) readl(gp->regs + MAC_RXSTAT), readl(gp->regs + MAC_RXCFG)); - spin_lock_irq(&gp->lock); - spin_lock(&gp->tx_lock); - - gp->reset_task_pending = 1; - schedule_work(&gp->reset_task); - - spin_unlock(&gp->tx_lock); - spin_unlock_irq(&gp->lock); + gem_schedule_reset(gp); } static __inline__ int gem_intme(int entry) @@ -1001,7 +1004,6 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, struct gem *gp = netdev_priv(dev); int entry; u64 ctrl; - unsigned long flags; ctrl = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) { @@ -1013,21 +1015,12 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, (csum_stuff_off << 21)); } - if (!spin_trylock_irqsave(&gp->tx_lock, flags)) { - /* Tell upper layer to requeue */ - return NETDEV_TX_LOCKED; - } - /* We raced with gem_do_stop() */ - if (!gp->running) { - spin_unlock_irqrestore(&gp->tx_lock, flags); - return NETDEV_TX_BUSY; - } - - /* This is a hard error, log it. */ - if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) { - netif_stop_queue(dev); - spin_unlock_irqrestore(&gp->tx_lock, flags); - netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); + if (unlikely(TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1))) { + /* This is a hard error, log it. */ + if (!netif_queue_stopped(dev)) { + netif_stop_queue(dev); + netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); + } return NETDEV_TX_BUSY; } @@ -1104,17 +1097,23 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, } gp->tx_new = entry; - if (TX_BUFFS_AVAIL(gp) <= (MAX_SKB_FRAGS + 1)) + if (unlikely(TX_BUFFS_AVAIL(gp) <= (MAX_SKB_FRAGS + 1))) { netif_stop_queue(dev); + /* netif_stop_queue() must be done before checking + * checking tx index in TX_BUFFS_AVAIL() below, because + * in gem_tx(), we update tx_old before checking for + * netif_queue_stopped(). + */ + smp_mb(); + if (TX_BUFFS_AVAIL(gp) > (MAX_SKB_FRAGS + 1)) + netif_wake_queue(dev); + } if (netif_msg_tx_queued(gp)) printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n", dev->name, entry, skb->len); mb(); writel(gp->tx_new, gp->regs + TXDMA_KICK); - spin_unlock_irqrestore(&gp->tx_lock, flags); - - dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ return NETDEV_TX_OK; } @@ -1184,7 +1183,6 @@ static void gem_pcs_reinit_adv(struct gem *gp) #define STOP_TRIES 32 -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_reset(struct gem *gp) { int limit; @@ -1213,7 +1211,6 @@ static void gem_reset(struct gem *gp) gem_pcs_reinit_adv(gp); } -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_start_dma(struct gem *gp) { u32 val; @@ -1236,8 +1233,7 @@ static void gem_start_dma(struct gem *gp) writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK); } -/* Must be invoked under gp->lock and gp->tx_lock. DMA won't be - * actually stopped before about 4ms tho ... +/* DMA won't be actually stopped before about 4ms tho ... */ static void gem_stop_dma(struct gem *gp) { @@ -1259,7 +1255,6 @@ static void gem_stop_dma(struct gem *gp) } -/* Must be invoked under gp->lock and gp->tx_lock. */ // XXX dbl check what that function should do when called on PCS PHY static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep) { @@ -1319,7 +1314,7 @@ start_aneg: /* If we are asleep, we don't try to actually setup the PHY, we * just store the settings */ - if (gp->asleep) { + if (!netif_device_present(gp->dev)) { gp->phy_mii.autoneg = gp->want_autoneg = autoneg; gp->phy_mii.speed = speed; gp->phy_mii.duplex = duplex; @@ -1345,13 +1340,12 @@ non_mii: /* A link-up condition has occurred, initialize and enable the * rest of the chip. - * - * Must be invoked under gp->lock and gp->tx_lock. */ static int gem_set_link_modes(struct gem *gp) { - u32 val; + struct netdev_queue *txq = netdev_get_tx_queue(gp->dev, 0); int full_duplex, speed, pause; + u32 val; full_duplex = 0; speed = SPEED_10; @@ -1375,8 +1369,11 @@ static int gem_set_link_modes(struct gem *gp) netif_info(gp, link, gp->dev, "Link is up at %d Mbps, %s-duplex\n", speed, (full_duplex ? "full" : "half")); - if (!gp->running) - return 0; + + /* We take the tx queue lock to avoid collisions between + * this code, the tx path and the NAPI-driven error path + */ + __netif_tx_lock(txq, smp_processor_id()); val = (MAC_TXCFG_EIPG0 | MAC_TXCFG_NGU); if (full_duplex) { @@ -1425,18 +1422,6 @@ static int gem_set_link_modes(struct gem *gp) pause = 1; } - if (netif_msg_link(gp)) { - if (pause) { - netdev_info(gp->dev, - "Pause is enabled (rxfifo: %d off: %d on: %d)\n", - gp->rx_fifo_sz, - gp->rx_pause_off, - gp->rx_pause_on); - } else { - netdev_info(gp->dev, "Pause is disabled\n"); - } - } - if (!full_duplex) writel(512, gp->regs + MAC_STIME); else @@ -1450,10 +1435,23 @@ static int gem_set_link_modes(struct gem *gp) gem_start_dma(gp); + __netif_tx_unlock(txq); + + if (netif_msg_link(gp)) { + if (pause) { + netdev_info(gp->dev, + "Pause is enabled (rxfifo: %d off: %d on: %d)\n", + gp->rx_fifo_sz, + gp->rx_pause_off, + gp->rx_pause_on); + } else { + netdev_info(gp->dev, "Pause is disabled\n"); + } + } + return 0; } -/* Must be invoked under gp->lock and gp->tx_lock. */ static int gem_mdio_link_not_up(struct gem *gp) { switch (gp->lstate) { @@ -1501,20 +1499,12 @@ static int gem_mdio_link_not_up(struct gem *gp) static void gem_link_timer(unsigned long data) { struct gem *gp = (struct gem *) data; + struct net_device *dev = gp->dev; int restart_aneg = 0; - if (gp->asleep) - return; - - spin_lock_irq(&gp->lock); - spin_lock(&gp->tx_lock); - gem_get_cell(gp); - - /* If the reset task is still pending, we just - * reschedule the link timer - */ + /* There's no point doing anything if we're going to be reset */ if (gp->reset_task_pending) - goto restart; + return; if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes) { @@ -1528,7 +1518,7 @@ static void gem_link_timer(unsigned long data) goto restart; gp->lstate = link_up; - netif_carrier_on(gp->dev); + netif_carrier_on(dev); (void)gem_set_link_modes(gp); } goto restart; @@ -1544,12 +1534,12 @@ static void gem_link_timer(unsigned long data) gp->last_forced_speed = gp->phy_mii.speed; gp->timer_ticks = 5; if (netif_msg_link(gp)) - netdev_info(gp->dev, + netdev_info(dev, "Got link after fallback, retrying autoneg once...\n"); gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, gp->phy_mii.advertising); } else if (gp->lstate != link_up) { gp->lstate = link_up; - netif_carrier_on(gp->dev); + netif_carrier_on(dev); if (gem_set_link_modes(gp)) restart_aneg = 1; } @@ -1559,11 +1549,11 @@ static void gem_link_timer(unsigned long data) */ if (gp->lstate == link_up) { gp->lstate = link_down; - netif_info(gp, link, gp->dev, "Link down\n"); - netif_carrier_off(gp->dev); - gp->reset_task_pending = 1; - schedule_work(&gp->reset_task); - restart_aneg = 1; + netif_info(gp, link, dev, "Link down\n"); + netif_carrier_off(dev); + gem_schedule_reset(gp); + /* The reset task will restart the timer */ + return; } else if (++gp->timer_ticks > 10) { if (found_mii_phy(gp)) restart_aneg = gem_mdio_link_not_up(gp); @@ -1573,17 +1563,12 @@ static void gem_link_timer(unsigned long data) } if (restart_aneg) { gem_begin_auto_negotiation(gp, NULL); - goto out_unlock; + return; } restart: mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10)); -out_unlock: - gem_put_cell(gp); - spin_unlock(&gp->tx_lock); - spin_unlock_irq(&gp->lock); } -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_clean_rings(struct gem *gp) { struct gem_init_block *gb = gp->init_block; @@ -1634,7 +1619,6 @@ static void gem_clean_rings(struct gem *gp) } } -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_init_rings(struct gem *gp) { struct gem_init_block *gb = gp->init_block; @@ -1653,7 +1637,7 @@ static void gem_init_rings(struct gem *gp) struct sk_buff *skb; struct gem_rxd *rxd = &gb->rxd[i]; - skb = gem_alloc_skb(RX_BUF_ALLOC_SIZE(gp), GFP_ATOMIC); + skb = gem_alloc_skb(dev, RX_BUF_ALLOC_SIZE(gp), GFP_KERNEL); if (!skb) { rxd->buffer = 0; rxd->status_word = 0; @@ -1661,7 +1645,6 @@ static void gem_init_rings(struct gem *gp) } gp->rx_skbs[i] = skb; - skb->dev = dev; skb_put(skb, (gp->rx_buf_sz + RX_OFFSET)); dma_addr = pci_map_page(gp->pdev, virt_to_page(skb->data), @@ -1737,7 +1720,7 @@ static void gem_init_phy(struct gem *gp) if (gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) { - // XXX check for errors + /* Reset and detect MII PHY */ mii_phy_probe(&gp->phy_mii, gp->mii_phy_addr); /* Init PHY */ @@ -1753,13 +1736,15 @@ static void gem_init_phy(struct gem *gp) gp->lstate = link_down; netif_carrier_off(gp->dev); - /* Can I advertise gigabit here ? I'd need BCM PHY docs... */ - spin_lock_irq(&gp->lock); + /* Print things out */ + if (gp->phy_type == phy_mii_mdio0 || + gp->phy_type == phy_mii_mdio1) + netdev_info(gp->dev, "Found %s PHY\n", + gp->phy_mii.def ? gp->phy_mii.def->name : "no"); + gem_begin_auto_negotiation(gp, NULL); - spin_unlock_irq(&gp->lock); } -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_init_dma(struct gem *gp) { u64 desc_dma = (u64) gp->gblock_dvma; @@ -1797,7 +1782,6 @@ static void gem_init_dma(struct gem *gp) gp->regs + RXDMA_BLANK); } -/* Must be invoked under gp->lock and gp->tx_lock. */ static u32 gem_setup_multicast(struct gem *gp) { u32 rxcfg = 0; @@ -1835,7 +1819,6 @@ static u32 gem_setup_multicast(struct gem *gp) return rxcfg; } -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_init_mac(struct gem *gp) { unsigned char *e = &gp->dev->dev_addr[0]; @@ -1918,7 +1901,6 @@ static void gem_init_mac(struct gem *gp) writel(0, gp->regs + WOL_WAKECSR); } -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_init_pause_thresholds(struct gem *gp) { u32 cfg; @@ -2079,7 +2061,6 @@ static int gem_check_invariants(struct gem *gp) return 0; } -/* Must be invoked under gp->lock and gp->tx_lock. */ static void gem_reinit_chip(struct gem *gp) { /* Reset the chip */ @@ -2100,11 +2081,9 @@ static void gem_reinit_chip(struct gem *gp) } -/* Must be invoked with no lock held. */ static void gem_stop_phy(struct gem *gp, int wol) { u32 mifcfg; - unsigned long flags; /* Let the chip settle down a bit, it seems that helps * for sleep mode on some models @@ -2150,15 +2129,9 @@ static void gem_stop_phy(struct gem *gp, int wol) writel(0, gp->regs + RXDMA_CFG); if (!wol) { - spin_lock_irqsave(&gp->lock, flags); - spin_lock(&gp->tx_lock); gem_reset(gp); writel(MAC_TXRST_CMD, gp->regs + MAC_TXRST); writel(MAC_RXRST_CMD, gp->regs + MAC_RXRST); - spin_unlock(&gp->tx_lock); - spin_unlock_irqrestore(&gp->lock, flags); - - /* No need to take the lock here */ if (found_mii_phy(gp) && gp->phy_mii.def->ops->suspend) gp->phy_mii.def->ops->suspend(&gp->phy_mii); @@ -2175,54 +2148,55 @@ static void gem_stop_phy(struct gem *gp, int wol) } } - static int gem_do_start(struct net_device *dev) { struct gem *gp = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&gp->lock, flags); - spin_lock(&gp->tx_lock); + int rc; /* Enable the cell */ gem_get_cell(gp); - /* Init & setup chip hardware */ - gem_reinit_chip(gp); - - gp->running = 1; - - napi_enable(&gp->napi); + /* Make sure PCI access and bus master are enabled */ + rc = pci_enable_device(gp->pdev); + if (rc) { + netdev_err(dev, "Failed to enable chip on PCI bus !\n"); - if (gp->lstate == link_up) { - netif_carrier_on(gp->dev); - gem_set_link_modes(gp); + /* Put cell and forget it for now, it will be considered as + * still asleep, a new sleep cycle may bring it back + */ + gem_put_cell(gp); + return -ENXIO; } + pci_set_master(gp->pdev); - netif_wake_queue(gp->dev); - - spin_unlock(&gp->tx_lock); - spin_unlock_irqrestore(&gp->lock, flags); + /* Init & setup chip hardware */ + gem_reinit_chip(gp); - if (request_irq(gp->pdev->irq, gem_interrupt, - IRQF_SHARED, dev->name, (void *)dev)) { + /* An interrupt might come in handy */ + rc = request_irq(gp->pdev->irq, gem_interrupt, + IRQF_SHARED, dev->name, (void *)dev); + if (rc) { netdev_err(dev, "failed to request irq !\n"); - spin_lock_irqsave(&gp->lock, flags); - spin_lock(&gp->tx_lock); - - napi_disable(&gp->napi); - - gp->running = 0; gem_reset(gp); gem_clean_rings(gp); gem_put_cell(gp); + return rc; + } - spin_unlock(&gp->tx_lock); - spin_unlock_irqrestore(&gp->lock, flags); + /* Mark us as attached again if we come from resume(), this has + * no effect if we weren't detatched and needs to be done now. + */ + netif_device_attach(dev); - return -EAGAIN; - } + /* Restart NAPI & queues */ + gem_netif_start(gp); + + /* Detect & init PHY, start autoneg etc... this will + * eventually result in starting DMA operations when + * the link is up + */ + gem_init_phy(gp); return 0; } @@ -2230,22 +2204,30 @@ static int gem_do_start(struct net_device *dev) static void gem_do_stop(struct net_device *dev, int wol) { struct gem *gp = netdev_priv(dev); - unsigned long flags; - spin_lock_irqsave(&gp->lock, flags); - spin_lock(&gp->tx_lock); + /* Stop NAPI and stop tx queue */ + gem_netif_stop(gp); - gp->running = 0; - - /* Stop netif queue */ - netif_stop_queue(dev); - - /* Make sure ints are disabled */ + /* Make sure ints are disabled. We don't care about + * synchronizing as NAPI is disabled, thus a stray + * interrupt will do nothing bad (our irq handler + * just schedules NAPI) + */ gem_disable_ints(gp); - /* We can drop the lock now */ - spin_unlock(&gp->tx_lock); - spin_unlock_irqrestore(&gp->lock, flags); + /* Stop the link timer */ + del_timer_sync(&gp->link_timer); + + /* We cannot cancel the reset task while holding the + * rtnl lock, we'd get an A->B / B->A deadlock stituation + * if we did. This is not an issue however as the reset + * task is synchronized vs. us (rtnl_lock) and will do + * nothing if the device is down or suspended. We do + * still clear reset_task_pending to avoid a spurrious + * reset later on in case we do resume before it gets + * scheduled. + */ + gp->reset_task_pending = 0; /* If we are going to sleep with WOL */ gem_stop_dma(gp); @@ -2260,79 +2242,79 @@ static void gem_do_stop(struct net_device *dev, int wol) /* No irq needed anymore */ free_irq(gp->pdev->irq, (void *) dev); + /* Shut the PHY down eventually and setup WOL */ + gem_stop_phy(gp, wol); + + /* Make sure bus master is disabled */ + pci_disable_device(gp->pdev); + /* Cell not needed neither if no WOL */ - if (!wol) { - spin_lock_irqsave(&gp->lock, flags); + if (!wol) gem_put_cell(gp); - spin_unlock_irqrestore(&gp->lock, flags); - } } static void gem_reset_task(struct work_struct *work) { struct gem *gp = container_of(work, struct gem, reset_task); - mutex_lock(&gp->pm_mutex); + /* Lock out the network stack (essentially shield ourselves + * against a racing open, close, control call, or suspend + */ + rtnl_lock(); - if (gp->opened) - napi_disable(&gp->napi); + /* Skip the reset task if suspended or closed, or if it's + * been cancelled by gem_do_stop (see comment there) + */ + if (!netif_device_present(gp->dev) || + !netif_running(gp->dev) || + !gp->reset_task_pending) { + rtnl_unlock(); + return; + } - spin_lock_irq(&gp->lock); - spin_lock(&gp->tx_lock); + /* Stop the link timer */ + del_timer_sync(&gp->link_timer); - if (gp->running) { - netif_stop_queue(gp->dev); + /* Stop NAPI and tx */ + gem_netif_stop(gp); - /* Reset the chip & rings */ - gem_reinit_chip(gp); - if (gp->lstate == link_up) - gem_set_link_modes(gp); - netif_wake_queue(gp->dev); - } + /* Reset the chip & rings */ + gem_reinit_chip(gp); + if (gp->lstate == link_up) + gem_set_link_modes(gp); - gp->reset_task_pending = 0; + /* Restart NAPI and Tx */ + gem_netif_start(gp); - spin_unlock(&gp->tx_lock); - spin_unlock_irq(&gp->lock); + /* We are back ! */ + gp->reset_task_pending = 0; - if (gp->opened) - napi_enable(&gp->napi); + /* If the link is not up, restart autoneg, else restart the + * polling timer + */ + if (gp->lstate != link_up) + gem_begin_auto_negotiation(gp, NULL); + else + mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10)); - mutex_unlock(&gp->pm_mutex); + rtnl_unlock(); } - static int gem_open(struct net_device *dev) { - struct gem *gp = netdev_priv(dev); - int rc = 0; - - mutex_lock(&gp->pm_mutex); - - /* We need the cell enabled */ - if (!gp->asleep) - rc = gem_do_start(dev); - gp->opened = (rc == 0); - - mutex_unlock(&gp->pm_mutex); - - return rc; + /* We allow open while suspended, we just do nothing, + * the chip will be initialized in resume() + */ + if (netif_device_present(dev)) + return gem_do_start(dev); + return 0; } static int gem_close(struct net_device *dev) { - struct gem *gp = netdev_priv(dev); - - mutex_lock(&gp->pm_mutex); - - napi_disable(&gp->napi); - - gp->opened = 0; - if (!gp->asleep) + if (netif_device_present(dev)) gem_do_stop(dev, 0); - mutex_unlock(&gp->pm_mutex); - return 0; } @@ -2341,59 +2323,35 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); struct gem *gp = netdev_priv(dev); - unsigned long flags; - mutex_lock(&gp->pm_mutex); - - netdev_info(dev, "suspending, WakeOnLan %s\n", - (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled"); - - /* Keep the cell enabled during the entire operation */ - spin_lock_irqsave(&gp->lock, flags); - spin_lock(&gp->tx_lock); - gem_get_cell(gp); - spin_unlock(&gp->tx_lock); - spin_unlock_irqrestore(&gp->lock, flags); - - /* If the driver is opened, we stop the MAC */ - if (gp->opened) { - napi_disable(&gp->napi); + /* Lock the network stack first to avoid racing with open/close, + * reset task and setting calls + */ + rtnl_lock(); - /* Stop traffic, mark us closed */ + /* Not running, mark ourselves non-present, no need for + * a lock here + */ + if (!netif_running(dev)) { netif_device_detach(dev); + rtnl_unlock(); + return 0; + } + netdev_info(dev, "suspending, WakeOnLan %s\n", + (gp->wake_on_lan && netif_running(dev)) ? + "enabled" : "disabled"); - /* Switch off MAC, remember WOL setting */ - gp->asleep_wol = gp->wake_on_lan; - gem_do_stop(dev, gp->asleep_wol); - } else - gp->asleep_wol = 0; - - /* Mark us asleep */ - gp->asleep = 1; - wmb(); - - /* Stop the link timer */ - del_timer_sync(&gp->link_timer); - - /* Now we release the mutex to not block the reset task who - * can take it too. We are marked asleep, so there will be no - * conflict here + /* Tell the network stack we're gone. gem_do_stop() below will + * synchronize with TX, stop NAPI etc... */ - mutex_unlock(&gp->pm_mutex); - - /* Wait for the pending reset task to complete */ - flush_work_sync(&gp->reset_task); + netif_device_detach(dev); - /* Shut the PHY down eventually and setup WOL */ - gem_stop_phy(gp, gp->asleep_wol); - - /* Make sure bus master is disabled */ - pci_disable_device(gp->pdev); + /* Switch off chip, remember WOL setting */ + gp->asleep_wol = gp->wake_on_lan; + gem_do_stop(dev, gp->asleep_wol); - /* Release the cell, no need to take a lock at this point since - * nothing else can happen now - */ - gem_put_cell(gp); + /* Unlock the network stack */ + rtnl_unlock(); return 0; } @@ -2402,53 +2360,23 @@ static int gem_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct gem *gp = netdev_priv(dev); - unsigned long flags; - netdev_info(dev, "resuming\n"); + /* See locking comment in gem_suspend */ + rtnl_lock(); - mutex_lock(&gp->pm_mutex); - - /* Keep the cell enabled during the entire operation, no need to - * take a lock here tho since nothing else can happen while we are - * marked asleep + /* Not running, mark ourselves present, no need for + * a lock here */ - gem_get_cell(gp); - - /* Make sure PCI access and bus master are enabled */ - if (pci_enable_device(gp->pdev)) { - netdev_err(dev, "Can't re-enable chip !\n"); - /* Put cell and forget it for now, it will be considered as - * still asleep, a new sleep cycle may bring it back - */ - gem_put_cell(gp); - mutex_unlock(&gp->pm_mutex); + if (!netif_running(dev)) { + netif_device_attach(dev); + rtnl_unlock(); return 0; } - pci_set_master(gp->pdev); - - /* Reset everything */ - gem_reset(gp); - /* Mark us woken up */ - gp->asleep = 0; - wmb(); - - /* Bring the PHY back. Again, lock is useless at this point as - * nothing can be happening until we restart the whole thing + /* Restart chip. If that fails there isn't much we can do, we + * leave things stopped. */ - gem_init_phy(gp); - - /* If we were opened, bring everything back */ - if (gp->opened) { - /* Restart MAC */ - gem_do_start(dev); - - /* Re-attach net device */ - netif_device_attach(dev); - } - - spin_lock_irqsave(&gp->lock, flags); - spin_lock(&gp->tx_lock); + gem_do_start(dev); /* If we had WOL enabled, the cell clock was never turned off during * sleep, so we end up beeing unbalanced. Fix that here @@ -2456,15 +2384,8 @@ static int gem_resume(struct pci_dev *pdev) if (gp->asleep_wol) gem_put_cell(gp); - /* This function doesn't need to hold the cell, it will be held if the - * driver is open by gem_do_start(). - */ - gem_put_cell(gp); - - spin_unlock(&gp->tx_lock); - spin_unlock_irqrestore(&gp->lock, flags); - - mutex_unlock(&gp->pm_mutex); + /* Unlock the network stack */ + rtnl_unlock(); return 0; } @@ -2474,33 +2395,35 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev) { struct gem *gp = netdev_priv(dev); - spin_lock_irq(&gp->lock); - spin_lock(&gp->tx_lock); - /* I have seen this being called while the PM was in progress, - * so we shield against this + * so we shield against this. Let's also not poke at registers + * while the reset task is going on. + * + * TODO: Move stats collection elsewhere (link timer ?) and + * make this a nop to avoid all those synchro issues */ - if (gp->running) { - dev->stats.rx_crc_errors += readl(gp->regs + MAC_FCSERR); - writel(0, gp->regs + MAC_FCSERR); + if (!netif_device_present(dev) || !netif_running(dev)) + goto bail; - dev->stats.rx_frame_errors += readl(gp->regs + MAC_AERR); - writel(0, gp->regs + MAC_AERR); + /* Better safe than sorry... */ + if (WARN_ON(!gp->cell_enabled)) + goto bail; - dev->stats.rx_length_errors += readl(gp->regs + MAC_LERR); - writel(0, gp->regs + MAC_LERR); + dev->stats.rx_crc_errors += readl(gp->regs + MAC_FCSERR); + writel(0, gp->regs + MAC_FCSERR); - dev->stats.tx_aborted_errors += readl(gp->regs + MAC_ECOLL); - dev->stats.collisions += - (readl(gp->regs + MAC_ECOLL) + - readl(gp->regs + MAC_LCOLL)); - writel(0, gp->regs + MAC_ECOLL); - writel(0, gp->regs + MAC_LCOLL); - } + dev->stats.rx_frame_errors += readl(gp->regs + MAC_AERR); + writel(0, gp->regs + MAC_AERR); - spin_unlock(&gp->tx_lock); - spin_unlock_irq(&gp->lock); + dev->stats.rx_length_errors += readl(gp->regs + MAC_LERR); + writel(0, gp->regs + MAC_LERR); + dev->stats.tx_aborted_errors += readl(gp->regs + MAC_ECOLL); + dev->stats.collisions += + (readl(gp->regs + MAC_ECOLL) + readl(gp->regs + MAC_LCOLL)); + writel(0, gp->regs + MAC_ECOLL); + writel(0, gp->regs + MAC_LCOLL); + bail: return &dev->stats; } @@ -2513,22 +2436,19 @@ static int gem_set_mac_address(struct net_device *dev, void *addr) if (!is_valid_ether_addr(macaddr->sa_data)) return -EADDRNOTAVAIL; - if (!netif_running(dev) || !netif_device_present(dev)) { - /* We'll just catch it later when the - * device is up'd or resumed. - */ - memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len); + memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len); + + /* We'll just catch it later when the device is up'd or resumed */ + if (!netif_running(dev) || !netif_device_present(dev)) return 0; - } - mutex_lock(&gp->pm_mutex); - memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len); - if (gp->running) { - writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0); - writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1); - writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2); - } - mutex_unlock(&gp->pm_mutex); + /* Better safe than sorry... */ + if (WARN_ON(!gp->cell_enabled)) + return 0; + + writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0); + writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1); + writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2); return 0; } @@ -2539,14 +2459,12 @@ static void gem_set_multicast(struct net_device *dev) u32 rxcfg, rxcfg_new; int limit = 10000; + if (!netif_running(dev) || !netif_device_present(dev)) + return; - spin_lock_irq(&gp->lock); - spin_lock(&gp->tx_lock); - - if (!gp->running) - goto bail; - - netif_stop_queue(dev); + /* Better safe than sorry... */ + if (gp->reset_task_pending || WARN_ON(!gp->cell_enabled)) + return; rxcfg = readl(gp->regs + MAC_RXCFG); rxcfg_new = gem_setup_multicast(gp); @@ -2566,12 +2484,6 @@ static void gem_set_multicast(struct net_device *dev) rxcfg |= rxcfg_new; writel(rxcfg, gp->regs + MAC_RXCFG); - - netif_wake_queue(dev); - - bail: - spin_unlock(&gp->tx_lock); - spin_unlock_irq(&gp->lock); } /* Jumbo-grams don't seem to work :-( */ @@ -2589,26 +2501,21 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu) if (new_mtu < GEM_MIN_MTU || new_mtu > GEM_MAX_MTU) return -EINVAL; - if (!netif_running(dev) || !netif_device_present(dev)) { - /* We'll just catch it later when the - * device is up'd or resumed. - */ - dev->mtu = new_mtu; + dev->mtu = new_mtu; + + /* We'll just catch it later when the device is up'd or resumed */ + if (!netif_running(dev) || !netif_device_present(dev)) return 0; - } - mutex_lock(&gp->pm_mutex); - spin_lock_irq(&gp->lock); - spin_lock(&gp->tx_lock); - dev->mtu = new_mtu; - if (gp->running) { - gem_reinit_chip(gp); - if (gp->lstate == link_up) - gem_set_link_modes(gp); - } - spin_unlock(&gp->tx_lock); - spin_unlock_irq(&gp->lock); - mutex_unlock(&gp->pm_mutex); + /* Better safe than sorry... */ + if (WARN_ON(!gp->cell_enabled)) + return 0; + + gem_netif_stop(gp); + gem_reinit_chip(gp); + if (gp->lstate == link_up) + gem_set_link_modes(gp); + gem_netif_start(gp); return 0; } @@ -2640,7 +2547,6 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->phy_address = 0; /* XXX fixed PHYAD */ /* Return current PHY settings */ - spin_lock_irq(&gp->lock); cmd->autoneg = gp->want_autoneg; ethtool_cmd_speed_set(cmd, gp->phy_mii.speed); cmd->duplex = gp->phy_mii.duplex; @@ -2652,7 +2558,6 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) */ if (cmd->advertising == 0) cmd->advertising = cmd->supported; - spin_unlock_irq(&gp->lock); } else { // XXX PCS ? cmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | @@ -2706,11 +2611,10 @@ static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; /* Apply settings and restart link process. */ - spin_lock_irq(&gp->lock); - gem_get_cell(gp); - gem_begin_auto_negotiation(gp, cmd); - gem_put_cell(gp); - spin_unlock_irq(&gp->lock); + if (netif_device_present(gp->dev)) { + del_timer_sync(&gp->link_timer); + gem_begin_auto_negotiation(gp, cmd); + } return 0; } @@ -2722,12 +2626,11 @@ static int gem_nway_reset(struct net_device *dev) if (!gp->want_autoneg) return -EINVAL; - /* Restart link process. */ - spin_lock_irq(&gp->lock); - gem_get_cell(gp); - gem_begin_auto_negotiation(gp, NULL); - gem_put_cell(gp); - spin_unlock_irq(&gp->lock); + /* Restart link process */ + if (netif_device_present(gp->dev)) { + del_timer_sync(&gp->link_timer); + gem_begin_auto_negotiation(gp, NULL); + } return 0; } @@ -2791,16 +2694,11 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct gem *gp = netdev_priv(dev); struct mii_ioctl_data *data = if_mii(ifr); int rc = -EOPNOTSUPP; - unsigned long flags; - /* Hold the PM mutex while doing ioctl's or we may collide - * with power management. + /* For SIOCGMIIREG and SIOCSMIIREG the core checks for us that + * netif_device_present() is true and holds rtnl_lock for us + * so we have nothing to worry about */ - mutex_lock(&gp->pm_mutex); - - spin_lock_irqsave(&gp->lock, flags); - gem_get_cell(gp); - spin_unlock_irqrestore(&gp->lock, flags); switch (cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ @@ -2808,32 +2706,17 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /* Fallthrough... */ case SIOCGMIIREG: /* Read MII PHY register. */ - if (!gp->running) - rc = -EAGAIN; - else { - data->val_out = __phy_read(gp, data->phy_id & 0x1f, - data->reg_num & 0x1f); - rc = 0; - } + data->val_out = __phy_read(gp, data->phy_id & 0x1f, + data->reg_num & 0x1f); + rc = 0; break; case SIOCSMIIREG: /* Write MII PHY register. */ - if (!gp->running) - rc = -EAGAIN; - else { - __phy_write(gp, data->phy_id & 0x1f, data->reg_num & 0x1f, - data->val_in); - rc = 0; - } + __phy_write(gp, data->phy_id & 0x1f, data->reg_num & 0x1f, + data->val_in); + rc = 0; break; }; - - spin_lock_irqsave(&gp->lock, flags); - gem_put_cell(gp); - spin_unlock_irqrestore(&gp->lock, flags); - - mutex_unlock(&gp->pm_mutex); - return rc; } @@ -2921,23 +2804,9 @@ static void gem_remove_one(struct pci_dev *pdev) unregister_netdev(dev); - /* Stop the link timer */ - del_timer_sync(&gp->link_timer); - - /* We shouldn't need any locking here */ - gem_get_cell(gp); - - /* Cancel reset task */ + /* Ensure reset task is truely gone */ cancel_work_sync(&gp->reset_task); - /* Shut the PHY down */ - gem_stop_phy(gp, 0); - - gem_put_cell(gp); - - /* Make sure bus master is disabled */ - pci_disable_device(gp->pdev); - /* Free resources */ pci_free_consistent(pdev, sizeof(struct gem_init_block), @@ -3043,10 +2912,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gp->msg_enable = DEFAULT_MSG; - spin_lock_init(&gp->lock); - spin_lock_init(&gp->tx_lock); - mutex_init(&gp->pm_mutex); - init_timer(&gp->link_timer); gp->link_timer.function = gem_link_timer; gp->link_timer.data = (unsigned long) gp; @@ -3122,14 +2987,11 @@ static int __devinit gem_init_one(struct pci_dev *pdev, /* Set that now, in case PM kicks in now */ pci_set_drvdata(pdev, dev); - /* Detect & init PHY, start autoneg, we release the cell now - * too, it will be managed by whoever needs it - */ - gem_init_phy(gp); - - spin_lock_irq(&gp->lock); - gem_put_cell(gp); - spin_unlock_irq(&gp->lock); + /* We can do scatter/gather and HW checksum */ + dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM; + dev->features |= dev->hw_features | NETIF_F_RXCSUM; + if (pci_using_dac) + dev->features |= NETIF_F_HIGHDMA; /* Register with kernel */ if (register_netdev(dev)) { @@ -3138,20 +3000,15 @@ static int __devinit gem_init_one(struct pci_dev *pdev, goto err_out_free_consistent; } + /* Undo the get_cell with appropriate locking (we could use + * ndo_init/uninit but that would be even more clumsy imho) + */ + rtnl_lock(); + gem_put_cell(gp); + rtnl_unlock(); + netdev_info(dev, "Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n", dev->dev_addr); - - if (gp->phy_type == phy_mii_mdio0 || - gp->phy_type == phy_mii_mdio1) - netdev_info(dev, "Found %s PHY\n", - gp->phy_mii.def ? gp->phy_mii.def->name : "no"); - - /* GEM can do it all... */ - dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM; - dev->features |= dev->hw_features | NETIF_F_RXCSUM | NETIF_F_LLTX; - if (pci_using_dac) - dev->features |= NETIF_F_HIGHDMA; - return 0; err_out_free_consistent: diff --git a/drivers/net/sungem.h b/drivers/net/sungem.h index d225077964e..835ce1b3cb9 100644 --- a/drivers/net/sungem.h +++ b/drivers/net/sungem.h @@ -973,23 +973,14 @@ enum link_state { }; struct gem { - spinlock_t lock; - spinlock_t tx_lock; void __iomem *regs; int rx_new, rx_old; int tx_new, tx_old; unsigned int has_wol : 1; /* chip supports wake-on-lan */ - unsigned int asleep : 1; /* chip asleep, protected by pm_mutex */ unsigned int asleep_wol : 1; /* was asleep with WOL enabled */ - unsigned int opened : 1; /* driver opened, protected by pm_mutex */ - unsigned int running : 1; /* chip running, protected by lock */ - /* cell enable count, protected by lock */ int cell_enabled; - - struct mutex pm_mutex; - u32 msg_enable; u32 status; @@ -1033,20 +1024,4 @@ struct gem { #define found_mii_phy(gp) ((gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) && \ gp->phy_mii.def && gp->phy_mii.def->ops) -#define ALIGNED_RX_SKB_ADDR(addr) \ - ((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr)) -static __inline__ struct sk_buff *gem_alloc_skb(int size, - gfp_t gfp_flags) -{ - struct sk_buff *skb = alloc_skb(size + 64, gfp_flags); - - if (skb) { - int offset = (int) ALIGNED_RX_SKB_ADDR(skb->data); - if (offset) - skb_reserve(skb, offset); - } - - return skb; -} - #endif /* _SUNGEM_H */ -- cgit v1.2.3-70-g09d2 From 34624d6631b6b3a1df16407a847286bb6233a96b Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Thu, 2 Jun 2011 02:24:14 +0000 Subject: netxen: suppress false lro warning messages When interface is down, driver prints false warning messages during lro configuration through ethtool. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_hw.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 5cef718fe35..3f89e57cae5 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -809,6 +809,9 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable) u64 word; int rv = 0; + if (!test_bit(__NX_FW_ATTACHED, &adapter->state)) + return 0; + memset(&req, 0, sizeof(nx_nic_req_t)); req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); @@ -959,6 +962,9 @@ int netxen_send_lro_cleanup(struct netxen_adapter *adapter) u64 word; int rv; + if (!test_bit(__NX_FW_ATTACHED, &adapter->state)) + return 0; + memset(&req, 0, sizeof(nx_nic_req_t)); req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); -- cgit v1.2.3-70-g09d2 From 2e69167c32780b2228f294505d5bf742494c960f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:48:23 +0900 Subject: rtlwifi: Synchronize IRQ after disabling it This make sure any IRQ handlers running on other CPUs complete. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index d5d3c8a572c..944f55e9d31 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1194,6 +1194,7 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); rtlpci->irq_enabled = false; + synchronize_irq(rtlpci->pdev->irq); } static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) -- cgit v1.2.3-70-g09d2 From f2ea312cf4338ae187212e41b3dce97a666e3912 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:48:50 +0900 Subject: rtlwifi: Remove set_rfpowerstate_inprogress set_rfpowerstate_inprogress is only set and never read so remove it. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 4 ---- drivers/net/wireless/rtlwifi/wifi.h | 1 - 4 files changed, 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index c5be547ad71..dde619e2994 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -519,7 +519,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, u8 i, queue_id; struct rtl8192_tx_ring *ring = NULL; - ppsc->set_rfpowerstate_inprogress = true; switch (rfpwr_state) { case ERFON:{ if ((ppsc->rfpwr_state == ERFOFF) && @@ -615,7 +614,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, } if (bresult) ppsc->rfpwr_state = rfpwr_state; - ppsc->set_rfpowerstate_inprogress = false; return bresult; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 9a3d0239e27..72852900df8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -470,7 +470,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, u8 i, queue_id; struct rtl8192_tx_ring *ring = NULL; - ppsc->set_rfpowerstate_inprogress = true; switch (rfpwr_state) { case ERFON: if ((ppsc->rfpwr_state == ERFOFF) && @@ -590,7 +589,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, } if (bresult) ppsc->rfpwr_state = rfpwr_state; - ppsc->set_rfpowerstate_inprogress = false; return bresult; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index a26713b5afb..fd969fd0e5c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -546,8 +546,6 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, if (rfpwr_state == ppsc->rfpwr_state) return false; - ppsc->set_rfpowerstate_inprogress = true; - switch (rfpwr_state) { case ERFON:{ if ((ppsc->rfpwr_state == ERFOFF) && @@ -659,8 +657,6 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, if (bresult) ppsc->rfpwr_state = rfpwr_state; - ppsc->set_rfpowerstate_inprogress = false; - return bresult; } diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 693395ee98f..03213285f77 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1188,7 +1188,6 @@ struct rtl_efuse { struct rtl_ps_ctl { bool pwrdomain_protect; - bool set_rfpowerstate_inprogress; bool in_powersavemode; bool rfchange_inprogress; bool swrf_processing; -- cgit v1.2.3-70-g09d2 From 34ddb2077e5ced1a09a1dd2cbb82f807bfc5f88b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:49:07 +0900 Subject: rtlwifi: Store loop index in local variable _rtl_pci_rx_interrupt uses rtlpci->rx_ring[rx_queue_idx].idx a few times, so store it in a separate variable. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 89100e7c553..b44de0d0cc9 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -644,22 +644,23 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) .noise = -98, .rate = 0, }; + int index = rtlpci->rx_ring[rx_queue_idx].idx; /*RX NORMAL PKT */ while (count--) { /*rx descriptor */ struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[ - rtlpci->rx_ring[rx_queue_idx].idx]; + index]; /*rx pkt */ struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ - rtlpci->rx_ring[rx_queue_idx].idx]; + index]; own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, HW_DESC_OWN); if (own) { /*wait data to be filled by hardware */ - return; + break; } else { struct ieee80211_hdr *hdr; __le16 fc; @@ -770,10 +771,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) skb = new_skb; - rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> - rx_ring - [rx_queue_idx]. - idx] = skb; + rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; *((dma_addr_t *) skb->cb) = pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), rtlpci->rxbuffersize, @@ -792,17 +790,15 @@ done: HW_DESC_RXPKT_LEN, (u8 *)&rtlpci->rxbuffersize); - if (rtlpci->rx_ring[rx_queue_idx].idx == - rtlpci->rxringcount - 1) + if (index == rtlpci->rxringcount - 1) rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXERO, (u8 *)&tmp_one); - rtlpci->rx_ring[rx_queue_idx].idx = - (rtlpci->rx_ring[rx_queue_idx].idx + 1) % - rtlpci->rxringcount; + index = (index + 1) % rtlpci->rxringcount; } + rtlpci->rx_ring[rx_queue_idx].idx = index; } static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) -- cgit v1.2.3-70-g09d2 From 67fc6052a49b781efbcfc138f3b68fe79ddd0c2f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:49:23 +0900 Subject: rtlwifi: Run IPS leave work in a tasklet This removes the need to use IRQ safe spinlocks in many places. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 14 ++++++++++++-- drivers/net/wireless/rtlwifi/ps.c | 1 + drivers/net/wireless/rtlwifi/wifi.h | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index b44de0d0cc9..6c1b9dffc07 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -622,7 +622,7 @@ tx_status_ok: if (((rtlpriv->link_info.num_rx_inperiod + rtlpriv->link_info.num_tx_inperiod) > 8) || (rtlpriv->link_info.num_rx_inperiod > 2)) { - rtl_lps_leave(hw); + tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); } } @@ -766,7 +766,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) if (((rtlpriv->link_info.num_rx_inperiod + rtlpriv->link_info.num_tx_inperiod) > 8) || (rtlpriv->link_info.num_rx_inperiod > 2)) { - rtl_lps_leave(hw); + tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); } skb = new_skb; @@ -936,6 +936,11 @@ static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) _rtl_pci_tx_chk_waitq(hw); } +static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw) +{ + rtl_lps_leave(hw); +} + static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1034,6 +1039,9 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, (unsigned long)hw); + tasklet_init(&rtlpriv->works.ips_leave_tasklet, + (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet, + (unsigned long)hw); } static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, @@ -1503,6 +1511,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw) synchronize_irq(rtlpci->pdev->irq); tasklet_kill(&rtlpriv->works.irq_tasklet); + tasklet_kill(&rtlpriv->works.ips_leave_tasklet); flush_workqueue(rtlpriv->works.rtl_wq); destroy_workqueue(rtlpriv->works.rtl_wq); @@ -1577,6 +1586,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) set_hal_stop(rtlhal); rtlpriv->cfg->ops->disable_interrupt(hw); + tasklet_kill(&rtlpriv->works.ips_leave_tasklet); spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); while (ppsc->rfchange_inprogress) { diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index a73ffbe68ba..fd3b04f0843 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -68,6 +68,7 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw) /*<2> Disable Interrupt */ rtlpriv->cfg->ops->disable_interrupt(hw); + tasklet_kill(&rtlpriv->works.irq_tasklet); /*<3> Disable Adapter */ rtlpriv->cfg->ops->hw_disable(hw); diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 03213285f77..9d003e0864f 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1535,6 +1535,7 @@ struct rtl_works { /* For SW LPS */ struct delayed_work ps_work; struct delayed_work ps_rfon_wq; + struct tasklet_struct ips_leave_tasklet; }; struct rtl_debug { -- cgit v1.2.3-70-g09d2 From 312d5479dcfaca2b8aa451201b5388fdb8c8684a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:49:36 +0900 Subject: rtlwifi: Don't block interrupts in spinlocks Now power state transitions are not called from an interrupt context, there's no need to block interrupts. This code appears to block interrupts for too long, causing my trackpad to lose sync occasionally. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/ps.c | 44 ++++++++++++---------------- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 10 +++---- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 10 +++---- 3 files changed, 26 insertions(+), 38 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index fd3b04f0843..d14c13d0217 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -85,7 +85,6 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool actionallowed = false; u16 rfwait_cnt = 0; - unsigned long flag; /*protect_or_not = true; */ @@ -98,10 +97,9 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, *should wait to be executed. */ while (true) { - spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + spin_lock(&rtlpriv->locks.rf_ps_lock); if (ppsc->rfchange_inprogress) { - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, - flag); + spin_unlock(&rtlpriv->locks.rf_ps_lock); RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("RF Change in progress!" @@ -122,8 +120,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, } } else { ppsc->rfchange_inprogress = true; - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, - flag); + spin_unlock(&rtlpriv->locks.rf_ps_lock); break; } } @@ -171,9 +168,9 @@ no_protect: rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); if (!protect_or_not) { - spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + spin_lock(&rtlpriv->locks.rf_ps_lock); ppsc->rfchange_inprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + spin_unlock(&rtlpriv->locks.rf_ps_lock); } return actionallowed; @@ -287,12 +284,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); enum rf_pwrstate rtstate; - unsigned long flags; if (mac->opmode != NL80211_IFTYPE_STATION) return; - spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); + spin_lock(&rtlpriv->locks.ips_lock); if (ppsc->inactiveps) { rtstate = ppsc->rfpwr_state; @@ -308,7 +304,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) } } - spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags); + spin_unlock(&rtlpriv->locks.ips_lock); } /*for FW LPS*/ @@ -426,7 +422,6 @@ void rtl_lps_enter(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_priv *rtlpriv = rtl_priv(hw); - unsigned long flag; if (!ppsc->fwctrl_lps) return; @@ -447,7 +442,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) if (mac->link_state != MAC80211_LINKED) return; - spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); + spin_lock(&rtlpriv->locks.lps_lock); /* Idle for a while if we connect to AP a while ago. */ if (mac->cnt_after_linked >= 2) { @@ -459,7 +454,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) } } - spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); + spin_unlock(&rtlpriv->locks.lps_lock); } /*Leave the leisure power save mode.*/ @@ -468,9 +463,8 @@ void rtl_lps_leave(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - unsigned long flag; - spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); + spin_lock(&rtlpriv->locks.lps_lock); if (ppsc->fwctrl_lps) { if (ppsc->dot11_psmode != EACTIVE) { @@ -491,7 +485,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) rtl_lps_set_psmode(hw, EACTIVE); } } - spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); + spin_unlock(&rtlpriv->locks.lps_lock); } /* For sw LPS*/ @@ -580,7 +574,6 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - unsigned long flag; if (!rtlpriv->psc.swctrl_lps) return; @@ -593,9 +586,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); } - spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); + spin_lock(&rtlpriv->locks.lps_lock); rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); - spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); + spin_unlock(&rtlpriv->locks.lps_lock); } void rtl_swlps_rfon_wq_callback(void *data) @@ -612,7 +605,6 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - unsigned long flag; u8 sleep_intv; if (!rtlpriv->psc.sw_ps_enabled) @@ -629,16 +621,16 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) if (rtlpriv->link_info.busytraffic) return; - spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + spin_lock(&rtlpriv->locks.rf_ps_lock); if (rtlpriv->psc.rfchange_inprogress) { - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + spin_unlock(&rtlpriv->locks.rf_ps_lock); return; } - spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + spin_unlock(&rtlpriv->locks.rf_ps_lock); - spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); + spin_lock(&rtlpriv->locks.lps_lock); rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); - spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); + spin_unlock(&rtlpriv->locks.lps_lock); if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index dde619e2994..592a10ac592 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -46,13 +46,12 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 original_value, readback_value, bitshift; struct rtl_phy *rtlphy = &(rtlpriv->phy); - unsigned long flags; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " "rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath, bitmask)); - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + spin_lock(&rtlpriv->locks.rf_lock); if (rtlphy->rf_mode != RF_OP_BY_FW) { original_value = _rtl92c_phy_rf_serial_read(hw, @@ -65,7 +64,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + spin_unlock(&rtlpriv->locks.rf_lock); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " @@ -120,13 +119,12 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); u32 original_value, bitshift; - unsigned long flags; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + spin_lock(&rtlpriv->locks.rf_lock); if (rtlphy->rf_mode != RF_OP_BY_FW) { if (bitmask != RFREG_OFFSET_MASK) { @@ -153,7 +151,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); } - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + spin_unlock(&rtlpriv->locks.rf_lock); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " "bitmask(%#x), data(%#x), " diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index fd969fd0e5c..7ee2daccd7d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -180,19 +180,18 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, { struct rtl_priv *rtlpriv = rtl_priv(hw); u32 original_value, readback_value, bitshift; - unsigned long flags; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " "bitmask(%#x)\n", regaddr, rfpath, bitmask)); - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + spin_lock(&rtlpriv->locks.rf_lock); original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + spin_unlock(&rtlpriv->locks.rf_lock); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath, @@ -207,7 +206,6 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); u32 original_value, bitshift; - unsigned long flags; if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) return; @@ -215,7 +213,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + spin_lock(&rtlpriv->locks.rf_lock); if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, @@ -226,7 +224,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data); - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + spin_unlock(&rtlpriv->locks.rf_lock); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), " "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); -- cgit v1.2.3-70-g09d2 From febc9fe5387ed37cb329563ae29d21b41c71a9dd Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:49:51 +0900 Subject: rtlwifi: Assign rx buffer ownership to hardware last Ownership of an rx buffer should only be given to the hardware after all other changes are written, otherwise there's a potential race. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 6c1b9dffc07..e29feef002b 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -784,8 +784,6 @@ done: rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, HW_DESC_RXBUFF_ADDR, (u8 *)&bufferaddress); - rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, - (u8 *)&tmp_one); rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXPKT_LEN, (u8 *)&rtlpci->rxbuffersize); @@ -795,6 +793,9 @@ done: HW_DESC_RXERO, (u8 *)&tmp_one); + rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, + (u8 *)&tmp_one); + index = (index + 1) % rtlpci->rxringcount; } -- cgit v1.2.3-70-g09d2 From 71352b2318675cf6a3f54c02a33d91ac17af1626 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:50:07 +0900 Subject: rtlwifi: Use write barrier when assigning ownership Make sure all updates to a descriptor are flushed to memory before assigning ownship to hardware. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index ac95dc44374..2492cc234c0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -930,6 +930,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) if (istx == true) { switch (desc_name) { case HW_DESC_OWN: + wmb(); SET_TX_DESC_OWN(pdesc, 1); break; case HW_DESC_TX_NEXTDESC_ADDR: @@ -943,6 +944,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) } else { switch (desc_name) { case HW_DESC_RXOWN: + wmb(); SET_RX_DESC_OWN(pdesc, 1); break; case HW_DESC_RXBUFF_ADDR: -- cgit v1.2.3-70-g09d2 From dabd3001f941e35c4afa2458ceb17e5170062189 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 31 May 2011 08:50:24 +0900 Subject: rtlwifi: Fix logic in rx_interrupt Should pass along packet if there's no CRC and no hardware error. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index e29feef002b..fc44005b0d5 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -701,7 +701,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); - if (!stats.crc || !stats.hwerror) { + if (!stats.crc && !stats.hwerror) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); -- cgit v1.2.3-70-g09d2 From 5a6f78afdabeb8b8e0811547fb98813323abf888 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 31 May 2011 21:21:41 +0200 Subject: ath9k: show excessive-retry MPDUs in debugfs Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 6 +++++- drivers/net/wireless/ath/ath9k/debug.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 7230d6578b1..22d3a26e684 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -600,6 +600,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("MPDUs Queued: ", queued); PR("MPDUs Completed: ", completed); + PR("MPDUs XRetried: ", xretries); PR("Aggregates: ", a_aggr); PR("AMPDUs Queued HW:", a_queued_hw); PR("AMPDUs Queued SW:", a_queued_sw); @@ -856,7 +857,10 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, else TX_STAT_INC(qnum, a_completed); } else { - TX_STAT_INC(qnum, completed); + if (bf_isxretried(bf)) + TX_STAT_INC(qnum, xretries); + else + TX_STAT_INC(qnum, completed); } if (ts->ts_status & ATH9K_TXERR_FIFO) diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 8ce6ad80f4e..4a04510e111 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -116,6 +116,7 @@ struct ath_tx_stats { u32 tx_bytes_all; u32 queued; u32 completed; + u32 xretries; u32 a_aggr; u32 a_queued_hw; u32 a_queued_sw; -- cgit v1.2.3-70-g09d2 From 4da909e7b572b561d8150f9d41b04bcfff386222 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 2 Jun 2011 01:07:12 +0200 Subject: b43: do not use SSB specific flags when calling core reset function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Luckily the only flag we use when calling core reset is GMODE one. Thanks to that we can just switch to single bool and make function calls bus generic. Tested on my BCM4312 (LP-PHY) and early tested with BCM43224. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 25 +++++++++++-------------- drivers/net/wireless/b43/main.h | 2 +- drivers/net/wireless/b43/phy_g.c | 2 +- 3 files changed, 13 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 659bc3169a4..1b9d3cc2dd9 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1144,11 +1144,14 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) } } -static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) +static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) { struct ssb_device *sdev = dev->dev->sdev; u32 tmslow; + u32 flags = 0; + if (gmode) + flags |= B43_TMSLOW_GMODE; flags |= B43_TMSLOW_PHYCLKEN; flags |= B43_TMSLOW_PHYRESET; if (dev->phy.type == B43_PHYTYPE_N) @@ -1169,11 +1172,11 @@ static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) msleep(1); } -void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) +void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode) { u32 macctl; - b43_ssb_wireless_core_reset(dev, flags); + b43_ssb_wireless_core_reset(dev, gmode); /* Turn Analog ON, but only if we already know the PHY-type. * This protects against very early setup where we don't know the @@ -1184,7 +1187,7 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) macctl = b43_read32(dev, B43_MMIO_MACCTL); macctl &= ~B43_MACCTL_GMODE; - if (flags & B43_TMSLOW_GMODE) + if (gmode) macctl |= B43_MACCTL_GMODE; macctl |= B43_MACCTL_IHR_ENABLED; b43_write32(dev, B43_MMIO_MACCTL, macctl); @@ -4328,17 +4331,14 @@ static int b43_wireless_core_init(struct b43_wldev *dev) struct b43_phy *phy = &dev->phy; int err; u64 hf; - u32 tmp; B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); err = b43_bus_powerup(dev, 0); if (err) goto out; - if (!b43_device_is_enabled(dev)) { - tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; - b43_wireless_core_reset(dev, tmp); - } + if (!b43_device_is_enabled(dev)) + b43_wireless_core_reset(dev, phy->gmode); /* Reset all data structures. */ setup_struct_wldev_for_init(dev); @@ -4747,7 +4747,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; int err; bool have_2ghz_phy = 0, have_5ghz_phy = 0; - u32 tmp; /* Do NOT do any device initialization here. * Do it in wireless_core_init() instead. @@ -4773,8 +4772,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) dev->phy.gmode = have_2ghz_phy; dev->phy.radio_on = 1; - tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; - b43_wireless_core_reset(dev, tmp); + b43_wireless_core_reset(dev, dev->phy.gmode); err = b43_phy_versioning(dev); if (err) @@ -4822,8 +4820,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) goto err_powerdown; dev->phy.gmode = have_2ghz_phy; - tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; - b43_wireless_core_reset(dev, tmp); + b43_wireless_core_reset(dev, dev->phy.gmode); err = b43_validate_chipaccess(dev); if (err) diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index a0d327f1318..e4ebce9be59 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h @@ -121,7 +121,7 @@ void b43_hf_write(struct b43_wldev *dev, u64 value); void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on); -void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags); +void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode); void b43_controller_restart(struct b43_wldev *dev, const char *reason); diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 684be1fd59a..83532d19347 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -2535,7 +2535,7 @@ static int b43_gphy_op_prepare_hardware(struct b43_wldev *dev) b43_wireless_core_reset(dev, 0); b43_phy_initg(dev); phy->gmode = 1; - b43_wireless_core_reset(dev, B43_TMSLOW_GMODE); + b43_wireless_core_reset(dev, 1); } return 0; -- cgit v1.2.3-70-g09d2 From 3c65ab62c5869a9d6ce5d9c28f7042b0e7e57891 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 2 Jun 2011 09:56:04 +0200 Subject: b43: add an option to register BROKEN bcma driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It does nothing useful yet, so it is matched as BROKEN. For now this is just an option for b43, in future we may want to make b43 support SSB or BCMA (note: or, not xor). Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 5 +++++ drivers/net/wireless/b43/b43.h | 1 + drivers/net/wireless/b43/main.c | 44 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 480595f0441..fe26bf448fd 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -26,6 +26,11 @@ config B43 This driver can be built as a module (recommended) that will be called "b43". If unsure, say M. +config B43_BCMA + bool "Support for BCMA bus" + depends on B43 && BCMA && BROKEN + default y + # Auto-select SSB PCI-HOST support, if possible config B43_PCI_AUTOSELECT bool diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 0a3c7012901..81d78bfa0e8 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1b9d3cc2dd9..1d8d98324d1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -113,6 +113,16 @@ static int b43_modparam_pio = B43_PIO_DEFAULT; module_param_named(pio, b43_modparam_pio, int, 0644); MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); +#ifdef CONFIG_B43_BCMA +static const struct bcma_device_id b43_bcma_tbl[] = { + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), + BCMA_CORETABLE_END +}; +MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); +#endif + static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), @@ -4986,6 +4996,26 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev) return wl; } +#ifdef CONFIG_B43_BCMA +static int b43_bcma_probe(struct bcma_device *core) +{ + b43err(NULL, "BCMA is not supported yet!"); + return -EOPNOTSUPP; +} + +static void b43_bcma_remove(struct bcma_device *core) +{ + /* TODO */ +} + +static struct bcma_driver b43_bcma_driver = { + .name = KBUILD_MODNAME, + .id_table = b43_bcma_tbl, + .probe = b43_bcma_probe, + .remove = b43_bcma_remove, +}; +#endif + static int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) { @@ -5116,14 +5146,23 @@ static int __init b43_init(void) err = b43_sdio_init(); if (err) goto err_pcmcia_exit; - err = ssb_driver_register(&b43_ssb_driver); +#ifdef CONFIG_B43_BCMA + err = bcma_driver_register(&b43_bcma_driver); if (err) goto err_sdio_exit; +#endif + err = ssb_driver_register(&b43_ssb_driver); + if (err) + goto err_bcma_driver_exit; b43_print_driverinfo(); return err; +err_bcma_driver_exit: +#ifdef CONFIG_B43_BCMA + bcma_driver_unregister(&b43_bcma_driver); err_sdio_exit: +#endif b43_sdio_exit(); err_pcmcia_exit: b43_pcmcia_exit(); @@ -5135,6 +5174,9 @@ err_dfs_exit: static void __exit b43_exit(void) { ssb_driver_unregister(&b43_ssb_driver); +#ifdef CONFIG_B43_BCMA + bcma_driver_unregister(&b43_bcma_driver); +#endif b43_sdio_exit(); b43_pcmcia_exit(); b43_debugfs_exit(); -- cgit v1.2.3-70-g09d2 From aa4e0141c1c1ca53c643eacc6a68f29ade5f77ba Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 2 Jun 2011 13:43:24 +0200 Subject: b43: add BCMA 80211 core specific defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 81d78bfa0e8..1cb2ddee9dc 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -416,6 +416,17 @@ enum { #define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ #define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ +/* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */ +#define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */ +#define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */ +#define B43_BCMA_IOCTL_MACPHYCLKEN 0x00000010 /* MAC PHY Clock Control Enable */ +#define B43_BCMA_IOCTL_PLLREFSEL 0x00000020 /* PLL Frequency Reference Select */ +#define B43_BCMA_IOCTL_PHY_BW 0x000000C0 /* PHY band width and clock speed mask (N-PHY+ only?) */ +#define B43_BCMA_IOCTL_PHY_BW_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */ +#define B43_BCMA_IOCTL_PHY_BW_20MHZ 0x00000040 /* 20 MHz bandwidth, 80 MHz PHY */ +#define B43_BCMA_IOCTL_PHY_BW_40MHZ 0x00000080 /* 40 MHz bandwidth, 160 MHz PHY */ +#define B43_BCMA_IOCTL_GMODE 0x00002000 /* G Mode Enable */ + /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */ #define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ #define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */ -- cgit v1.2.3-70-g09d2 From e5a042ea30c1772df9ed3dbe1538520e091ad25f Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Thu, 2 Jun 2011 21:06:06 -0500 Subject: iwlegacy: remove unreachable code return; at the end of the function is unecessary. Signed-off-by: Greg Dietsche Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-eeprom.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-eeprom.c b/drivers/net/wireless/iwlegacy/iwl-eeprom.c index cb346d1a9ff..5bf3f49b74a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-eeprom.c +++ b/drivers/net/wireless/iwlegacy/iwl-eeprom.c @@ -316,7 +316,6 @@ static void iwl_legacy_init_band_reference(const struct iwl_priv *priv, break; default: BUG(); - return; } } -- cgit v1.2.3-70-g09d2 From 04975f3fc390974059ad06ac4162db7a6668a18d Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Thu, 2 Jun 2011 21:06:07 -0500 Subject: iwlegacy: remove unecessary if statement the code always returns ret regardless, so if(ret) check is unecessary. Signed-off-by: Greg Dietsche Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index f5433c74b84..ffda05ca20f 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1185,8 +1185,6 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, ret = iwl_legacy_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, sizeof(rxon_assoc), &rxon_assoc, NULL); - if (ret) - return ret; return ret; } -- cgit v1.2.3-70-g09d2 From 8e638188b2b84ef9bb9ccbb87b92dda9d0a77bcb Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Thu, 2 Jun 2011 21:06:08 -0500 Subject: iwlegacy: return -EINVAL instead of -1 Cleanup the code to return -EINVAL instead of -1 Signed-off-by: Greg Dietsche Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index ffda05ca20f..06dcee5c51a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -496,7 +496,7 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel) channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) return CALIB_CH_GROUP_4; - return -1; + return -EINVAL; } static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) -- cgit v1.2.3-70-g09d2 From 5c30c76ee616fffb47cbd9810bfd0a99ce4ddb38 Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Thu, 2 Jun 2011 21:06:09 -0500 Subject: iwlegacy: propagate error return value propogate the return value from iwl4965_get_tx_atten_grp instead of implicitly returning -EINVAL in the error case. Signed-off-by: Greg Dietsche Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index 06dcee5c51a..79e7ce643f7 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -915,7 +915,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, if (txatten_grp < 0) { IWL_ERR(priv, "Can't find txatten group for channel %d.\n", channel); - return -EINVAL; + return txatten_grp; } IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", -- cgit v1.2.3-70-g09d2 From 0c34861e7c66435ab0986509ec20055c402f29d8 Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Thu, 2 Jun 2011 22:24:06 -0500 Subject: iwlegacy: add missing null check lq_sta has other null checks in this function. assuming they are correct, this additional null check should be added too. Incorporating suggestion from Gustavo Padovan. Signed-off-by: Greg Dietsche Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965-rs.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c index 24d149909ba..9b65153bdd0 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c @@ -2275,6 +2275,9 @@ iwl4965_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, if (rate_control_send_low(sta, priv_sta, txrc)) return; + if (!lq_sta) + return; + rate_idx = lq_sta->last_txrate_idx; if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { -- cgit v1.2.3-70-g09d2 From 88e9ba76bf906d8106d5f64856eba6e6d6777003 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 07:54:12 -0700 Subject: iwlagn: save the latest smps mode When change smps mode due to bt coex, save it Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 4ab77c8a584..677f73c4c1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1797,6 +1797,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) priv->cfg->ops->lib->update_chain_flags(priv); if (smps_request != -1) { + priv->current_ht_config.smps = smps_request; for_each_context(priv, ctx) { if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) ieee80211_request_smps(ctx->vif, smps_request); -- cgit v1.2.3-70-g09d2 From 15b3f3b006b42a678523cad989bfd60b76bf4403 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 07:54:13 -0700 Subject: iwlagn: set smps mode after assoc for 1000 device For some timing reason, 1000 device having problem to kick-in to aggregation without sending rxon assoc command. This is a W/A until find the real reason Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 5 +++-- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 99409501ad4..7aa240e6ba1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -222,6 +222,7 @@ static struct iwl_base_params iwl1000_base_params = { static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ + .smps_mode = IEEE80211_SMPS_STATIC, }; #define IWL_DEVICE_1000 \ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index afb2f202afb..5f562d91c2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -291,6 +291,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, IWL_ERR(priv, "Error sending TX power (%d)\n", ret); return ret; } + + if ((ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) && + priv->cfg->ht_params->smps_mode) + ieee80211_request_smps(ctx->vif, + priv->cfg->ht_params->smps_mode); + return 0; } @@ -395,6 +401,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * do it now if after settings changed. */ iwl_set_tx_power(priv, priv->tx_power_next, false); + + /* make sure we are in the right PS state */ + iwl_power_update_mode(priv, true); + return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a87b54fb9e7..e430a4fc8c5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -224,7 +224,7 @@ struct iwl_base_params { * @ampdu_factor: Maximum A-MPDU length factor * @ampdu_density: Minimum A-MPDU spacing * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode -*/ + */ struct iwl_bt_params { bool advanced_bt_coexist; u8 bt_init_traffic_load; @@ -237,10 +237,11 @@ struct iwl_bt_params { }; /* * @use_rts_for_aggregation: use rts/cts protection for HT traffic -*/ + */ struct iwl_ht_params { const bool ht_greenfield_support; /* if used set to true */ bool use_rts_for_aggregation; + enum ieee80211_smps_mode smps_mode; }; /** -- cgit v1.2.3-70-g09d2 From c2b821d7a59e5d6b53c906d0a8fecc68e2aee540 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 07:54:14 -0700 Subject: iwlagn: move all post scan functions in one place Both tx power and power save are being done after scan complete, move into post_scan function Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 7 +++++++ drivers/net/wireless/iwlwifi/iwl-scan.c | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 5f562d91c2e..18e69008728 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -799,6 +799,13 @@ void iwlagn_post_scan(struct iwl_priv *priv) { struct iwl_rxon_context *ctx; + /* + * We do not commit power settings while scan is pending, + * do it now if the settings changed. + */ + iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); + iwl_set_tx_power(priv, priv->tx_power_next, false); + /* * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index d60d630cb93..8c9af45c598 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -600,13 +600,6 @@ out_settings: if (!iwl_is_ready_rf(priv)) goto out; - /* - * We do not commit power settings while scan is pending, - * do it now if the settings changed. - */ - iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); - iwl_set_tx_power(priv, priv->tx_power_next, false); - priv->cfg->ops->utils->post_scan(priv); out: -- cgit v1.2.3-70-g09d2 From e80d70e98b993a7ece93e29a408da4a7d57a4da2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 07:54:15 -0700 Subject: iwlagn: direct call to post_scan function After driver split, no need to use function "ops" for post_scan. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 1 - drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-scan.c | 3 ++- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index b12c72d63cc..938230d30ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -332,5 +332,4 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { .tx_cmd_protection = iwlagn_tx_cmd_protection, .calc_rssi = iwlagn_calc_rssi, .request_scan = iwlagn_request_scan, - .post_scan = iwlagn_post_scan, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e430a4fc8c5..4ca03360fbf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -112,7 +112,6 @@ struct iwl_hcmd_utils_ops { int (*calc_rssi)(struct iwl_priv *priv, struct iwl_rx_phy_res *rx_resp); int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); - void (*post_scan)(struct iwl_priv *priv); }; struct iwl_apm_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 8c9af45c598..438eecd8733 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -36,6 +36,7 @@ #include "iwl-sta.h" #include "iwl-io.h" #include "iwl-helpers.h" +#include "iwl-agn.h" /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after * sending probe req. This should be set long enough to hear probe responses @@ -600,7 +601,7 @@ out_settings: if (!iwl_is_ready_rf(priv)) goto out; - priv->cfg->ops->utils->post_scan(priv); + iwlagn_post_scan(priv); out: mutex_unlock(&priv->mutex); -- cgit v1.2.3-70-g09d2 From 805a3b810708db3261cc8c1183ffb2703a5ce243 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 07:54:16 -0700 Subject: iwlagn: call commit_rxon function directly No need to go though multiple levels of indirect call to send RXON command. Call it directly Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +++++----- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 7 +------ 4 files changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 938230d30ac..87fd05acfe6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -310,7 +310,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) } struct iwl_hcmd_ops iwlagn_hcmd = { - .commit_rxon = iwlagn_commit_rxon, .set_rxon_chain = iwlagn_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwl_send_bt_config, @@ -318,7 +317,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = { }; struct iwl_hcmd_ops iwlagn_bt_hcmd = { - .commit_rxon = iwlagn_commit_rxon, .set_rxon_chain = iwlagn_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwlagn_send_advance_bt_config, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6ad33765637..96c72887710 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -97,7 +97,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv) for_each_context(priv, ctx) { priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); if (ctx->active.rx_chain != ctx->staging.rx_chain) - iwlcore_commit_rxon(priv, ctx); + iwlagn_commit_rxon(priv, ctx); } } } @@ -274,7 +274,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) for_each_context(priv, ctx) { if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - iwlcore_commit_rxon(priv, ctx); + iwlagn_commit_rxon(priv, ctx); } priv->cfg->ops->hcmd->send_bt_config(priv); @@ -2056,7 +2056,7 @@ int iwl_alive_start(struct iwl_priv *priv) set_bit(STATUS_READY, &priv->status); /* Configure the adapter for unassociated operation */ - ret = iwlcore_commit_rxon(priv, ctx); + ret = iwlagn_commit_rxon(priv, ctx); if (ret) return ret; @@ -3101,7 +3101,7 @@ static void iwlagn_disable_roc(struct iwl_priv *priv) priv->_agn.hw_roc_channel = NULL; - iwlcore_commit_rxon(priv, ctx); + iwlagn_commit_rxon(priv, ctx); ctx->is_active = false; } @@ -3144,7 +3144,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, priv->_agn.hw_roc_channel = channel; priv->_agn.hw_roc_chantype = channel_type; priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); - iwlcore_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); + iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, msecs_to_jiffies(duration + 20)); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 52e941382e0..de18916ca01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1279,7 +1279,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - return iwlcore_commit_rxon(priv, ctx); + return iwlagn_commit_rxon(priv, ctx); } static int iwl_setup_interface(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4ca03360fbf..b38477c8ad4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -90,7 +90,6 @@ struct iwl_cmd; #define IWL_CMD(x) case x: return #x struct iwl_hcmd_ops { - int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); void (*set_rxon_chain)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); @@ -611,11 +610,7 @@ void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -static inline int iwlcore_commit_rxon(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); -} + static inline const struct ieee80211_supported_band *iwl_get_hw_mode( struct iwl_priv *priv, enum ieee80211_band band) { -- cgit v1.2.3-70-g09d2 From 6403eab143205a45a5493166ff8bf7e3646f4a77 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 3 Jun 2011 11:51:20 +0000 Subject: drivers/net: Remove unnecessary semicolons Semicolons are not necessary after switch/while/for/if braces so remove them. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/amd8111e.c | 2 +- drivers/net/cxgb4/cxgb4_main.c | 2 +- drivers/net/enic/enic_main.c | 2 +- drivers/net/irda/via-ircc.h | 2 +- drivers/net/iseries_veth.c | 4 ++-- drivers/net/ixgbe/ixgbe_82599.c | 4 ++-- drivers/net/ixgbe/ixgbe_common.c | 4 ++-- drivers/net/myri10ge/myri10ge.c | 2 +- drivers/net/netxen/netxen_nic_init.c | 2 +- drivers/net/ps3_gelic_net.c | 2 +- drivers/net/slhc.c | 2 +- drivers/net/sungem.c | 2 +- drivers/net/tokenring/3c359.c | 6 ++++-- drivers/net/tokenring/ibmtr.c | 2 +- drivers/net/tun.c | 2 +- drivers/net/via-velocity.c | 2 +- drivers/net/wireless/b43/main.c | 2 +- drivers/net/wireless/b43legacy/main.c | 2 +- drivers/net/wireless/iwmc3200wifi/fw.c | 2 +- drivers/net/wireless/orinoco/main.c | 2 +- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- drivers/net/znet.c | 2 +- 23 files changed, 29 insertions(+), 27 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 241b185e656..81475ea3a71 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1958,7 +1958,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, IPG_CONVERGE_JIFFIES; lp->ipg_data.ipg = DEFAULT_IPG; lp->ipg_data.ipg_state = CSTATE; - }; + } /* display driver and device information */ diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 7e3cfbe89e3..c9957b7f17b 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -3704,7 +3704,7 @@ static int __devinit init_one(struct pci_dev *pdev, if (err) { dev_warn(&pdev->dev, "only %d net devices registered\n", i); err = 0; - }; + } if (cxgb4_debugfs_root) { adapter->debugfs_root = debugfs_create_dir(pci_name(pdev), diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 2f433fbfca0..5b087ebe632 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1560,7 +1560,7 @@ static void enic_notify_timer_start(struct enic *enic) default: /* Using intr for notification for INTx/MSI-X */ break; - }; + } } /* rtnl lock is held, process context */ diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h index c6f58482b76..f903a6a2dcb 100644 --- a/drivers/net/irda/via-ircc.h +++ b/drivers/net/irda/via-ircc.h @@ -210,7 +210,7 @@ static void DisableDmaChannel(unsigned int channel) break; default: break; - }; //Switch + } } static unsigned char ReadLPCReg(int iRegNum) diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 9ece1fd9889..b6c296f4b4d 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -538,7 +538,7 @@ static void veth_handle_ack(struct veth_lpevent *event) default: veth_error("Unknown ack type %d from LPAR %d.\n", event->base_event.xSubtype, rlp); - }; + } } static void veth_handle_int(struct veth_lpevent *event) @@ -584,7 +584,7 @@ static void veth_handle_int(struct veth_lpevent *event) default: veth_error("Unknown interrupt type %d from LPAR %d.\n", event->base_event.xSubtype, rlp); - }; + } } static void veth_handle_event(struct HvLpEvent *event) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 8ee661245af..0d7bc915635 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1157,7 +1157,7 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) default: /* bad value */ return IXGBE_ERR_CONFIG; - }; + } /* Move the flexible bytes to use the ethertype - shift 6 words */ fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT); @@ -1245,7 +1245,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) default: /* bad value */ return IXGBE_ERR_CONFIG; - }; + } /* Turn perfect match filtering on */ fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH; diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index b894b42a741..de65643b79a 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1292,7 +1292,7 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) udelay(5); ixgbe_standby_eeprom(hw); - }; + } /* * On some parts, SPI write time could vary from 0-20mSec on 3.3V @@ -1374,7 +1374,7 @@ static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, * EEPROM */ mask = mask >> 1; - }; + } /* We leave the "DI" bit set to "0" when we leave this routine. */ eec &= ~IXGBE_EEC_DI; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index bf84849600c..3f33870de21 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1013,7 +1013,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) cmd.data2 = i; status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0); - }; + } status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 7f999671c7b..ca59b4f026f 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1279,7 +1279,7 @@ void netxen_free_dummy_dma(struct netxen_adapter *adapter) if (--i == 0) break; - }; + } } if (i) { diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index b1f251da153..d47abb4e7eb 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -1009,7 +1009,7 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) netdev = card->netdev[i]; break; } - }; + } if (GELIC_PORT_MAX <= i) { pr_info("%s: unknown packet vid=%x\n", __func__, vid); goto refill; diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index ab9e3b785b5..0a0a6643cf3 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -297,7 +297,7 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, lcs = cs; cs = cs->next; comp->sls_o_searches++; - }; + } /* * Didn't find it -- re-use oldest cstate. Send an * uncompressed packet that tells the other side what diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index f0bcbe4bce4..71d4a0329d0 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2716,7 +2716,7 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) data->val_in); rc = 0; break; - }; + } return rc; } diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index ff32befd844..b6162fe2348 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -304,7 +304,7 @@ static int __devinit xl_probe(struct pci_dev *pdev, if ((i = pci_request_regions(pdev,"3c359"))) { return i ; - } ; + } /* * Allowing init_trdev to allocate the private data will align @@ -1773,7 +1773,9 @@ static void xl_wait_misr_flags(struct net_device *dev) if (readb(xl_mmio + MMIO_MACDATA) != 0) { /* Misr not clear */ for (i=0; i<6; i++) { writel(MEM_BYTE_READ | 0xDFFE0 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - while (readb(xl_mmio + MMIO_MACDATA) != 0 ) {} ; /* Empty Loop */ + while (readb(xl_mmio + MMIO_MACDATA) != 0) { + ; /* Empty Loop */ + } } } diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 4786497de03..e896ad0e8d2 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -177,7 +177,7 @@ static char __devinit *adapter_def(char type) case 0xD: return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter"; case 0xC: return "Auto 16/4 Adapter"; default: return "adapter (unknown type)"; - }; + } }; #define TRC_INIT 0x01 /* Trace initialization & PROBEs */ diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 74e94054ab1..8a27cbf19dd 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -666,7 +666,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, case TUN_TAP_DEV: skb->protocol = eth_type_trans(skb, tun->dev); break; - }; + } if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { pr_debug("GSO!\n"); diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 06daa9d6fee..f92924283d3 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1887,7 +1887,7 @@ static void velocity_error(struct velocity_info *vptr, int status) else netif_wake_queue(vptr->dev); - }; + } if (status & ISR_MIBFI) velocity_update_hw_mibs(vptr); if (status & ISR_LSTEI) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index eb415968698..d74bc5ff8e1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4085,7 +4085,7 @@ static int b43_phy_versioning(struct b43_wldev *dev) #endif default: unsupported = 1; - }; + } if (unsupported) { b43err(dev->wl, "FOUND UNSUPPORTED PHY " "(Analog %u, Type %u, Revision %u)\n", diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1ab8861dd43..60107b8e4c9 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2974,7 +2974,7 @@ static int b43legacy_phy_versioning(struct b43legacy_wldev *dev) break; default: unsupported = 1; - }; + } if (unsupported) { b43legacyerr(dev->wl, "FOUND UNSUPPORTED PHY " "(Analog %u, Type %u, Revision %u)\n", diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c index 49067092d33..6f1afe6bbc8 100644 --- a/drivers/net/wireless/iwmc3200wifi/fw.c +++ b/drivers/net/wireless/iwmc3200wifi/fw.c @@ -187,7 +187,7 @@ static int iwm_load_img(struct iwm_priv *iwm, const char *img_name) if (ret < 0) goto err_release_fw; opcode_idx++; - }; + } /* Read firmware version */ fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_SW_VER, 0); diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 62c6b2b37db..b0f233f1100 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -1958,7 +1958,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id) evstat = hermes_read_regn(hw, EVSTAT); events = evstat & hw->inten; - }; + } orinoco_unlock(priv, &flags); return IRQ_HANDLED; diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 2a6aa85cc6c..8f92dfcb08d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1355,7 +1355,7 @@ static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev, gf20_rate = gf40_rate = 0x0003; } break; - }; + } /* check for STAs not supporting greenfield mode */ if (any_sta_nongf) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cc4a54f571b..3ac0943b978 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -219,7 +219,7 @@ static void rt2800pci_start_queue(struct data_queue *queue) break; default: break; - }; + } } static void rt2800pci_kick_queue(struct data_queue *queue) diff --git a/drivers/net/znet.c b/drivers/net/znet.c index ec2800ff8d4..8b8881718f5 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -731,7 +731,7 @@ static void znet_rx(struct net_device *dev) cur_frame_end_offset -= ((count + 1)>>1) + 3; if (cur_frame_end_offset < 0) cur_frame_end_offset += RX_BUF_SIZE/2; - }; + } /* Now step forward through the list. */ do { -- cgit v1.2.3-70-g09d2 From 44d856665789288859b7aa47ca25933c1c6ab57d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 30 Jan 2011 22:14:49 +0100 Subject: can: at91_can: don't align struct definitions Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 74efb5a2ad4..8f15ae4c719 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -157,21 +157,21 @@ enum at91_mb_mode { #define AT91_IRQ_ALL (0x1fffffff) struct at91_priv { - struct can_priv can; /* must be the first member! */ - struct net_device *dev; - struct napi_struct napi; + struct can_priv can; /* must be the first member! */ + struct net_device *dev; + struct napi_struct napi; - void __iomem *reg_base; + void __iomem *reg_base; - u32 reg_sr; - unsigned int tx_next; - unsigned int tx_echo; - unsigned int rx_next; + u32 reg_sr; + unsigned int tx_next; + unsigned int tx_echo; + unsigned int rx_next; - struct clk *clk; - struct at91_can_data *pdata; + struct clk *clk; + struct at91_can_data *pdata; - canid_t mb0_id; + canid_t mb0_id; }; static struct can_bittiming_const at91_bittiming_const = { @@ -271,7 +271,7 @@ static void at91_setup_mailboxes(struct net_device *dev) /* reset acceptance mask and id register */ for (i = AT91_MB_RX_FIRST; i <= AT91_MB_RX_LAST; i++) { - at91_write(priv, AT91_MAM(i), 0x0 ); + at91_write(priv, AT91_MAM(i), 0x0); at91_write(priv, AT91_MID(i), AT91_MID_MIDE); } @@ -1231,11 +1231,11 @@ static int __devexit at91_can_remove(struct platform_device *pdev) } static struct platform_driver at91_can_driver = { - .probe = at91_can_probe, - .remove = __devexit_p(at91_can_remove), - .driver = { - .name = KBUILD_MODNAME, - .owner = THIS_MODULE, + .probe = at91_can_probe, + .remove = __devexit_p(at91_can_remove), + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, }, }; -- cgit v1.2.3-70-g09d2 From 5613fff2dc315e5f44623031cb62a29942548427 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 16 Apr 2011 13:25:15 +0200 Subject: can: at91_can: fix comment about priv->tx_next Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 8f15ae4c719..afd0f5d394b 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -375,7 +375,7 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state) * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits * encode the mailbox number, the upper 4 bits the mailbox priority: * - * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) || + * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) | * (mb - AT91_MB_TX_FIRST); * */ -- cgit v1.2.3-70-g09d2 From e14ee40bece891b5edccdd514112999ec423a448 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 21 Oct 2010 18:39:26 +0200 Subject: can: at91_can: don't copy data to rx'ed RTR frames Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/at91_can.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index afd0f5d394b..5358d705921 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -513,12 +513,14 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK; reg_msr = at91_read(priv, AT91_MSR(mb)); - if (reg_msr & AT91_MSR_MRTR) - cf->can_id |= CAN_RTR_FLAG; cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf); - *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb)); - *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb)); + if (reg_msr & AT91_MSR_MRTR) + cf->can_id |= CAN_RTR_FLAG; + else { + *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb)); + *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb)); + } /* allow RX of extended frames */ at91_write(priv, AT91_MID(mb), AT91_MID_MIDE); -- cgit v1.2.3-70-g09d2 From 9c2e0a6d2f7b7c76e0cbc42a8da99fd732f0fdfa Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 17:47:55 +0200 Subject: can: at91_can: let get_tx_* functions return unsigned int Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 5358d705921..716f22bf3d2 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -186,17 +186,17 @@ static struct can_bittiming_const at91_bittiming_const = { .brp_inc = 1, }; -static inline int get_tx_next_mb(const struct at91_priv *priv) +static inline unsigned int get_tx_next_mb(const struct at91_priv *priv) { return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; } -static inline int get_tx_next_prio(const struct at91_priv *priv) +static inline unsigned int get_tx_next_prio(const struct at91_priv *priv) { return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf; } -static inline int get_tx_echo_mb(const struct at91_priv *priv) +static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv) { return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; } -- cgit v1.2.3-70-g09d2 From 267cbe047cb4f6a3a6337029fc60862be1cf437d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 30 Apr 2011 20:46:12 +0200 Subject: can: at91_can: directly define AT91_MB_RX_LAST ...instead of deriving it from AT91_MB_RX_FIRST and AT91_MB_RX_NUM. This removes a level of computation, when switching the driver from compile time constants to runtime values. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 716f22bf3d2..9ce00fa90d9 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -47,11 +47,10 @@ * RX/TX Mailbox split * don't dare to touch */ -#define AT91_MB_RX_NUM 11 #define AT91_MB_TX_SHIFT 2 #define AT91_MB_RX_FIRST 1 -#define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) +#define AT91_MB_RX_LAST 11 #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) #define AT91_MB_RX_SPLIT 8 -- cgit v1.2.3-70-g09d2 From b049994d0f3a19c1706627117a7269ce5bd335ab Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 16:37:16 +0200 Subject: can: at91_can: rename AT91_MB_RX_MASK to AT91_IRQ_MB_RX ... and use it for AT91_NEXT_MB_MASK, AT91_IRQ_MB_RX and AT91_IRQ_MB_RX, too. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 9ce00fa90d9..86994845a1d 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -52,11 +52,11 @@ #define AT91_MB_RX_FIRST 1 #define AT91_MB_RX_LAST 11 -#define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) +#define AT91_MB_MASK(i) ((1 << (i)) - 1) #define AT91_MB_RX_SPLIT 8 #define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) -#define AT91_MB_RX_LOW_MASK (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT) & \ - ~AT91_MB_RX_MASK(AT91_MB_RX_FIRST)) +#define AT91_MB_RX_LOW_MASK (AT91_MB_MASK(AT91_MB_RX_SPLIT) & \ + ~AT91_MB_MASK(AT91_MB_RX_FIRST)) #define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) #define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) @@ -64,7 +64,7 @@ #define AT91_NEXT_PRIO_SHIFT (AT91_MB_TX_SHIFT) #define AT91_NEXT_PRIO_MASK (0xf << AT91_MB_TX_SHIFT) -#define AT91_NEXT_MB_MASK (AT91_MB_TX_NUM - 1) +#define AT91_NEXT_MB_MASK (AT91_MB_MASK(AT91_MB_TX_SHIFT)) #define AT91_NEXT_MASK ((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK) /* Common registers */ @@ -127,10 +127,10 @@ enum at91_mb_mode { }; /* Interrupt mask bits */ -#define AT91_IRQ_MB_RX ((1 << (AT91_MB_RX_LAST + 1)) \ - - (1 << AT91_MB_RX_FIRST)) -#define AT91_IRQ_MB_TX ((1 << (AT91_MB_TX_LAST + 1)) \ - - (1 << AT91_MB_TX_FIRST)) +#define AT91_IRQ_MB_RX (AT91_MB_MASK(AT91_MB_RX_LAST + 1) & \ + ~AT91_MB_MASK(AT91_MB_RX_FIRST)) +#define AT91_IRQ_MB_TX (AT91_MB_MASK(AT91_MB_TX_LAST + 1) & \ + ~AT91_MB_MASK(AT91_MB_TX_FIRST)) #define AT91_IRQ_MB_ALL (AT91_IRQ_MB_RX | AT91_IRQ_MB_TX) #define AT91_IRQ_ERRA (1 << 16) @@ -735,7 +735,7 @@ static int at91_poll(struct napi_struct *napi, int quota) if (work_done < quota) { /* enable IRQs for frame errors and all mailboxes >= rx_next */ u32 reg_ier = AT91_IRQ_ERR_FRAME; - reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_RX_MASK(priv->rx_next); + reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_MASK(priv->rx_next); napi_complete(napi); at91_write(priv, AT91_IER, reg_ier); -- cgit v1.2.3-70-g09d2 From 79008997e232ad1d871bb6fedfb7fbd77ea95af8 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 17:31:40 +0200 Subject: can: at91_can: convert derived mailbox constants into functions This is the first of two patches converting the at91_can driver from a compile time mailbox setup to a dynamic one. This patch converts all derived mailbox constants to functions. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 125 ++++++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 42 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 86994845a1d..900ff67ed7f 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -54,18 +54,7 @@ #define AT91_MB_MASK(i) ((1 << (i)) - 1) #define AT91_MB_RX_SPLIT 8 -#define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) -#define AT91_MB_RX_LOW_MASK (AT91_MB_MASK(AT91_MB_RX_SPLIT) & \ - ~AT91_MB_MASK(AT91_MB_RX_FIRST)) -#define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) -#define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) -#define AT91_MB_TX_LAST (AT91_MB_TX_FIRST + AT91_MB_TX_NUM - 1) - -#define AT91_NEXT_PRIO_SHIFT (AT91_MB_TX_SHIFT) -#define AT91_NEXT_PRIO_MASK (0xf << AT91_MB_TX_SHIFT) -#define AT91_NEXT_MB_MASK (AT91_MB_MASK(AT91_MB_TX_SHIFT)) -#define AT91_NEXT_MASK ((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK) /* Common registers */ enum at91_reg { @@ -127,12 +116,6 @@ enum at91_mb_mode { }; /* Interrupt mask bits */ -#define AT91_IRQ_MB_RX (AT91_MB_MASK(AT91_MB_RX_LAST + 1) & \ - ~AT91_MB_MASK(AT91_MB_RX_FIRST)) -#define AT91_IRQ_MB_TX (AT91_MB_MASK(AT91_MB_TX_LAST + 1) & \ - ~AT91_MB_MASK(AT91_MB_TX_FIRST)) -#define AT91_IRQ_MB_ALL (AT91_IRQ_MB_RX | AT91_IRQ_MB_TX) - #define AT91_IRQ_ERRA (1 << 16) #define AT91_IRQ_WARN (1 << 17) #define AT91_IRQ_ERRP (1 << 18) @@ -185,19 +168,77 @@ static struct can_bittiming_const at91_bittiming_const = { .brp_inc = 1, }; +static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv) +{ + return AT91_MB_RX_SPLIT - 1; +} + +static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv) +{ + return AT91_MB_MASK(AT91_MB_RX_SPLIT) & + ~AT91_MB_MASK(AT91_MB_RX_FIRST); +} + +static inline unsigned int get_mb_tx_num(const struct at91_priv *priv) +{ + return 1 << AT91_MB_TX_SHIFT; +} + +static inline unsigned int get_mb_tx_first(const struct at91_priv *priv) +{ + return AT91_MB_RX_LAST + 1; +} + +static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) +{ + return get_mb_tx_first(priv) + get_mb_tx_num(priv) - 1; +} + +static inline unsigned int get_next_prio_shift(const struct at91_priv *priv) +{ + return AT91_MB_TX_SHIFT; +} + +static inline unsigned int get_next_prio_mask(const struct at91_priv *priv) +{ + return 0xf << AT91_MB_TX_SHIFT; +} + +static inline unsigned int get_next_mb_mask(const struct at91_priv *priv) +{ + return AT91_MB_MASK(AT91_MB_TX_SHIFT); +} + +static inline unsigned int get_next_mask(const struct at91_priv *priv) +{ + return get_next_mb_mask(priv) | get_next_prio_mask(priv); +} + +static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv) +{ + return AT91_MB_MASK(AT91_MB_RX_LAST + 1) & + ~AT91_MB_MASK(AT91_MB_RX_FIRST); +} + +static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv) +{ + return AT91_MB_MASK(get_mb_tx_last(priv) + 1) & + ~AT91_MB_MASK(get_mb_tx_first(priv)); +} + static inline unsigned int get_tx_next_mb(const struct at91_priv *priv) { - return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; + return (priv->tx_next & get_next_mb_mask(priv)) + get_mb_tx_first(priv); } static inline unsigned int get_tx_next_prio(const struct at91_priv *priv) { - return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf; + return (priv->tx_next >> get_next_prio_shift(priv)) & 0xf; } static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv) { - return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST; + return (priv->tx_echo & get_next_mb_mask(priv)) + get_mb_tx_first(priv); } static inline u32 at91_read(const struct at91_priv *priv, enum at91_reg reg) @@ -275,7 +316,7 @@ static void at91_setup_mailboxes(struct net_device *dev) } /* The last 4 mailboxes are used for transmitting. */ - for (i = AT91_MB_TX_FIRST; i <= AT91_MB_TX_LAST; i++) + for (i = get_mb_tx_first(priv); i <= get_mb_tx_last(priv); i++) set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0); /* Reset tx and rx helper pointers */ @@ -335,7 +376,7 @@ static void at91_chip_start(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; /* Enable interrupts */ - reg_ier = AT91_IRQ_MB_RX | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME; + reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME; at91_write(priv, AT91_IDR, AT91_IRQ_ALL); at91_write(priv, AT91_IER, reg_ier); } @@ -416,7 +457,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) stats->tx_bytes += cf->can_dlc; /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ - can_put_echo_skb(skb, dev, mb - AT91_MB_TX_FIRST); + can_put_echo_skb(skb, dev, mb - get_mb_tx_first(priv)); /* * we have to stop the queue and deliver all messages in case @@ -429,7 +470,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) priv->tx_next++; if (!(at91_read(priv, AT91_MSR(get_tx_next_mb(priv))) & AT91_MSR_MRDY) || - (priv->tx_next & AT91_NEXT_MASK) == 0) + (priv->tx_next & get_next_mask(priv)) == 0) netif_stop_queue(dev); /* Enable interrupt for this mailbox */ @@ -446,7 +487,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) */ static inline void at91_activate_rx_low(const struct at91_priv *priv) { - u32 mask = AT91_MB_RX_LOW_MASK; + u32 mask = get_mb_rx_low_mask(priv); at91_write(priv, AT91_TCR, mask); } @@ -611,23 +652,23 @@ static int at91_poll_rx(struct net_device *dev, int quota) unsigned int mb; int received = 0; - if (priv->rx_next > AT91_MB_RX_LOW_LAST && - reg_sr & AT91_MB_RX_LOW_MASK) + if (priv->rx_next > get_mb_rx_low_last(priv) && + reg_sr & get_mb_rx_low_mask(priv)) netdev_info(dev, "order of incoming frames cannot be guaranteed\n"); again: - for (mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, priv->rx_next); - mb < AT91_MB_RX_LAST + 1 && quota > 0; + for (mb = find_next_bit(addr, get_mb_tx_first(priv), priv->rx_next); + mb < get_mb_tx_first(priv) && quota > 0; reg_sr = at91_read(priv, AT91_SR), - mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, ++priv->rx_next)) { + mb = find_next_bit(addr, get_mb_tx_first(priv), ++priv->rx_next)) { at91_read_msg(dev, mb); /* reactivate mailboxes */ - if (mb == AT91_MB_RX_LOW_LAST) + if (mb == get_mb_rx_low_last(priv)) /* all lower mailboxed, if just finished it */ at91_activate_rx_low(priv); - else if (mb > AT91_MB_RX_LOW_LAST) + else if (mb > get_mb_rx_low_last(priv)) /* only the mailbox we read */ at91_activate_rx_mb(priv, mb); @@ -636,7 +677,7 @@ static int at91_poll_rx(struct net_device *dev, int quota) } /* upper group completed, look again in lower */ - if (priv->rx_next > AT91_MB_RX_LOW_LAST && + if (priv->rx_next > get_mb_rx_low_last(priv) && quota > 0 && mb > AT91_MB_RX_LAST) { priv->rx_next = AT91_MB_RX_FIRST; goto again; @@ -721,7 +762,7 @@ static int at91_poll(struct napi_struct *napi, int quota) u32 reg_sr = at91_read(priv, AT91_SR); int work_done = 0; - if (reg_sr & AT91_IRQ_MB_RX) + if (reg_sr & get_irq_mb_rx(priv)) work_done += at91_poll_rx(dev, quota - work_done); /* @@ -735,7 +776,7 @@ static int at91_poll(struct napi_struct *napi, int quota) if (work_done < quota) { /* enable IRQs for frame errors and all mailboxes >= rx_next */ u32 reg_ier = AT91_IRQ_ERR_FRAME; - reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_MASK(priv->rx_next); + reg_ier |= get_irq_mb_rx(priv) & ~AT91_MB_MASK(priv->rx_next); napi_complete(napi); at91_write(priv, AT91_IER, reg_ier); @@ -784,7 +825,7 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr) if (likely(reg_msr & AT91_MSR_MRDY && ~reg_msr & AT91_MSR_MABT)) { /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ - can_get_echo_skb(dev, mb - AT91_MB_TX_FIRST); + can_get_echo_skb(dev, mb - get_mb_tx_first(priv)); dev->stats.tx_packets++; } } @@ -794,8 +835,8 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr) * we get a TX int for the last can frame directly before a * wrap around. */ - if ((priv->tx_next & AT91_NEXT_MASK) != 0 || - (priv->tx_echo & AT91_NEXT_MASK) == 0) + if ((priv->tx_next & get_next_mask(priv)) != 0 || + (priv->tx_echo & get_next_mask(priv)) == 0) netif_wake_queue(dev); } @@ -969,19 +1010,19 @@ static irqreturn_t at91_irq(int irq, void *dev_id) handled = IRQ_HANDLED; /* Receive or error interrupt? -> napi */ - if (reg_sr & (AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME)) { + if (reg_sr & (get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME)) { /* * The error bits are clear on read, * save for later use. */ priv->reg_sr = reg_sr; at91_write(priv, AT91_IDR, - AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME); + get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME); napi_schedule(&priv->napi); } /* Transmission complete interrupt */ - if (reg_sr & AT91_IRQ_MB_TX) + if (reg_sr & get_irq_mb_tx(priv)) at91_irq_tx(dev, reg_sr); at91_irq_err(dev); @@ -1158,7 +1199,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev) goto exit_release; } - dev = alloc_candev(sizeof(struct at91_priv), AT91_MB_TX_NUM); + dev = alloc_candev(sizeof(struct at91_priv), 1 << AT91_MB_TX_SHIFT); if (!dev) { err = -ENOMEM; goto exit_iounmap; -- cgit v1.2.3-70-g09d2 From d3d47264a364aa3adcbb485471dbf9f693fb4216 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 3 May 2011 17:41:09 +0200 Subject: can: at91_can: add id_table and convert prime mailbox constats to functions This is the second of two patches converting the at91_can driver from a compile time mailbox setup to a dynamic one. This patch first adds a id_table to the platform driver. Depending on the driver_data the constants for the mailbox setup is selected. Then all remaining prime mailbox constants are converted to functions, using the run time selected mailbox constants. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 137 ++++++++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 38 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 900ff67ed7f..248e03fec03 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -41,20 +41,7 @@ #include -#define AT91_NAPI_WEIGHT 11 - -/* - * RX/TX Mailbox split - * don't dare to touch - */ -#define AT91_MB_TX_SHIFT 2 - -#define AT91_MB_RX_FIRST 1 -#define AT91_MB_RX_LAST 11 - #define AT91_MB_MASK(i) ((1 << (i)) - 1) -#define AT91_MB_RX_SPLIT 8 - /* Common registers */ enum at91_reg { @@ -138,6 +125,18 @@ enum at91_mb_mode { #define AT91_IRQ_ALL (0x1fffffff) +enum at91_devtype { + AT91_DEVTYPE_SAM9263, +}; + +struct at91_devtype_data { + unsigned int rx_first; + unsigned int rx_split; + unsigned int rx_last; + unsigned int tx_shift; + enum at91_devtype type; +}; + struct at91_priv { struct can_priv can; /* must be the first member! */ struct net_device *dev; @@ -149,6 +148,7 @@ struct at91_priv { unsigned int tx_next; unsigned int tx_echo; unsigned int rx_next; + struct at91_devtype_data devtype_data; struct clk *clk; struct at91_can_data *pdata; @@ -156,6 +156,15 @@ struct at91_priv { canid_t mb0_id; }; +static const struct at91_devtype_data at91_devtype_data[] __devinitconst = { + [AT91_DEVTYPE_SAM9263] = { + .rx_first = 1, + .rx_split = 8, + .rx_last = 11, + .tx_shift = 2, + }, +}; + static struct can_bittiming_const at91_bittiming_const = { .name = KBUILD_MODNAME, .tseg1_min = 4, @@ -168,25 +177,58 @@ static struct can_bittiming_const at91_bittiming_const = { .brp_inc = 1, }; +#define AT91_IS(_model) \ +static inline int at91_is_sam##_model(const struct at91_priv *priv) \ +{ \ + return priv->devtype_data.type == AT91_DEVTYPE_SAM##_model; \ +} + +AT91_IS(9263); + +static inline unsigned int get_mb_rx_first(const struct at91_priv *priv) +{ + return priv->devtype_data.rx_first; +} + +static inline unsigned int get_mb_rx_last(const struct at91_priv *priv) +{ + return priv->devtype_data.rx_last; +} + +static inline unsigned int get_mb_rx_split(const struct at91_priv *priv) +{ + return priv->devtype_data.rx_split; +} + +static inline unsigned int get_mb_rx_num(const struct at91_priv *priv) +{ + return get_mb_rx_last(priv) - get_mb_rx_first(priv) + 1; +} + static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv) { - return AT91_MB_RX_SPLIT - 1; + return get_mb_rx_split(priv) - 1; } static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv) { - return AT91_MB_MASK(AT91_MB_RX_SPLIT) & - ~AT91_MB_MASK(AT91_MB_RX_FIRST); + return AT91_MB_MASK(get_mb_rx_split(priv)) & + ~AT91_MB_MASK(get_mb_rx_first(priv)); +} + +static inline unsigned int get_mb_tx_shift(const struct at91_priv *priv) +{ + return priv->devtype_data.tx_shift; } static inline unsigned int get_mb_tx_num(const struct at91_priv *priv) { - return 1 << AT91_MB_TX_SHIFT; + return 1 << get_mb_tx_shift(priv); } static inline unsigned int get_mb_tx_first(const struct at91_priv *priv) { - return AT91_MB_RX_LAST + 1; + return get_mb_rx_last(priv) + 1; } static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) @@ -196,17 +238,17 @@ static inline unsigned int get_mb_tx_last(const struct at91_priv *priv) static inline unsigned int get_next_prio_shift(const struct at91_priv *priv) { - return AT91_MB_TX_SHIFT; + return get_mb_tx_shift(priv); } static inline unsigned int get_next_prio_mask(const struct at91_priv *priv) { - return 0xf << AT91_MB_TX_SHIFT; + return 0xf << get_mb_tx_shift(priv); } static inline unsigned int get_next_mb_mask(const struct at91_priv *priv) { - return AT91_MB_MASK(AT91_MB_TX_SHIFT); + return AT91_MB_MASK(get_mb_tx_shift(priv)); } static inline unsigned int get_next_mask(const struct at91_priv *priv) @@ -216,8 +258,8 @@ static inline unsigned int get_next_mask(const struct at91_priv *priv) static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv) { - return AT91_MB_MASK(AT91_MB_RX_LAST + 1) & - ~AT91_MB_MASK(AT91_MB_RX_FIRST); + return AT91_MB_MASK(get_mb_rx_last(priv) + 1) & + ~AT91_MB_MASK(get_mb_rx_first(priv)); } static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv) @@ -299,18 +341,18 @@ static void at91_setup_mailboxes(struct net_device *dev) * overflow. */ reg_mid = at91_can_id_to_reg_mid(priv->mb0_id); - for (i = 0; i < AT91_MB_RX_FIRST; i++) { + for (i = 0; i < get_mb_rx_first(priv); i++) { set_mb_mode(priv, i, AT91_MB_MODE_DISABLED); at91_write(priv, AT91_MID(i), reg_mid); at91_write(priv, AT91_MCR(i), 0x0); /* clear dlc */ } - for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) + for (i = get_mb_rx_first(priv); i < get_mb_rx_last(priv); i++) set_mb_mode(priv, i, AT91_MB_MODE_RX); - set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); + set_mb_mode(priv, get_mb_rx_last(priv), AT91_MB_MODE_RX_OVRWR); /* reset acceptance mask and id register */ - for (i = AT91_MB_RX_FIRST; i <= AT91_MB_RX_LAST; i++) { + for (i = get_mb_rx_first(priv); i <= get_mb_rx_last(priv); i++) { at91_write(priv, AT91_MAM(i), 0x0); at91_write(priv, AT91_MID(i), AT91_MID_MIDE); } @@ -321,7 +363,7 @@ static void at91_setup_mailboxes(struct net_device *dev) /* Reset tx and rx helper pointers */ priv->tx_next = priv->tx_echo = 0; - priv->rx_next = AT91_MB_RX_FIRST; + priv->rx_next = get_mb_rx_first(priv); } static int at91_set_bittiming(struct net_device *dev) @@ -415,8 +457,8 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state) * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits * encode the mailbox number, the upper 4 bits the mailbox priority: * - * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) | - * (mb - AT91_MB_TX_FIRST); + * priv->tx_next = (prio << get_next_prio_shift(priv)) | + * (mb - get_mb_tx_first(priv)); * */ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) @@ -565,7 +607,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, /* allow RX of extended frames */ at91_write(priv, AT91_MID(mb), AT91_MID_MIDE); - if (unlikely(mb == AT91_MB_RX_LAST && reg_msr & AT91_MSR_MMI)) + if (unlikely(mb == get_mb_rx_last(priv) && reg_msr & AT91_MSR_MMI)) at91_rx_overflow_err(dev); } @@ -603,8 +645,9 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) * * Theory of Operation: * - * 11 of the 16 mailboxes on the chip are reserved for RX. we split - * them into 2 groups. The lower group holds 7 and upper 4 mailboxes. + * About 3/4 of the mailboxes (get_mb_rx_first()...get_mb_rx_last()) + * on the chip are reserved for RX. We split them into 2 groups. The + * lower group ranges from get_mb_rx_first() to get_mb_rx_low_last(). * * Like it or not, but the chip always saves a received CAN message * into the first free mailbox it finds (starting with the @@ -678,8 +721,8 @@ static int at91_poll_rx(struct net_device *dev, int quota) /* upper group completed, look again in lower */ if (priv->rx_next > get_mb_rx_low_last(priv) && - quota > 0 && mb > AT91_MB_RX_LAST) { - priv->rx_next = AT91_MB_RX_FIRST; + quota > 0 && mb > get_mb_rx_last(priv)) { + priv->rx_next = get_mb_rx_first(priv); goto again; } @@ -1165,6 +1208,8 @@ static struct attribute_group at91_sysfs_attr_group = { static int __devinit at91_can_probe(struct platform_device *pdev) { + const struct at91_devtype_data *devtype_data; + enum at91_devtype devtype; struct net_device *dev; struct at91_priv *priv; struct resource *res; @@ -1172,6 +1217,9 @@ static int __devinit at91_can_probe(struct platform_device *pdev) void __iomem *addr; int err, irq; + devtype = pdev->id_entry->driver_data; + devtype_data = &at91_devtype_data[devtype]; + clk = clk_get(&pdev->dev, "can_clk"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "no clock defined\n"); @@ -1199,7 +1247,8 @@ static int __devinit at91_can_probe(struct platform_device *pdev) goto exit_release; } - dev = alloc_candev(sizeof(struct at91_priv), 1 << AT91_MB_TX_SHIFT); + dev = alloc_candev(sizeof(struct at91_priv), + 1 << devtype_data->tx_shift); if (!dev) { err = -ENOMEM; goto exit_iounmap; @@ -1216,13 +1265,15 @@ static int __devinit at91_can_probe(struct platform_device *pdev) priv->can.do_set_mode = at91_set_mode; priv->can.do_get_berr_counter = at91_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; - priv->reg_base = addr; priv->dev = dev; + priv->reg_base = addr; + priv->devtype_data = *devtype_data; + priv->devtype_data.type = devtype; priv->clk = clk; priv->pdata = pdev->dev.platform_data; priv->mb0_id = 0x7ff; - netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT); + netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv)); dev_set_drvdata(&pdev->dev, dev); SET_NETDEV_DEV(dev, &pdev->dev); @@ -1272,6 +1323,15 @@ static int __devexit at91_can_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id at91_can_id_table[] = { + { + .name = "at91_can", + .driver_data = AT91_DEVTYPE_SAM9263, + }, { + /* sentinel */ + } +}; + static struct platform_driver at91_can_driver = { .probe = at91_can_probe, .remove = __devexit_p(at91_can_remove), @@ -1279,6 +1339,7 @@ static struct platform_driver at91_can_driver = { .name = KBUILD_MODNAME, .owner = THIS_MODULE, }, + .id_table = at91_can_id_table, }; static int __init at91_can_module_init(void) -- cgit v1.2.3-70-g09d2 From 07a648e668aa7f7c94d41d8d2e4ad53b609e391d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 1 Jun 2011 00:20:17 +0200 Subject: can: at91_can: register mb0 sysfs entry only on at91sam9263 This patch prepares the driver for the at91sam9X5 processors, which don't have the mb0 bug. (See commit 3a5655a5b545e9647c3437473ee3d815fe1b9050 for more details.) Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 248e03fec03..2b972812b2d 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1257,7 +1257,6 @@ static int __devinit at91_can_probe(struct platform_device *pdev) dev->netdev_ops = &at91_netdev_ops; dev->irq = irq; dev->flags |= IFF_ECHO; - dev->sysfs_groups[0] = &at91_sysfs_attr_group; priv = netdev_priv(dev); priv->can.clock.freq = clk_get_rate(clk); @@ -1275,6 +1274,9 @@ static int __devinit at91_can_probe(struct platform_device *pdev) netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv)); + if (at91_is_sam9263(priv)) + dev->sysfs_groups[0] = &at91_sysfs_attr_group; + dev_set_drvdata(&pdev->dev, dev); SET_NETDEV_DEV(dev, &pdev->dev); -- cgit v1.2.3-70-g09d2 From 6388b39614208d63661607f45157e3326548eb62 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 17 Apr 2011 00:08:45 +0200 Subject: can: at91_can: add support for the AT91SAM9X5 SOCs The AT91SAM9X5 SOCs have a similar CAN core, but they only have 8 compared to 16 mailboxes on the AT91SAM9263 SOC. Another difference is that the bits defining the state of the CAN core are cleared on read, thus the driver has to derive the state by looking at the error counters. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c | 69 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 2b972812b2d..121ede663e2 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -127,6 +127,7 @@ enum at91_mb_mode { enum at91_devtype { AT91_DEVTYPE_SAM9263, + AT91_DEVTYPE_SAM9X5, }; struct at91_devtype_data { @@ -163,6 +164,12 @@ static const struct at91_devtype_data at91_devtype_data[] __devinitconst = { .rx_last = 11, .tx_shift = 2, }, + [AT91_DEVTYPE_SAM9X5] = { + .rx_first = 0, + .rx_split = 4, + .rx_last = 5, + .tx_shift = 1, + }, }; static struct can_bittiming_const at91_bittiming_const = { @@ -184,6 +191,7 @@ static inline int at91_is_sam##_model(const struct at91_priv *priv) \ } AT91_IS(9263); +AT91_IS(9X5); static inline unsigned int get_mb_rx_first(const struct at91_priv *priv) { @@ -991,6 +999,29 @@ static void at91_irq_err_state(struct net_device *dev, at91_write(priv, AT91_IER, reg_ier); } +static int at91_get_state_by_bec(const struct net_device *dev, + enum can_state *state) +{ + struct can_berr_counter bec; + int err; + + err = at91_get_berr_counter(dev, &bec); + if (err) + return err; + + if (bec.txerr < 96 && bec.rxerr < 96) + *state = CAN_STATE_ERROR_ACTIVE; + else if (bec.txerr < 128 && bec.rxerr < 128) + *state = CAN_STATE_ERROR_WARNING; + else if (bec.txerr < 256 && bec.rxerr < 256) + *state = CAN_STATE_ERROR_PASSIVE; + else + *state = CAN_STATE_BUS_OFF; + + return 0; +} + + static void at91_irq_err(struct net_device *dev) { struct at91_priv *priv = netdev_priv(dev); @@ -998,21 +1029,28 @@ static void at91_irq_err(struct net_device *dev) struct can_frame *cf; enum can_state new_state; u32 reg_sr; + int err; - reg_sr = at91_read(priv, AT91_SR); - - /* we need to look at the unmasked reg_sr */ - if (unlikely(reg_sr & AT91_IRQ_BOFF)) - new_state = CAN_STATE_BUS_OFF; - else if (unlikely(reg_sr & AT91_IRQ_ERRP)) - new_state = CAN_STATE_ERROR_PASSIVE; - else if (unlikely(reg_sr & AT91_IRQ_WARN)) - new_state = CAN_STATE_ERROR_WARNING; - else if (likely(reg_sr & AT91_IRQ_ERRA)) - new_state = CAN_STATE_ERROR_ACTIVE; - else { - netdev_err(dev, "BUG! hardware in undefined state\n"); - return; + if (at91_is_sam9263(priv)) { + reg_sr = at91_read(priv, AT91_SR); + + /* we need to look at the unmasked reg_sr */ + if (unlikely(reg_sr & AT91_IRQ_BOFF)) + new_state = CAN_STATE_BUS_OFF; + else if (unlikely(reg_sr & AT91_IRQ_ERRP)) + new_state = CAN_STATE_ERROR_PASSIVE; + else if (unlikely(reg_sr & AT91_IRQ_WARN)) + new_state = CAN_STATE_ERROR_WARNING; + else if (likely(reg_sr & AT91_IRQ_ERRA)) + new_state = CAN_STATE_ERROR_ACTIVE; + else { + netdev_err(dev, "BUG! hardware in undefined state\n"); + return; + } + } else { + err = at91_get_state_by_bec(dev, &new_state); + if (err) + return; } /* state hasn't changed */ @@ -1329,6 +1367,9 @@ static const struct platform_device_id at91_can_id_table[] = { { .name = "at91_can", .driver_data = AT91_DEVTYPE_SAM9263, + }, { + .name = "at91sam9x5_can", + .driver_data = AT91_DEVTYPE_SAM9X5, }, { /* sentinel */ } -- cgit v1.2.3-70-g09d2 From b9e379bccda6913f7baece42cd249824c0758b97 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 26 Apr 2011 15:05:59 +0200 Subject: net/can: allow CAN_AT91 on AT91SAM9X5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 1d699e3df54..bbf06f77ee8 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -58,9 +58,10 @@ config CAN_CALC_BITTIMING config CAN_AT91 tristate "Atmel AT91 onchip CAN controller" - depends on CAN_DEV && ARCH_AT91SAM9263 + depends on CAN_DEV && (ARCH_AT91SAM9263 || ARCH_AT91SAM9X5) ---help--- - This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. + This is a driver for the SoC CAN controller in Atmel's AT91SAM9263 + and AT91SAM9X5 processors. config CAN_TI_HECC depends on CAN_DEV && ARCH_OMAP3 -- cgit v1.2.3-70-g09d2 From 8d13e670d3fb83f4668c9e37196c3bbf5b9f094c Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Mon, 6 Jun 2011 04:27:16 +0000 Subject: macvlan: add VLAN filters to lowerdev Stacking VLANs on top of the macvlan device does not work if the lowerdev device is using vlan filters set by NETIF_F_HW_VLAN_FILTER. Add ndo ops to pass vlan calls to lowerdev. Signed-off-by: John Fastabend Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index d6aeaa5f25e..cc67cbe670c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -414,7 +414,8 @@ static struct lock_class_key macvlan_netdev_addr_lock_key; #define MACVLAN_FEATURES \ (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \ - NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM) + NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \ + NETIF_F_HW_VLAN_FILTER) #define MACVLAN_STATE_MASK \ ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) @@ -509,6 +510,39 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, return stats; } +static void macvlan_vlan_rx_register(struct net_device *dev, + struct vlan_group *grp) +{ + struct macvlan_dev *vlan = netdev_priv(dev); + struct net_device *lowerdev = vlan->lowerdev; + const struct net_device_ops *ops = lowerdev->netdev_ops; + + if (ops->ndo_vlan_rx_register) + ops->ndo_vlan_rx_register(lowerdev, grp); +} + +static void macvlan_vlan_rx_add_vid(struct net_device *dev, + unsigned short vid) +{ + struct macvlan_dev *vlan = netdev_priv(dev); + struct net_device *lowerdev = vlan->lowerdev; + const struct net_device_ops *ops = lowerdev->netdev_ops; + + if (ops->ndo_vlan_rx_add_vid) + ops->ndo_vlan_rx_add_vid(lowerdev, vid); +} + +static void macvlan_vlan_rx_kill_vid(struct net_device *dev, + unsigned short vid) +{ + struct macvlan_dev *vlan = netdev_priv(dev); + struct net_device *lowerdev = vlan->lowerdev; + const struct net_device_ops *ops = lowerdev->netdev_ops; + + if (ops->ndo_vlan_rx_kill_vid) + ops->ndo_vlan_rx_kill_vid(lowerdev, vid); +} + static void macvlan_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { @@ -541,6 +575,9 @@ static const struct net_device_ops macvlan_netdev_ops = { .ndo_set_multicast_list = macvlan_set_multicast_list, .ndo_get_stats64 = macvlan_dev_get_stats64, .ndo_validate_addr = eth_validate_addr, + .ndo_vlan_rx_register = macvlan_vlan_rx_register, + .ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid, }; void macvlan_common_setup(struct net_device *dev) -- cgit v1.2.3-70-g09d2 From c97c894dc7bcae28d0308dbcd010185079de4a28 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Fri, 3 Jun 2011 14:35:17 +0000 Subject: enic: Add support for MTU change via port profile on a dynamic vnic enic driver gets MTU change notifications for MTU changes in the port profile associated to a dynamic vnic. This patch adds support in enic driver to set new MTU on the dynamic vnic and dynamically adjust its buffers with new MTU size in response to such notifications. Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 3 +- drivers/net/enic/enic_main.c | 71 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 38b351c7b97..e0d2ad181bb 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.13" +#define DRV_VERSION "2.1.1.16" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -74,6 +74,7 @@ struct enic { struct vnic_dev *vdev; struct timer_list notify_timer; struct work_struct reset; + struct work_struct change_mtu_work; struct msix_entry msix_entry[ENIC_INTR_MAX]; struct enic_msix_entry msix[ENIC_INTR_MAX]; u32 msg_enable; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 5b087ebe632..1daf79b3616 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -423,11 +423,18 @@ static void enic_mtu_check(struct enic *enic) if (mtu && mtu != enic->port_mtu) { enic->port_mtu = mtu; - if (mtu < netdev->mtu) - netdev_warn(netdev, - "interface MTU (%d) set higher " - "than switch port MTU (%d)\n", - netdev->mtu, mtu); + if (enic_is_dynamic(enic)) { + mtu = max_t(int, ENIC_MIN_MTU, + min_t(int, ENIC_MAX_MTU, mtu)); + if (mtu != netdev->mtu) + schedule_work(&enic->change_mtu_work); + } else { + if (mtu < netdev->mtu) + netdev_warn(netdev, + "interface MTU (%d) set higher " + "than switch port MTU (%d)\n", + netdev->mtu, mtu); + } } } @@ -1688,6 +1695,9 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu) if (new_mtu < ENIC_MIN_MTU || new_mtu > ENIC_MAX_MTU) return -EINVAL; + if (enic_is_dynamic(enic)) + return -EOPNOTSUPP; + if (running) enic_stop(netdev); @@ -1704,6 +1714,55 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu) return 0; } +static void enic_change_mtu_work(struct work_struct *work) +{ + struct enic *enic = container_of(work, struct enic, change_mtu_work); + struct net_device *netdev = enic->netdev; + int new_mtu = vnic_dev_mtu(enic->vdev); + int err; + unsigned int i; + + new_mtu = max_t(int, ENIC_MIN_MTU, min_t(int, ENIC_MAX_MTU, new_mtu)); + + rtnl_lock(); + + /* Stop RQ */ + del_timer_sync(&enic->notify_timer); + + for (i = 0; i < enic->rq_count; i++) + napi_disable(&enic->napi[i]); + + vnic_intr_mask(&enic->intr[0]); + enic_synchronize_irqs(enic); + err = vnic_rq_disable(&enic->rq[0]); + if (err) { + netdev_err(netdev, "Unable to disable RQ.\n"); + return; + } + vnic_rq_clean(&enic->rq[0], enic_free_rq_buf); + vnic_cq_clean(&enic->cq[0]); + vnic_intr_clean(&enic->intr[0]); + + /* Fill RQ with new_mtu-sized buffers */ + netdev->mtu = new_mtu; + vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf); + /* Need at least one buffer on ring to get going */ + if (vnic_rq_desc_used(&enic->rq[0]) == 0) { + netdev_err(netdev, "Unable to alloc receive buffers.\n"); + return; + } + + /* Start RQ */ + vnic_rq_enable(&enic->rq[0]); + napi_enable(&enic->napi[0]); + vnic_intr_unmask(&enic->intr[0]); + enic_notify_timer_start(enic); + + rtnl_unlock(); + + netdev_info(netdev, "interface MTU set as %d\n", netdev->mtu); +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void enic_poll_controller(struct net_device *netdev) { @@ -2345,6 +2404,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, enic->notify_timer.data = (unsigned long)enic; INIT_WORK(&enic->reset, enic_reset); + INIT_WORK(&enic->change_mtu_work, enic_change_mtu_work); for (i = 0; i < enic->wq_count; i++) spin_lock_init(&enic->wq_lock[i]); @@ -2427,6 +2487,7 @@ static void __devexit enic_remove(struct pci_dev *pdev) struct enic *enic = netdev_priv(netdev); cancel_work_sync(&enic->reset); + cancel_work_sync(&enic->change_mtu_work); unregister_netdev(netdev); enic_dev_deinit(enic); vnic_dev_close(enic->vdev); -- cgit v1.2.3-70-g09d2 From 324dd96d2b022595b9fc8f24305b3ab770cc63b9 Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Sun, 5 Jun 2011 14:44:13 +0000 Subject: qlge: remove unecessary if statement the code always returns 'status' regardless, so if(status) check is unecessary. Signed-off-by: Greg Dietsche Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_ethtool.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 19b00fa0eaf..9b67bfea035 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c @@ -650,8 +650,6 @@ static int ql_set_pauseparam(struct net_device *netdev, return -EINVAL; status = ql_mb_set_port_cfg(qdev); - if (status) - return status; return status; } -- cgit v1.2.3-70-g09d2 From aedfebbaa7a4883dc568d8d32b7b32a0f9833f41 Mon Sep 17 00:00:00 2001 From: Selvin Xavier Date: Mon, 6 Jun 2011 02:27:13 +0000 Subject: be2net: Fix Rx pause counter for lancer Fixed Rx pause counter for Lancer. Swapping hi and lo words. Signed-off-by: Selvin Xavier Signed-off-by: Padmanabh Ratnakar Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 5824c95c784..9ba197b0978 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -362,8 +362,8 @@ static void populate_lancer_stats(struct be_adapter *adapter) drvs->rx_priority_pause_frames = 0; drvs->pmem_fifo_overflow_drop = 0; drvs->rx_pause_frames = - make_64bit_val(pport_stats->rx_pause_frames_lo, - pport_stats->rx_pause_frames_hi); + make_64bit_val(pport_stats->rx_pause_frames_hi, + pport_stats->rx_pause_frames_lo); drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi, pport_stats->rx_crc_errors_lo); drvs->rx_control_frames = -- cgit v1.2.3-70-g09d2 From a6b7a407865aab9f849dd99a71072b7cd1175116 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Jun 2011 10:43:46 +0000 Subject: net: remove interrupt.h inclusion from netdevice.h * remove interrupt.g inclusion from netdevice.h -- not needed * fixup fallout, add interrupt.h and hardirq.h back where needed. Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- drivers/atm/eni.h | 1 + drivers/atm/firestream.c | 1 + drivers/atm/horizon.c | 1 + drivers/atm/idt77252.c | 1 + drivers/atm/iphase.c | 1 + drivers/atm/zatm.c | 1 + drivers/infiniband/hw/amso1100/c2.c | 1 + drivers/infiniband/ulp/iser/iscsi_iser.h | 1 + drivers/isdn/hardware/mISDN/avmfritz.c | 1 + drivers/isdn/hardware/mISDN/hfcmulti.c | 1 + drivers/isdn/hardware/mISDN/hfcpci.c | 1 + drivers/isdn/hardware/mISDN/mISDNinfineon.c | 1 + drivers/isdn/hardware/mISDN/mISDNipac.c | 1 + drivers/isdn/hardware/mISDN/netjet.c | 1 + drivers/isdn/hardware/mISDN/speedfax.c | 1 + drivers/isdn/hardware/mISDN/w6692.c | 1 + drivers/isdn/hisax/hisax.h | 1 + drivers/isdn/hisax/hisax_fcpcipnp.c | 1 + drivers/media/dvb/b2c2/flexcop-common.h | 1 + drivers/media/dvb/dm1105/dm1105.c | 1 + drivers/media/dvb/mantis/mantis_common.h | 1 + drivers/media/dvb/pluto2/pluto2.c | 1 + drivers/net/3c503.c | 1 + drivers/net/8139cp.c | 1 + drivers/net/8139too.c | 1 + drivers/net/8390.h | 1 + drivers/net/ac3200.c | 1 + drivers/net/acenic.h | 1 + drivers/net/amd8111e.c | 1 + drivers/net/arcnet/arc-rimi.c | 1 + drivers/net/arcnet/com20020-isa.c | 1 + drivers/net/arcnet/com20020-pci.c | 1 + drivers/net/arcnet/com20020.c | 1 + drivers/net/arcnet/com90io.c | 1 + drivers/net/arcnet/com90xx.c | 1 + drivers/net/arm/at91_ether.c | 1 + drivers/net/arm/ep93xx_eth.c | 1 + drivers/net/arm/ks8695net.c | 1 + drivers/net/atl1c/atl1c.h | 1 + drivers/net/atl1e/atl1e.h | 1 + drivers/net/b44.c | 1 + drivers/net/bmac.c | 1 + drivers/net/bnx2x/bnx2x_cmn.c | 1 + drivers/net/caif/caif_serial.c | 1 + drivers/net/can/sja1000/sja1000.h | 1 + drivers/net/cassini.c | 1 + drivers/net/cxgb4vf/adapter.h | 1 + drivers/net/dm9000.c | 1 + drivers/net/dnet.c | 1 + drivers/net/e100.c | 2 ++ drivers/net/e1000e/ethtool.c | 1 + drivers/net/e1000e/netdev.c | 1 + drivers/net/e2100.c | 1 + drivers/net/enic/enic_main.c | 1 + drivers/net/es3210.c | 1 + drivers/net/ethoc.c | 1 + drivers/net/fec_mpc52xx.c | 1 + drivers/net/greth.c | 1 + drivers/net/hamradio/baycom_ser_fdx.c | 1 + drivers/net/hamradio/baycom_ser_hdx.c | 1 + drivers/net/hp-plus.c | 1 + drivers/net/hp.c | 1 + drivers/net/ibmveth.c | 1 + drivers/net/ifb.c | 1 + drivers/net/ipg.c | 1 + drivers/net/irda/ali-ircc.c | 1 + drivers/net/irda/donauboe.c | 1 + drivers/net/irda/nsc-ircc.c | 1 + drivers/net/irda/pxaficp_ir.c | 1 + drivers/net/irda/sir_dev.c | 1 + drivers/net/irda/smsc-ircc2.c | 1 + drivers/net/irda/via-ircc.c | 1 + drivers/net/irda/vlsi_ir.c | 1 + drivers/net/irda/w83977af_ir.c | 1 + drivers/net/ixgbe/ixgbe_ethtool.c | 1 + drivers/net/ixgbe/ixgbe_main.c | 1 + drivers/net/ixp2000/ixpdev.c | 1 + drivers/net/jme.h | 1 + drivers/net/ks8842.c | 1 + drivers/net/ks8851.c | 1 + drivers/net/ks8851_mll.c | 1 + drivers/net/ksz884x.c | 1 + drivers/net/lne390.c | 1 + drivers/net/macb.c | 1 + drivers/net/mace.c | 1 + drivers/net/netx-eth.c | 1 + drivers/net/niu.c | 1 + drivers/net/ns83820.c | 1 + drivers/net/ppp_async.c | 1 + drivers/net/ppp_synctty.c | 1 + drivers/net/ps3_gelic_net.c | 1 + drivers/net/qlge/qlge.h | 1 + drivers/net/r8169.c | 1 + drivers/net/sc92031.c | 1 + drivers/net/sfc/nic.c | 1 + drivers/net/sis190.c | 1 + drivers/net/skge.h | 1 + drivers/net/sky2.c | 1 + drivers/net/smc-mca.c | 1 + drivers/net/smc-ultra.c | 1 + drivers/net/smsc911x.c | 1 + drivers/net/smsc9420.c | 1 + drivers/net/spider_net.c | 1 + drivers/net/starfire.c | 1 + drivers/net/stmmac/stmmac_ethtool.c | 1 + drivers/net/tg3.c | 1 + drivers/net/tlan.c | 2 ++ drivers/net/tokenring/ibmtr.c | 1 + drivers/net/tsi108_eth.c | 1 + drivers/net/tulip/de2104x.c | 1 + drivers/net/tulip/pnic.c | 1 + drivers/net/tulip/tulip_core.c | 1 + drivers/net/vxge/vxge-config.h | 1 + drivers/net/vxge/vxge-main.c | 1 + drivers/net/wan/cycx_main.c | 1 + drivers/net/wan/dscc4.c | 1 + drivers/net/wan/farsync.c | 1 + drivers/net/wan/wanxl.c | 1 + drivers/net/wireless/adm8211.c | 1 + drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/atmel.c | 1 + drivers/net/wireless/hostap/hostap_wlan.h | 1 + drivers/net/wireless/ipw2x00/ipw2200.h | 1 + drivers/net/wireless/ipw2x00/libipw_wx.c | 1 + drivers/net/wireless/iwlegacy/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/libertas/cfg.c | 1 + drivers/net/wireless/libertas/cmd.c | 1 + drivers/net/wireless/libertas/cmdresp.c | 1 + drivers/net/wireless/libertas/debugfs.c | 1 + drivers/net/wireless/libertas/ethtool.c | 1 + drivers/net/wireless/libertas/if_spi.c | 2 ++ drivers/net/wireless/libertas/main.c | 1 + drivers/net/wireless/libertas/mesh.c | 1 + drivers/net/wireless/libertas/rx.c | 1 + drivers/net/wireless/libertas/tx.c | 1 + drivers/net/wireless/libertas_tf/cmd.c | 1 + drivers/net/wireless/libertas_tf/main.c | 1 + drivers/net/wireless/mwl8k.c | 1 + drivers/net/wireless/p54/p54pci.h | 1 + drivers/net/wireless/prism54/islpci_dev.c | 1 + drivers/net/wireless/prism54/islpci_dev.h | 1 + drivers/net/wireless/prism54/islpci_hotplug.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rtl818x/rtl8180/dev.c | 1 + drivers/net/wireless/wl1251/sdio.c | 1 + drivers/net/wireless/wl1251/spi.c | 1 + drivers/net/wireless/wl12xx/io.h | 1 + drivers/net/wireless/wl12xx/spi.c | 1 + drivers/s390/net/ctcm_mpc.h | 1 + include/linux/arcdevice.h | 1 + include/linux/dccp.h | 1 + include/linux/netdevice.h | 1 - include/net/bluetooth/hci_core.h | 1 + include/net/sock.h | 1 + net/atm/pppoatm.c | 1 + net/caif/chnl_net.c | 1 + net/can/bcm.c | 1 + net/rds/ib.h | 1 + net/rds/iw.h | 1 + net/sched/sch_atm.c | 1 + net/sunrpc/xprtrdma/svc_rdma_transport.c | 1 + net/sunrpc/xprtrdma/verbs.c | 1 + 163 files changed, 165 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/atm/eni.h b/drivers/atm/eni.h index e4c9525e60b..493a6932507 100644 --- a/drivers/atm/eni.h +++ b/drivers/atm/eni.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index ef7a658312a..7c7b571647f 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -44,6 +44,7 @@ #include /* for request_region */ #include #include +#include #include #include #include diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index d58e3fcb9db..28750618389 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 1f8d724a18b..be0dbfeb541 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index dee4f01a64d..957106f636e 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 624917902b6..7f8c5132ff3 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index 0cfc455630d..444470a28de 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 2f02ab0ccc1..342cbc1bdaa 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -45,6 +45,7 @@ #include #include +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index 472a2af7944..861b6511f3e 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c @@ -20,6 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index f6f3c87cc7c..a440d7fff0a 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -152,6 +152,7 @@ #define HFC_MULTI_VERSION "2.03" +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index b01a7be1300..3261de18a91 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -44,6 +44,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index bc0529ac88a..6218775ce87 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -38,6 +38,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 64ecc6f5ffa..d2ffb1d9b83 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index db25b6b2ae3..5ef9f11ee74 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c index 9e07246bb9e..4d0d41ea122 100644 --- a/drivers/isdn/hardware/mISDN/speedfax.c +++ b/drivers/isdn/hardware/mISDN/speedfax.c @@ -22,6 +22,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 9e84870b971..e10e0284533 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c @@ -21,6 +21,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index de1c669c7b1..0a5c42a3f12 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index 8b0a7d86b30..478ebab54ca 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 9e2148a1996..437912e4982 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h @@ -6,6 +6,7 @@ #ifndef __FLEXCOP_COMMON_H__ #define __FLEXCOP_COMMON_H__ +#include #include #include diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index b2b0c45f32a..55e6533f15e 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h index bd400d21b81..49dbca145bb 100644 --- a/drivers/media/dvb/mantis/mantis_common.h +++ b/drivers/media/dvb/mantis/mantis_common.h @@ -21,6 +21,7 @@ #ifndef __MANTIS_COMMON_H #define __MANTIS_COMMON_H +#include #include #include diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 7cb79ec685f..80fb5100446 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index d84f6e8903a..554a26c5518 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -49,6 +49,7 @@ static const char version[] = #include #include #include +#include #include #include diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 10c45051cae..73b10b07f9b 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 98517a37347..ed6355cc526 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -100,6 +100,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 3d9e8fb4fbe..58a12e4c78f 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -9,6 +9,7 @@ #include #include +#include #include #define TX_PAGES 12 /* Two Tx slots */ diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 5181e932211..f07b2e980fb 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -32,6 +32,7 @@ static const char version[] = #include #include #include +#include #include #include diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h index 0681da7e875..fd25a3b47fe 100644 --- a/drivers/net/acenic.h +++ b/drivers/net/acenic.h @@ -1,5 +1,6 @@ #ifndef _ACENIC_H_ #define _ACENIC_H_ +#include /* diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 81475ea3a71..db6d2da5a8f 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -75,6 +75,7 @@ Revision History: #include #include #include +#include #include #include #include diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 9efbbbae47c..25197b698dd 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c index 37272827ee5..45c61a2c5fb 100644 --- a/drivers/net/arcnet/com20020-isa.c +++ b/drivers/net/arcnet/com20020-isa.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index 48a1dbf01e6..d427493997b 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index c9e459400ff..7bfb91f3285 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c index eb27976dab3..487d780ebbd 100644 --- a/drivers/net/arcnet/com90io.c +++ b/drivers/net/arcnet/com90io.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index f3b46f71e29..b80fbe40aa0 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index e07b314ed8f..29dc43523ce 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 5a77001b6d1..a167addd538 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index a7b0caa1817..bb62b3f5183 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 925929d764c..dfe4370ccc9 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index 490d3b38e0c..9ac37e3ec8f 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/b44.c b/drivers/net/b44.c index a69331e06b8..085560e1d17 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index a1b8c8b8010..d2e58e2bea7 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -7,6 +7,7 @@ * May 1999, Al Viro: proper release of /proc/net/bmac entry, switched to * dynamic procfs inode. */ +#include #include #include #include diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 9b248348c0e..831c6ec98ee 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 3df0c0f8b8b..1cd0b59d13c 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -4,6 +4,7 @@ * License terms: GNU General Public License (GPL) version 2 */ +#include #include #include #include diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h index de8e778f683..78bd4ecac14 100644 --- a/drivers/net/can/sja1000/sja1000.h +++ b/drivers/net/can/sja1000/sja1000.h @@ -47,6 +47,7 @@ #ifndef SJA1000_DEV_H #define SJA1000_DEV_H +#include #include #include diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 22ce03e55b8..b414f5ae0da 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h index 4fd821aadc8..6e9a8d9ef59 100644 --- a/drivers/net/cxgb4vf/adapter.h +++ b/drivers/net/cxgb4vf/adapter.h @@ -40,6 +40,7 @@ #ifndef __CXGB4VF_ADAPTER_H__ #define __CXGB4VF_ADAPTER_H__ +#include #include #include #include diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index ee597e676ee..863e9c459e6 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 8318ea06cb6..b2269104667 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/e100.c b/drivers/net/e100.c index e336c7937f0..c1352c60c29 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -149,6 +149,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include #include #include #include diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 859d0d3af6c..cb1a3623253 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -28,6 +28,7 @@ /* ethtool support for e1000 */ +#include #include #include #include diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3310c3d477d..888bd9cc271 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index 94ec973b2bd..d50a9998ae7 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -44,6 +44,7 @@ static const char version[] = #include #include #include +#include #include #include diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 1daf79b3616..9600f435c0f 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c index 0ba5e7b9058..7a09575ecff 100644 --- a/drivers/net/es3210.c +++ b/drivers/net/es3210.c @@ -54,6 +54,7 @@ static const char version[] = #include #include #include +#include #include #include diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index a83dd312c3a..9162c705c4f 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 9f81b1ac130..eba0f696a51 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/greth.c b/drivers/net/greth.c index f181304a7ab..69b86d7fac8 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 99cdce33df8..a974727dd9a 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index d92fe6ca788..e349d867449 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 82bffc3cabd..29917363ebf 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -30,6 +30,7 @@ static const char version[] = #include #include #include +#include #include #include diff --git a/drivers/net/hp.c b/drivers/net/hp.c index ef2014375e6..18564d4a7c0 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -30,6 +30,7 @@ static const char version[] = #include #include #include +#include #include #include diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index b388d782c7c..838c5b67376 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 4fecaed67fc..ce53f4a23b1 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 58cd3202b48..d4aa40adf1e 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -22,6 +22,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index d532dde5120..963067d3bda 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 174cafad2c1..b45b2cc4280 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -152,6 +152,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 7a963d4e6d0..b56636da6cc 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 001ed0a255f..b1d1ce3dd8b 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -12,6 +12,7 @@ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor * */ +#include #include #include #include diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index efe05bb34dd..5039f08f5a5 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -11,6 +11,7 @@ * ********************************************************************/ +#include #include #include #include diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 8800e1fe412..d5072af81b2 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index f504b262ba3..6d6479049aa 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -46,6 +46,7 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177. #include #include #include +#include #include #include #include diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index c3d07382b7f..9021d013172 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -36,6 +36,7 @@ MODULE_LICENSE("GPL"); #include #include +#include #include #include #include diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 1f9c3f08d1a..c4366601b06 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index cb1555bc854..4950d03d3ef 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -27,6 +27,7 @@ /* ethtool support for ixgbe */ +#include #include #include #include diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 08e8e25c159..06cfaf31bcf 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index 78ddd8b79e7..e122493ab70 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/jme.h b/drivers/net/jme.h index e9aaeca96ab..0d5da06489d 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -24,6 +24,7 @@ #ifndef __JME_H_INCLUDED__ #define __JME_H_INCLUDED__ +#include #define DRV_NAME "jme" #define DRV_VERSION "1.0.8" diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c index fc12ac0d9f2..4a6ae057e3b 100644 --- a/drivers/net/ks8842.c +++ b/drivers/net/ks8842.c @@ -23,6 +23,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index bcd9ba68c9f..f56743a28fc 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c @@ -13,6 +13,7 @@ #define DEBUG +#include #include #include #include diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 61631cace91..aefbdd896d6 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -23,6 +23,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 41ea5920c15..2ac6c6c984b 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -17,6 +17,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c index 8a1097cf8a8..f9888d20177 100644 --- a/drivers/net/lne390.c +++ b/drivers/net/lne390.c @@ -41,6 +41,7 @@ static const char *version = #include #include #include +#include #include #include diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 6c6a02869df..818f0b8c277 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 1c5221f79d6..2074e9724ba 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 2e4b42175f3..2dfee892d20 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/niu.c b/drivers/net/niu.c index cc25bff0bd3..543eb17acdc 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 3e4040f2f3c..d3afb458987 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -106,6 +106,7 @@ #include #include #include +#include #include /* for iph */ #include /* for IPPROTO_... */ #include diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index a1b82c9c67d..6436ba916fe 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 2573f525f11..736a39ee05b 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index d47abb4e7eb..35e47c3cab3 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -28,6 +28,7 @@ #undef DEBUG +#include #include #include #include diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index d32850715f5..7d8483f9012 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -7,6 +7,7 @@ #ifndef _QLGE_H_ #define _QLGE_H_ +#include #include #include #include diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ef1ce2ebeb4..73108249462 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index fa74314ef78..9da47337b7c 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c @@ -22,6 +22,7 @@ * matching, so you need to enable IFF_PROMISC when using it. */ +#include #include #include #include diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index f2a2b947f86..bafa23a6874 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index b436e007eea..8ad7bfbaa3a 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -21,6 +21,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 598bf7a1a55..a2eb3411584 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -3,6 +3,7 @@ */ #ifndef _SKGE_H #define _SKGE_H +#include /* PCI config registers */ #define PCI_DEV_REG1 0x40 diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3ee41da130c..d252cb123a5 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index d07c39cb4da..34934fb23b9 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index 235a3c6c9f9..ba44ede2919 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -62,6 +62,7 @@ static const char version[] = #include #include #include +#include #include #include #include diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index c6d47d10590..054597625d5 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 4c92ad8be76..5e5e64da5cb 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -19,6 +19,7 @@ *************************************************************************** */ +#include #include #include #include diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 949f124e127..9bc6c20e8b9 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 36045f3b032..860a50815f8 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -30,6 +30,7 @@ #define DRV_VERSION "2.1" #define DRV_RELDATE "July 6, 2008" +#include #include #include #include diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index ae5213a8c4c..720c5a1531b 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -24,6 +24,7 @@ #include #include +#include #include #include diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a1f9f9eef37..c8a145d72f1 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index ace6404e2fa..145871b3130 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -29,8 +29,10 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include +#include #include #include #include diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index e896ad0e8d2..e257a00fe14 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -123,6 +123,7 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */ /* some 95 OS send many non UI frame; this allow removing the warning */ #define TR_FILTERNONUI 1 +#include #include #include #include diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 5c633a32eae..64cb9ac19ed 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index e2f69235118..ce90efc6ba3 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c index aa4d9dad039..52d898bdbeb 100644 --- a/drivers/net/tulip/pnic.c +++ b/drivers/net/tulip/pnic.c @@ -13,6 +13,7 @@ Please submit bugs to http://bugzilla.kernel.org/ . */ +#include #include #include #include "tulip.h" diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 82f87647207..1246998a677 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -28,6 +28,7 @@ #include #include "tulip.h" #include +#include #include #include #include diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 359b9b9f804..6219006d9d2 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -13,6 +13,7 @@ ******************************************************************************/ #ifndef VXGE_CONFIG_H #define VXGE_CONFIG_H +#include #include #include diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 8ab870a2ad0..e658edd1c95 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -44,6 +44,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c index 859dba9b972..a0976d1f97c 100644 --- a/drivers/net/wan/cycx_main.c +++ b/drivers/net/wan/cycx_main.c @@ -50,6 +50,7 @@ #include /* WAN router definitions */ #include /* cyclomx common user API definitions */ #include /* __init (when not using as a module) */ +#include unsigned int cycx_debug; diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index acb9ea83062..3590d588327 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -99,6 +99,7 @@ #include #include +#include #include #include diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index e050bd65e03..1eba06f6fa4 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index db73a7be199..4ea89fe0006 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index afe2cbc6cb2..43ebc44fc82 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f75068b4b31..e99dfe6065b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -19,6 +19,7 @@ #include #include +#include #include #include diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 39a11e8af4f..7e45ca2e78e 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -40,6 +40,7 @@ ******************************************************************************/ #include +#include #include #include diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 88dc6a52bdf..7bb0b4b3f2c 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -1,6 +1,7 @@ #ifndef HOSTAP_WLAN_H #define HOSTAP_WLAN_H +#include #include #include #include diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index 91795b5a93c..ecb561d7a7a 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index d7bd6cf00a8..6623e505225 100644 --- a/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/ipw2x00/libipw_wx.c @@ -30,6 +30,7 @@ ******************************************************************************/ +#include #include #include #include diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index be0106c6a2d..416448acd97 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -32,6 +32,7 @@ #ifndef __iwl_legacy_dev_h__ #define __iwl_legacy_dev_h__ +#include #include /* for struct pci_device_id */ #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 22a6e3ec709..1f4797d9848 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -31,6 +31,7 @@ #ifndef __iwl_dev_h__ #define __iwl_dev_h__ +#include #include /* for struct pci_device_id */ #include #include diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 5d637af2d7c..b456a53b64b 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -8,6 +8,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 71c8f3fccfa..9dcf967e1ee 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -3,6 +3,7 @@ * It prepares command and sends it to firmware when it is ready. */ +#include #include #include #include diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 207fc361db8..2ffe5a1ff00 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -3,6 +3,7 @@ * responses as well as events generated by firmware. */ +#include #include #include #include diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index 23250f62176..1af18277884 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 29dbce4a9f8..4dfb3bfd2cf 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 463352c890d..4fa0be9943f 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -19,6 +19,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include #include #include #include diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 8c40949cb07..cf3d2c8e196 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 24cf06680c6..7969d104189 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index fdb0448301a..bfb8898ae51 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -5,6 +5,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index bbb95f88dc0..f19495b178f 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -1,6 +1,7 @@ /* * This file contains the handling of TX in wlan driver. */ +#include #include #include #include diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c index 8945afd6ce3..13557fe0bf9 100644 --- a/drivers/net/wireless/libertas_tf/cmd.c +++ b/drivers/net/wireless/libertas_tf/cmd.c @@ -9,6 +9,7 @@ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include "libertas_tf.h" diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index d4005081f1d..5beb58142e9 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -9,6 +9,7 @@ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 32261189bce..8ff43c28141 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h index ee9bc62a4fa..7aa509f7e38 100644 --- a/drivers/net/wireless/p54/p54pci.h +++ b/drivers/net/wireless/p54/p54pci.h @@ -1,5 +1,6 @@ #ifndef P54PCI_H #define P54PCI_H +#include /* * Defines for PCI based mac80211 Prism54 driver diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index ec2c75d77ce..5d0f61508a2 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -18,6 +18,7 @@ * */ +#include #include #include diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h index c4d0f19b7cb..c40403877f9 100644 --- a/drivers/net/wireless/prism54/islpci_dev.h +++ b/drivers/net/wireless/prism54/islpci_dev.h @@ -22,6 +22,7 @@ #ifndef _ISLPCI_DEV_H #define _ISLPCI_DEV_H +#include #include #include #include diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c index b5e64d71b7a..9e68e0cb718 100644 --- a/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/drivers/net/wireless/prism54/islpci_hotplug.c @@ -17,6 +17,7 @@ * */ +#include #include #include #include diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c446db69bd3..4efaf886fb8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -29,6 +29,7 @@ #define RT2X00_H #include +#include #include #include #include diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 80db5cabc9b..66b29dc07cc 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index f51a0241a44..f78694295c3 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -19,6 +19,7 @@ * Copyright (C) 2008 Google Inc * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com) */ +#include #include #include #include diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c index af6448c4d3e..eaa5f955620 100644 --- a/drivers/net/wireless/wl1251/spi.c +++ b/drivers/net/wireless/wl1251/spi.c @@ -19,6 +19,7 @@ * */ +#include #include #include #include diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index beed621a8ae..20b00319e44 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h @@ -25,6 +25,7 @@ #ifndef __IO_H__ #define __IO_H__ +#include #include "reg.h" #define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 51662bb6801..beebf64c535 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -21,6 +21,7 @@ * */ +#include #include #include #include diff --git a/drivers/s390/net/ctcm_mpc.h b/drivers/s390/net/ctcm_mpc.h index 5336120cddf..1fa07b0c11c 100644 --- a/drivers/s390/net/ctcm_mpc.h +++ b/drivers/s390/net/ctcm_mpc.h @@ -12,6 +12,7 @@ #ifndef _CTC_MPC_H_ #define _CTC_MPC_H_ +#include #include #include "fsm.h" diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h index 7d650a0e3d8..7216b0daf54 100644 --- a/include/linux/arcdevice.h +++ b/include/linux/arcdevice.h @@ -20,6 +20,7 @@ #include #ifdef __KERNEL__ +#include #ifndef bool #define bool int diff --git a/include/linux/dccp.h b/include/linux/dccp.h index d638e85dc50..710c04302a1 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -236,6 +236,7 @@ enum dccp_packet_dequeueing_policy { #ifdef __KERNEL__ #include +#include #include #include #include diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ca333e79e10..336288567c7 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1563,7 +1563,6 @@ struct packet_type { struct list_head list; }; -#include #include extern rwlock_t dev_base_lock; /* Device list lock */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6c994c004d1..7851c05833e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -25,6 +25,7 @@ #ifndef __HCI_CORE_H #define __HCI_CORE_H +#include #include /* HCI upper protocols */ diff --git a/include/net/sock.h b/include/net/sock.h index f2046e404a6..ebbc0bafe66 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -40,6 +40,7 @@ #ifndef _SOCK_H #define _SOCK_H +#include #include #include #include diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index e9aced0ec56..db4a11c61d1 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index adbb424403d..c628a57953c 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/net/can/bcm.c b/net/can/bcm.c index 184a6572b67..d6c8ae5b2e6 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -43,6 +43,7 @@ #include #include +#include #include #include #include diff --git a/net/rds/ib.h b/net/rds/ib.h index 4297d92788d..edfaaaf164e 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include "rds.h" diff --git a/net/rds/iw.h b/net/rds/iw.h index 90151922178..04ce3b193f7 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -1,6 +1,7 @@ #ifndef _RDS_IW_H #define _RDS_IW_H +#include #include #include #include "rds.h" diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 3f08158b868..e25e49061a0 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index c3c232a88d9..a385430c722 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 80f8da344df..28236bab57f 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -47,6 +47,7 @@ * o buffer memory */ +#include #include /* for Tavor hack below */ #include -- cgit v1.2.3-70-g09d2 From 70559a06657c55aeefe2f06619d3592a08cc68ac Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Sun, 22 May 2011 16:10:22 +0300 Subject: wl12xx: Stop BA session event from device Adding new event that close RX BA session in case of periodic BT activity limiting WLAN activity. Signed-off-by: Shahar Levi Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/boot.c | 3 ++- drivers/net/wireless/wl12xx/event.c | 23 +++++++++++++++++++++++ drivers/net/wireless/wl12xx/event.h | 17 +++++++++++++++-- drivers/net/wireless/wl12xx/init.c | 1 + drivers/net/wireless/wl12xx/main.c | 5 ++++- drivers/net/wireless/wl12xx/wl12xx.h | 1 + 6 files changed, 46 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index b07f8b7e5f1..7ccec07a600 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -485,7 +485,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) if (wl->bss_type == BSS_TYPE_AP_BSS) wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID; else - wl->event_mask |= DUMMY_PACKET_EVENT_ID; + wl->event_mask |= DUMMY_PACKET_EVENT_ID | + BA_SESSION_RX_CONSTRAINT_EVENT_ID; ret = wl1271_event_unmask(wl); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index c3c554cd658..94bbd00ec31 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -168,6 +168,21 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl, wl->last_rssi_event = event; } +static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed) +{ + /* Convert the value to bool */ + wl->ba_allowed = !!ba_allowed; + + /* + * Return in case: + * there are not BA open or the event indication is to allowed BA + */ + if ((!wl->ba_rx_bitmap) || (wl->ba_allowed)) + return; + + ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid); +} + static void wl1271_event_mbox_dump(struct event_mailbox *mbox) { wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); @@ -252,6 +267,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_event_rssi_trigger(wl, mbox); } + if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) && !is_ap) { + wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. " + "ba_allowed = 0x%x", mbox->ba_allowed); + + if (wl->vif) + wl1271_stop_ba_event(wl, mbox->ba_allowed); + } + if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) { wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); if (wl->vif) diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index b6cf06e565a..ce99adf4256 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h @@ -71,7 +71,7 @@ enum { HEALTH_CHECK_REPLY_EVENT_ID = BIT(27), PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28), PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29), - BA_SESSION_TEAR_DOWN_EVENT_ID = BIT(30), + BA_SESSION_RX_CONSTRAINT_EVENT_ID = BIT(30), EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, }; @@ -122,7 +122,20 @@ struct event_mailbox { __le16 sta_aging_status; __le16 sta_tx_retry_exceeded; - u8 reserved_5[24]; + /* + * Bitmap, Each bit set represents the Role ID for which this constraint + * is set. Range: 0 - FF, FF means ANY role + */ + u8 ba_role_id; + /* + * Bitmap, Each bit set represents the Link ID for which this constraint + * is set. Not applicable if ba_role_id is set to ANY role (FF). + * Range: 0 - FFFF, FFFF means ANY link in that role + */ + u8 ba_link_id; + u8 ba_allowed; + + u8 reserved_5[21]; } __packed; int wl1271_event_unmask(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index a8f4f156c05..f5c2c9e6f84 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -541,6 +541,7 @@ static int wl1271_set_ba_policies(struct wl1271 *wl) /* Reset the BA RX indicators */ wl->ba_rx_bitmap = 0; + wl->ba_allowed = true; /* validate that FW support BA */ wl1271_check_ba_support(wl); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e6497dc669d..f37f0b873c7 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3354,9 +3354,12 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, if (ret < 0) goto out; + wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d", + tid, action); + switch (action) { case IEEE80211_AMPDU_RX_START: - if (wl->ba_support) { + if ((wl->ba_support) && (wl->ba_allowed)) { ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn, true); if (!ret) diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index fbe8f46d123..3bc794a1ee7 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -564,6 +564,7 @@ struct wl1271 { /* RX BA constraint value */ bool ba_support; u8 ba_rx_bitmap; + bool ba_allowed; int tcxo_clock; -- cgit v1.2.3-70-g09d2 From f973f87ec13e82256d45e11b204a8e3fb3808635 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 2 Jun 2011 16:46:20 +0200 Subject: iwlagn: refactor iwlagn_mac_channel_switch Use less indentions and remove uneeded irq-save flags. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 106 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 54 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0b2d2cd4b54..099c2795ec0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2916,7 +2916,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u16 ch; - unsigned long flags = 0; IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -2933,65 +2932,64 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, if (!iwl_is_associated_ctx(ctx)) goto out; - if (priv->cfg->ops->lib->set_channel_switch) { + if (!priv->cfg->ops->lib->set_channel_switch) + goto out; - ch = channel->hw_value; - if (le16_to_cpu(ctx->active.channel) != ch) { - ch_info = iwl_get_channel_info(priv, - channel->band, - ch); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "invalid channel\n"); - goto out; - } - spin_lock_irqsave(&priv->lock, flags); - - priv->current_ht_config.smps = conf->smps_mode; - - /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) { - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } - } else - ctx->ht.is_40mhz = false; + ch = channel->hw_value; + if (le16_to_cpu(ctx->active.channel) == ch) + goto out; + + ch_info = iwl_get_channel_info(priv, channel->band, ch); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "invalid channel\n"); + goto out; + } - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; + spin_lock_irq(&priv->lock); - iwl_set_rxon_channel(priv, channel, ctx); - iwl_set_rxon_ht(priv, ht_conf); - iwl_set_flags_for_band(priv, ctx, channel->band, - ctx->vif); - spin_unlock_irqrestore(&priv->lock, flags); + priv->current_ht_config.smps = conf->smps_mode; - iwl_set_rate(priv); - /* - * at this point, staging_rxon has the - * configuration for channel switch - */ - set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); - priv->switch_channel = cpu_to_le16(ch); - if (priv->cfg->ops->lib->set_channel_switch(priv, - ch_switch)) { - clear_bit(STATUS_CHANNEL_SWITCH_PENDING, - &priv->status); - priv->switch_channel = 0; - ieee80211_chswitch_done(ctx->vif, false); - } + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; } + } else + ctx->ht.is_40mhz = false; + + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_set_rxon_channel(priv, channel, ctx); + iwl_set_rxon_ht(priv, ht_conf); + iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); + + spin_unlock_irq(&priv->lock); + + iwl_set_rate(priv); + /* + * at this point, staging_rxon has the + * configuration for channel switch + */ + set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); + priv->switch_channel = cpu_to_le16(ch); + if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { + clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); + priv->switch_channel = 0; + ieee80211_chswitch_done(ctx->vif, false); } + out: mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); -- cgit v1.2.3-70-g09d2 From 485868266150022a139b74ba4daf0da9ad86c1c0 Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Sun, 5 Jun 2011 19:30:11 -0500 Subject: iwlwifi: remove unecessary if statement the code always returns ret regardless, so if(ret) check is unecessary. Signed-off-by: Greg Dietsche Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index c8f6da83179..a7c66c4e5f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -178,9 +178,6 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, sizeof(rxon_assoc), &rxon_assoc, NULL); - if (ret) - return ret; - return ret; } -- cgit v1.2.3-70-g09d2 From fcf2176c87af77e5ee947edaf8e390bc67b729d8 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 6 Jun 2011 14:49:32 +0530 Subject: mwifiex: remove list traversal in mwifiex_num_pkts_in_txq Instead of counting the number of packets in txq for particular RA list before AMSDU creation, maintain a counter which will keep track of the same. This will reduce some MIPS while generating AMSDU traffic as we only have to check the counter instead of traversing through skb list. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_aggr.c | 5 ++++- drivers/net/wireless/mwifiex/main.h | 1 + drivers/net/wireless/mwifiex/wmm.c | 30 ++++++------------------------ 3 files changed, 11 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index f807447e4d9..84d2c76eca8 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -193,8 +193,10 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, else skb_src = NULL; - if (skb_src) + if (skb_src) { pra_list->total_pkts_size -= skb_src->len; + pra_list->total_pkts--; + } atomic_dec(&priv->wmm.tx_pkts_queued); @@ -258,6 +260,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, skb_queue_tail(&pra_list->skb_head, skb_aggr); pra_list->total_pkts_size += skb_aggr->len; + pra_list->total_pkts++; atomic_inc(&priv->wmm.tx_pkts_queued); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 89f98701b70..57b183af72d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -181,6 +181,7 @@ struct mwifiex_ra_list_tbl { struct sk_buff_head skb_head; u8 ra[ETH_ALEN]; u32 total_pkts_size; + u32 total_pkts; u32 is_11n_enabled; }; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 91634daec30..67b2d0b78c7 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -121,6 +121,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) memcpy(ra_list->ra, ra, ETH_ALEN); ra_list->total_pkts_size = 0; + ra_list->total_pkts = 0; dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list); @@ -645,6 +646,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, skb_queue_tail(&ra_list->skb_head, skb); ra_list->total_pkts_size += skb->len; + ra_list->total_pkts++; atomic_inc(&priv->wmm.tx_pkts_queued); @@ -970,28 +972,6 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, return NULL; } -/* - * This function gets the number of packets in the Tx queue of a - * particular RA list. - */ -static int -mwifiex_num_pkts_in_txq(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int max_buf_size) -{ - int count = 0, total_size = 0; - struct sk_buff *skb, *tmp; - - skb_queue_walk_safe(&ptr->skb_head, skb, tmp) { - total_size += skb->len; - if (total_size < max_buf_size) - ++count; - else - break; - } - - return count; -} - /* * This function sends a single packet to firmware for transmission. */ @@ -1019,6 +999,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb); ptr->total_pkts_size -= skb->len; + ptr->total_pkts--; if (!skb_queue_empty(&ptr->skb_head)) skb_next = skb_peek(&ptr->skb_head); @@ -1044,6 +1025,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, skb_queue_tail(&ptr->skb_head, skb); ptr->total_pkts_size += skb->len; + ptr->total_pkts++; tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); @@ -1231,9 +1213,9 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) } /* Minimum number of AMSDU */ #define MIN_NUM_AMSDU 2 + if (mwifiex_is_amsdu_allowed(priv, tid) && - (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= - MIN_NUM_AMSDU)) + (ptr->total_pkts >= MIN_NUM_AMSDU)) mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, ptr_index, flags); /* ra_list_spinlock has been freed in -- cgit v1.2.3-70-g09d2 From a8fe32937e4e55c9ed73c79800198d137a1b968a Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 6 Jun 2011 14:50:58 +0530 Subject: mwifiex: Remove redundant skb_queue_empty checks The check of skb list empty before calling skb_peek and skb_dequeue is redundant. These functions returns NULL if the list is empty. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_aggr.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 84d2c76eca8..aee3491f61d 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -164,12 +164,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, struct mwifiex_tx_param tx_param; struct txpd *ptx_pd = NULL; - if (skb_queue_empty(&pra_list->skb_head)) { + skb_src = skb_peek(&pra_list->skb_head); + if (!skb_src) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); return 0; } - skb_src = skb_peek(&pra_list->skb_head); + tx_info_src = MWIFIEX_SKB_TXCB(skb_src); skb_aggr = dev_alloc_skb(adapter->tx_buf_size); if (!skb_aggr) { @@ -188,10 +189,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, + LLC_SNAP_LEN) <= adapter->tx_buf_size)) { - if (!skb_queue_empty(&pra_list->skb_head)) - skb_src = skb_dequeue(&pra_list->skb_head); - else - skb_src = NULL; + skb_src = skb_dequeue(&pra_list->skb_head); if (skb_src) { pra_list->total_pkts_size -= skb_src->len; @@ -214,10 +212,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, return -1; } - if (!skb_queue_empty(&pra_list->skb_head)) - skb_src = skb_peek(&pra_list->skb_head); - else - skb_src = NULL; + skb_src = skb_peek(&pra_list->skb_head); } spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); -- cgit v1.2.3-70-g09d2 From fb3c19bc9687d972b83faf366b38ac807eca8f25 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 6 Jun 2011 14:53:02 +0530 Subject: mwifiex: adding check for enough space before padding All MSDUs, except the last one in an AMSDU, should end up at 4 bytes boundary. There is need to check if enough skb_tailroom space exists before padding the skb. Also re-arranging code for better readablity. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_aggr.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index aee3491f61d..25312e4437f 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -185,16 +185,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, tx_info_aggr->bss_index = tx_info_src->bss_index; skb_aggr->priority = skb_src->priority; - while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len - + LLC_SNAP_LEN) - <= adapter->tx_buf_size)) { + do { + /* Check if AMSDU can accommodate this MSDU */ + if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN)) + break; skb_src = skb_dequeue(&pra_list->skb_head); - if (skb_src) { - pra_list->total_pkts_size -= skb_src->len; - pra_list->total_pkts--; - } + pra_list->total_pkts_size -= skb_src->len; + pra_list->total_pkts--; atomic_dec(&priv->wmm.tx_pkts_queued); @@ -212,8 +211,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, return -1; } + if (skb_tailroom(skb_aggr) < pad) { + pad = 0; + break; + } + skb_put(skb_aggr, pad); + skb_src = skb_peek(&pra_list->skb_head); - } + + } while (skb_src); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); -- cgit v1.2.3-70-g09d2 From 36cb7cce230a06378915d405cd33adf58dd5fe2a Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 6 Jun 2011 14:54:17 +0530 Subject: mwifiex: disable transmission buffer aggregation for AMSDU packets Padding per MSDU will affect the length of next packet and hence the exact length of next packet is uncertain here. Also, aggregation of transmission buffer, while downloading the data to the card, wont gain much on the AMSDU packets as the AMSDU packets utilizes the transmission buffer space to the maximum (adapter->tx_buf_size). Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_aggr.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 25312e4437f..1a453a605b3 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -233,11 +233,19 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, skb_push(skb_aggr, headroom); - tx_param.next_pkt_len = ((pra_list->total_pkts_size) ? - (((pra_list->total_pkts_size) > - adapter->tx_buf_size) ? adapter-> - tx_buf_size : pra_list->total_pkts_size + - LLC_SNAP_LEN + sizeof(struct txpd)) : 0); + /* + * Padding per MSDU will affect the length of next + * packet and hence the exact length of next packet + * is uncertain here. + * + * Also, aggregation of transmission buffer, while + * downloading the data to the card, wont gain much + * on the AMSDU packets as the AMSDU packets utilizes + * the transmission buffer space to the maximum + * (adapter->tx_buf_size). + */ + tx_param.next_pkt_len = 0; + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, skb_aggr->data, skb_aggr->len, &tx_param); -- cgit v1.2.3-70-g09d2 From 931749bf78b969c54de9bbc67cf29b13a40bb73b Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 6 Jun 2011 23:02:33 +0530 Subject: ath9k: make use of a helper to get paprd scale factor Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index fee38cebdcd..2e7f0f2567e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -46,11 +46,10 @@ EXPORT_SYMBOL(ar9003_paprd_enable); static int ar9003_get_training_power_2g(struct ath_hw *ah) { - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G; + struct ath9k_channel *chan = ah->curchan; unsigned int power, scale, delta; - scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1); + scale = ar9003_get_paprd_scale_factor(ah, chan); power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, AR_PHY_POWERTX_RATE5_POWERTXHT20_0); @@ -67,20 +66,10 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah) static int ar9003_get_training_power_5g(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G; struct ath9k_channel *chan = ah->curchan; unsigned int power, scale, delta; - if (chan->channel >= 5700) - scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), - AR9300_PAPRD_SCALE_1); - else if (chan->channel >= 5400) - scale = MS(le32_to_cpu(hdr->papdRateMaskHt40), - AR9300_PAPRD_SCALE_2); - else - scale = MS(le32_to_cpu(hdr->papdRateMaskHt40), - AR9300_PAPRD_SCALE_1); + scale = ar9003_get_paprd_scale_factor(ah, chan); if (IS_CHAN_HT40(chan)) power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8, -- cgit v1.2.3-70-g09d2 From ffbc03bc75b39c7bd412e7cc6d2185c11b0ffedd Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 8 Jun 2011 15:49:33 +1000 Subject: net: add needed interrupt.h Fixes these errors after the removal of interrupt.h from netdevice.h: drivers/net/ll_temac_main.c: In function 'temac_open': drivers/net/ll_temac_main.c:859:2: error: implicit declaration of function 'request_irq' drivers/net/ll_temac_main.c:870:2: error: implicit declaration of function 'free_irq' drivers/net/ll_temac_main.c: In function 'temac_poll_controller': drivers/net/ll_temac_main.c:903:2: error: implicit declaration of function 'disable_irq' drivers/net/ll_temac_main.c:909:2: error: implicit declaration of function 'enable_irq' Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/ll_temac_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index b7948ccfcf7..e7b8afec73a 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "ll_temac.h" -- cgit v1.2.3-70-g09d2 From 8ef207d63f8ecc0eae41cded066dd0e0ee170edf Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 08:09:13 +0000 Subject: iph: use default get_stats This driver keeps stats in net_device stats therefore it does not need to define it's own get_stats hook. Also, use standard format for net_device_ops (without &). Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/usb/ipheth.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 81126ff85e0..15772b1b6a9 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -409,12 +409,6 @@ static void ipheth_tx_timeout(struct net_device *net) usb_unlink_urb(dev->tx_urb); } -static struct net_device_stats *ipheth_stats(struct net_device *net) -{ - struct ipheth_device *dev = netdev_priv(net); - return &dev->net->stats; -} - static u32 ipheth_ethtool_op_get_link(struct net_device *net) { struct ipheth_device *dev = netdev_priv(net); @@ -426,11 +420,10 @@ static struct ethtool_ops ops = { }; static const struct net_device_ops ipheth_netdev_ops = { - .ndo_open = &ipheth_open, - .ndo_stop = &ipheth_close, - .ndo_start_xmit = &ipheth_tx, - .ndo_tx_timeout = &ipheth_tx_timeout, - .ndo_get_stats = &ipheth_stats, + .ndo_open = ipheth_open, + .ndo_stop = ipheth_close, + .ndo_start_xmit = ipheth_tx, + .ndo_tx_timeout = ipheth_tx_timeout, }; static int ipheth_probe(struct usb_interface *intf, -- cgit v1.2.3-70-g09d2 From 95305f6c3b4e8c0bdd5044604c418a8ad2defc4e Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:53:57 +0000 Subject: vmxnet3: convert to 64 bit stats interface Convert vmxnet3 driver to 64 bit statistics interface. This driver was already counting packet per queue in a 64 bit value so not a huge change. Eliminate unused old net_device_stats structure. Signed-off-by: Stephen Hemminger Signed-off-by: Scott J. Goldman Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- drivers/net/vmxnet3/vmxnet3_ethtool.c | 44 +++++++++++++++++------------------ drivers/net/vmxnet3/vmxnet3_int.h | 5 ++-- 3 files changed, 26 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index fa6e2ac7475..cea1b3c2953 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2864,7 +2864,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, .ndo_set_mac_address = vmxnet3_set_mac_addr, .ndo_change_mtu = vmxnet3_change_mtu, .ndo_set_features = vmxnet3_set_features, - .ndo_get_stats = vmxnet3_get_stats, + .ndo_get_stats64 = vmxnet3_get_stats64, .ndo_tx_timeout = vmxnet3_tx_timeout, .ndo_set_multicast_list = vmxnet3_set_mc, .ndo_vlan_rx_register = vmxnet3_vlan_rx_register, diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index dc959fe27aa..bba7c15de5b 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -113,15 +113,15 @@ vmxnet3_global_stats[] = { }; -struct net_device_stats * -vmxnet3_get_stats(struct net_device *netdev) +struct rtnl_link_stats64 * +vmxnet3_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) { struct vmxnet3_adapter *adapter; struct vmxnet3_tq_driver_stats *drvTxStats; struct vmxnet3_rq_driver_stats *drvRxStats; struct UPT1_TxStats *devTxStats; struct UPT1_RxStats *devRxStats; - struct net_device_stats *net_stats = &netdev->stats; unsigned long flags; int i; @@ -132,36 +132,36 @@ vmxnet3_get_stats(struct net_device *netdev) VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS); spin_unlock_irqrestore(&adapter->cmd_lock, flags); - memset(net_stats, 0, sizeof(*net_stats)); for (i = 0; i < adapter->num_tx_queues; i++) { devTxStats = &adapter->tqd_start[i].stats; drvTxStats = &adapter->tx_queue[i].stats; - net_stats->tx_packets += devTxStats->ucastPktsTxOK + - devTxStats->mcastPktsTxOK + - devTxStats->bcastPktsTxOK; - net_stats->tx_bytes += devTxStats->ucastBytesTxOK + - devTxStats->mcastBytesTxOK + - devTxStats->bcastBytesTxOK; - net_stats->tx_errors += devTxStats->pktsTxError; - net_stats->tx_dropped += drvTxStats->drop_total; + stats->tx_packets += devTxStats->ucastPktsTxOK + + devTxStats->mcastPktsTxOK + + devTxStats->bcastPktsTxOK; + stats->tx_bytes += devTxStats->ucastBytesTxOK + + devTxStats->mcastBytesTxOK + + devTxStats->bcastBytesTxOK; + stats->tx_errors += devTxStats->pktsTxError; + stats->tx_dropped += drvTxStats->drop_total; } for (i = 0; i < adapter->num_rx_queues; i++) { devRxStats = &adapter->rqd_start[i].stats; drvRxStats = &adapter->rx_queue[i].stats; - net_stats->rx_packets += devRxStats->ucastPktsRxOK + - devRxStats->mcastPktsRxOK + - devRxStats->bcastPktsRxOK; + stats->rx_packets += devRxStats->ucastPktsRxOK + + devRxStats->mcastPktsRxOK + + devRxStats->bcastPktsRxOK; - net_stats->rx_bytes += devRxStats->ucastBytesRxOK + - devRxStats->mcastBytesRxOK + - devRxStats->bcastBytesRxOK; + stats->rx_bytes += devRxStats->ucastBytesRxOK + + devRxStats->mcastBytesRxOK + + devRxStats->bcastBytesRxOK; - net_stats->rx_errors += devRxStats->pktsRxError; - net_stats->rx_dropped += drvRxStats->drop_total; - net_stats->multicast += devRxStats->mcastPktsRxOK; + stats->rx_errors += devRxStats->pktsRxError; + stats->rx_dropped += drvRxStats->drop_total; + stats->multicast += devRxStats->mcastPktsRxOK; } - return net_stats; + + return stats; } static int diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index f50d36fdf40..0e567c249d6 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -323,7 +323,6 @@ struct vmxnet3_adapter { struct Vmxnet3_TxQueueDesc *tqd_start; /* all tx queue desc */ struct Vmxnet3_RxQueueDesc *rqd_start; /* all rx queue desc */ struct net_device *netdev; - struct net_device_stats net_stats; struct pci_dev *pdev; u8 __iomem *hw_addr0; /* for BAR 0 */ @@ -407,7 +406,9 @@ vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size); extern void vmxnet3_set_ethtool_ops(struct net_device *netdev); -extern struct net_device_stats *vmxnet3_get_stats(struct net_device *netdev); + +extern struct rtnl_link_stats64 * +vmxnet3_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats); extern char vmxnet3_driver_name[]; #endif -- cgit v1.2.3-70-g09d2 From 6311cc44a23bb42636f5076fef0a67859d0a0102 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:53:59 +0000 Subject: veth: convert to 64 bit statistics Not much change, device was already keeping per cpu statistics. Use recent 64 statistics interface. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/veth.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 8461576fa01..8730d649463 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -24,12 +24,12 @@ #define MAX_MTU 65535 /* Max L3 MTU (arbitrary) */ struct veth_net_stats { - unsigned long rx_packets; - unsigned long tx_packets; - unsigned long rx_bytes; - unsigned long tx_bytes; - unsigned long tx_dropped; - unsigned long rx_dropped; + u64 rx_packets; + u64 tx_packets; + u64 rx_bytes; + u64 tx_bytes; + u64 tx_dropped; + u64 rx_dropped; }; struct veth_priv { @@ -159,32 +159,27 @@ rx_drop: * general routines */ -static struct net_device_stats *veth_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *tot) { struct veth_priv *priv; int cpu; - struct veth_net_stats *stats, total = {0}; + struct veth_net_stats *stats; priv = netdev_priv(dev); for_each_possible_cpu(cpu) { stats = per_cpu_ptr(priv->stats, cpu); - total.rx_packets += stats->rx_packets; - total.tx_packets += stats->tx_packets; - total.rx_bytes += stats->rx_bytes; - total.tx_bytes += stats->tx_bytes; - total.tx_dropped += stats->tx_dropped; - total.rx_dropped += stats->rx_dropped; + tot->rx_packets += stats->rx_packets; + tot->tx_packets += stats->tx_packets; + tot->rx_bytes += stats->rx_bytes; + tot->tx_bytes += stats->tx_bytes; + tot->tx_dropped += stats->tx_dropped; + tot->rx_dropped += stats->rx_dropped; } - dev->stats.rx_packets = total.rx_packets; - dev->stats.tx_packets = total.tx_packets; - dev->stats.rx_bytes = total.rx_bytes; - dev->stats.tx_bytes = total.tx_bytes; - dev->stats.tx_dropped = total.tx_dropped; - dev->stats.rx_dropped = total.rx_dropped; - - return &dev->stats; + + return tot; } static int veth_open(struct net_device *dev) @@ -254,7 +249,7 @@ static const struct net_device_ops veth_netdev_ops = { .ndo_stop = veth_close, .ndo_start_xmit = veth_xmit, .ndo_change_mtu = veth_change_mtu, - .ndo_get_stats = veth_get_stats, + .ndo_get_stats64 = veth_get_stats64, .ndo_set_mac_address = eth_mac_addr, }; -- cgit v1.2.3-70-g09d2 From 47fd428cd051072cf3666aaef5065f7d5746ab2c Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:54:01 +0000 Subject: netxen: convert to 64 bit statistics Change to 64 bit statistics interface, driver was already maintaining 64 bit value. Signed-off-by: Stephen Hemminger Acked-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index b644383017f..684cacec10f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -92,7 +92,8 @@ static irqreturn_t netxen_msi_intr(int irq, void *data); static irqreturn_t netxen_msix_intr(int irq, void *data); static void netxen_config_indev_addr(struct net_device *dev, unsigned long); -static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); +static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev, + struct rtnl_link_stats64 *stats); static int netxen_nic_set_mac(struct net_device *netdev, void *p); /* PCI Device ID Table */ @@ -520,7 +521,7 @@ static const struct net_device_ops netxen_netdev_ops = { .ndo_open = netxen_nic_open, .ndo_stop = netxen_nic_close, .ndo_start_xmit = netxen_nic_xmit_frame, - .ndo_get_stats = netxen_nic_get_stats, + .ndo_get_stats64 = netxen_nic_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = netxen_set_multicast_list, .ndo_set_mac_address = netxen_nic_set_mac, @@ -2110,10 +2111,10 @@ request_reset: clear_bit(__NX_RESETTING, &adapter->state); } -static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) +static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *netdev, + struct rtnl_link_stats64 *stats) { struct netxen_adapter *adapter = netdev_priv(netdev); - struct net_device_stats *stats = &netdev->stats; stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; stats->tx_packets = adapter->stats.xmitfinished; -- cgit v1.2.3-70-g09d2 From f20530bc982d67ebde84b3e0a043549d7ccd85a1 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:54:02 +0000 Subject: enic: update to support 64 bit stats The device driver already uses 64 bit statistics, it just doesn't use the 64 bit interface. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 9600f435c0f..c7797ecd90d 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -801,10 +801,10 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, } /* dev_base_lock rwlock held, nominally process context */ -static struct net_device_stats *enic_get_stats(struct net_device *netdev) +static struct rtnl_link_stats64 *enic_get_stats(struct net_device *netdev, + struct rtnl_link_stats64 *net_stats) { struct enic *enic = netdev_priv(netdev); - struct net_device_stats *net_stats = &netdev->stats; struct vnic_stats *stats; enic_dev_stats_dump(enic, &stats); @@ -2117,7 +2117,7 @@ static const struct net_device_ops enic_netdev_dynamic_ops = { .ndo_open = enic_open, .ndo_stop = enic_stop, .ndo_start_xmit = enic_hard_start_xmit, - .ndo_get_stats = enic_get_stats, + .ndo_get_stats64 = enic_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = enic_set_rx_mode, .ndo_set_multicast_list = enic_set_rx_mode, @@ -2139,7 +2139,7 @@ static const struct net_device_ops enic_netdev_ops = { .ndo_open = enic_open, .ndo_stop = enic_stop, .ndo_start_xmit = enic_hard_start_xmit, - .ndo_get_stats = enic_get_stats, + .ndo_get_stats64 = enic_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = enic_set_mac_address, .ndo_set_rx_mode = enic_set_rx_mode, -- cgit v1.2.3-70-g09d2 From c5f7ef72fcca7602ff8c75682b2a8568ba4e5064 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:54:03 +0000 Subject: myricom: update to 64 bit stats Driver was already keeping 64 bit counters, just not using the new interface. Ps: IMHO drivers should not be duplicating network device stats into ethtool stats. It is useless duplication. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 3f33870de21..04e10f4d679 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -377,7 +377,8 @@ static inline void put_be32(__be32 val, __be32 __iomem * p) __raw_writel((__force __u32) val, (__force void __iomem *)p); } -static struct net_device_stats *myri10ge_get_stats(struct net_device *dev); +static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, + struct rtnl_link_stats64 *stats); static void set_fw_name(struct myri10ge_priv *mgp, char *name, bool allocated) { @@ -1831,13 +1832,14 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, { struct myri10ge_priv *mgp = netdev_priv(netdev); struct myri10ge_slice_state *ss; + struct rtnl_link_stats64 link_stats; int slice; int i; /* force stats update */ - (void)myri10ge_get_stats(netdev); + (void)myri10ge_get_stats(netdev, &link_stats); for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) - data[i] = ((unsigned long *)&netdev->stats)[i]; + data[i] = ((u64 *)&link_stats)[i]; data[i++] = (unsigned int)mgp->tx_boundary; data[i++] = (unsigned int)mgp->wc_enabled; @@ -2976,11 +2978,11 @@ drop: return NETDEV_TX_OK; } -static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, + struct rtnl_link_stats64 *stats) { struct myri10ge_priv *mgp = netdev_priv(dev); struct myri10ge_slice_netstats *slice_stats; - struct net_device_stats *stats = &dev->stats; int i; spin_lock(&mgp->stats_lock); @@ -3790,7 +3792,7 @@ static const struct net_device_ops myri10ge_netdev_ops = { .ndo_open = myri10ge_open, .ndo_stop = myri10ge_close, .ndo_start_xmit = myri10ge_xmit, - .ndo_get_stats = myri10ge_get_stats, + .ndo_get_stats64 = myri10ge_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = myri10ge_change_mtu, .ndo_fix_features = myri10ge_fix_features, -- cgit v1.2.3-70-g09d2 From 1a7a10325d370e2cbed0c5bb7313904545f6dac8 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:54:04 +0000 Subject: niu: support 64 bit stats interface Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/niu.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 543eb17acdc..1c7b790217f 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -6249,9 +6249,10 @@ static void niu_sync_mac_stats(struct niu *np) niu_sync_bmac_stats(np); } -static void niu_get_rx_stats(struct niu *np) +static void niu_get_rx_stats(struct niu *np, + struct rtnl_link_stats64 *stats) { - unsigned long pkts, dropped, errors, bytes; + u64 pkts, dropped, errors, bytes; struct rx_ring_info *rx_rings; int i; @@ -6273,15 +6274,16 @@ static void niu_get_rx_stats(struct niu *np) } no_rings: - np->dev->stats.rx_packets = pkts; - np->dev->stats.rx_bytes = bytes; - np->dev->stats.rx_dropped = dropped; - np->dev->stats.rx_errors = errors; + stats->rx_packets = pkts; + stats->rx_bytes = bytes; + stats->rx_dropped = dropped; + stats->rx_errors = errors; } -static void niu_get_tx_stats(struct niu *np) +static void niu_get_tx_stats(struct niu *np, + struct rtnl_link_stats64 *stats) { - unsigned long pkts, errors, bytes; + u64 pkts, errors, bytes; struct tx_ring_info *tx_rings; int i; @@ -6300,20 +6302,22 @@ static void niu_get_tx_stats(struct niu *np) } no_rings: - np->dev->stats.tx_packets = pkts; - np->dev->stats.tx_bytes = bytes; - np->dev->stats.tx_errors = errors; + stats->tx_packets = pkts; + stats->tx_bytes = bytes; + stats->tx_errors = errors; } -static struct net_device_stats *niu_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 *niu_get_stats(struct net_device *dev, + struct rtnl_link_stats64 *stats) { struct niu *np = netdev_priv(dev); if (netif_running(dev)) { - niu_get_rx_stats(np); - niu_get_tx_stats(np); + niu_get_rx_stats(np, stats); + niu_get_tx_stats(np, stats); } - return &dev->stats; + + return stats; } static void niu_load_hash_xmac(struct niu *np, u16 *hash) @@ -9711,7 +9715,7 @@ static const struct net_device_ops niu_netdev_ops = { .ndo_open = niu_open, .ndo_stop = niu_close, .ndo_start_xmit = niu_start_xmit, - .ndo_get_stats = niu_get_stats, + .ndo_get_stats64 = niu_get_stats, .ndo_set_multicast_list = niu_set_rx_mode, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = niu_set_mac_addr, -- cgit v1.2.3-70-g09d2 From 93736656138e6d2f39f19c1d68f9ef81cfc9dd66 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 8 Jun 2011 19:29:32 +0000 Subject: cnic: Fix interrupt logic We need to keep looping until cnic_get_kcqes() returns 0. cnic_get_kcqes() returns a maximum of 64 entries. If there are more entries in the queue and we don't loop back, the remaining entries may not be serviced for a long time. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 11a92afdf98..5c0a669dfa5 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2778,13 +2778,10 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) /* Tell compiler that status_blk fields can change. */ barrier(); - if (status_idx != *cp->kcq1.status_idx_ptr) { - status_idx = (u16) *cp->kcq1.status_idx_ptr; - /* status block index must be read first */ - rmb(); - cp->kwq_con_idx = *cp->kwq_con_idx_ptr; - } else - break; + status_idx = (u16) *cp->kcq1.status_idx_ptr; + /* status block index must be read first */ + rmb(); + cp->kwq_con_idx = *cp->kwq_con_idx_ptr; } CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx); @@ -2908,8 +2905,6 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) /* Tell compiler that sblk fields can change. */ barrier(); - if (last_status == *info->status_idx_ptr) - break; last_status = *info->status_idx_ptr; /* status block index must be read before reading the KCQ */ -- cgit v1.2.3-70-g09d2 From 101c40c8cb0d10c30f423805f9f5b7a75956832d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 8 Jun 2011 19:29:33 +0000 Subject: cnic: Fix race conditions with firmware During iSCSI connection terminations, if the target is also terminating at about the same time, the firmware may not complete the driver's request to close or reset the connection. This is fixed by handling other events (instead of the expected completion event) as an indication that the driver's request has been rejected. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 5c0a669dfa5..ea7245c5fb6 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3767,7 +3767,13 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe) break; case L4_KCQE_OPCODE_VALUE_CLOSE_RECEIVED: - cnic_cm_upcall(cp, csk, opcode); + /* after we already sent CLOSE_REQ */ + if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags) && + !test_bit(SK_F_OFFLD_COMPLETE, &csk->flags) && + csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP) + cp->close_conn(csk, L4_KCQE_OPCODE_VALUE_RESET_COMP); + else + cnic_cm_upcall(cp, csk, opcode); break; } csk_put(csk); @@ -3821,12 +3827,14 @@ static int cnic_ready_to_close(struct cnic_sock *csk, u32 opcode) } /* 1. If event opcode matches the expected event in csk->state - * 2. If the expected event is CLOSE_COMP, we accept any event + * 2. If the expected event is CLOSE_COMP or RESET_COMP, we accept any + * event * 3. If the expected event is 0, meaning the connection was never * never established, we accept the opcode from cm_abort. */ if (opcode == csk->state || csk->state == 0 || - csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP) { + csk->state == L4_KCQE_OPCODE_VALUE_CLOSE_COMP || + csk->state == L4_KCQE_OPCODE_VALUE_RESET_COMP) { if (!test_and_set_bit(SK_F_CLOSING, &csk->flags)) { if (csk->state == 0) csk->state = opcode; -- cgit v1.2.3-70-g09d2 From 11f23aa8ccd56786f0a6f04211cf59b3fab2ce08 Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Wed, 8 Jun 2011 19:29:34 +0000 Subject: cnic: Randomize initial TCP port for iSCSI connections This reduces the likelihood of port re-use when re-loading the driver. Signed-off-by: Eddie Wai Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index ea7245c5fb6..a529bde03c5 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -605,11 +605,12 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) } EXPORT_SYMBOL(cnic_unregister_driver); -static int cnic_init_id_tbl(struct cnic_id_tbl *id_tbl, u32 size, u32 start_id) +static int cnic_init_id_tbl(struct cnic_id_tbl *id_tbl, u32 size, u32 start_id, + u32 next) { id_tbl->start = start_id; id_tbl->max = size; - id_tbl->next = 0; + id_tbl->next = next; spin_lock_init(&id_tbl->lock); id_tbl->table = kzalloc(DIV_ROUND_UP(size, 32) * 4, GFP_KERNEL); if (!id_tbl->table) @@ -3804,14 +3805,17 @@ static void cnic_cm_free_mem(struct cnic_dev *dev) static int cnic_cm_alloc_mem(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + u32 port_id; cp->csk_tbl = kzalloc(sizeof(struct cnic_sock) * MAX_CM_SK_TBL_SZ, GFP_KERNEL); if (!cp->csk_tbl) return -ENOMEM; + get_random_bytes(&port_id, sizeof(port_id)); + port_id %= CNIC_LOCAL_PORT_RANGE; if (cnic_init_id_tbl(&cp->csk_port_tbl, CNIC_LOCAL_PORT_RANGE, - CNIC_LOCAL_PORT_MIN)) { + CNIC_LOCAL_PORT_MIN, port_id)) { cnic_cm_free_mem(dev); return -ENOMEM; } @@ -4829,7 +4833,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) pfid = cp->pfid; ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ, - cp->iscsi_start_cid); + cp->iscsi_start_cid, 0); if (ret) return -ENOMEM; @@ -4837,7 +4841,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (BNX2X_CHIP_IS_E2(cp->chip_id)) { ret = cnic_init_id_tbl(&cp->fcoe_cid_tbl, BNX2X_FCOE_NUM_CONNECTIONS, - cp->fcoe_start_cid); + cp->fcoe_start_cid, 0); if (ret) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From db1d350fcb156b58f66a67680617077bcacfe6fc Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 8 Jun 2011 19:29:35 +0000 Subject: cnic: Improve NETDEV_UP event handling During NETDEV_UP, we use symbol_get() to get the net driver's cnic probe function. This sometimes doesn't work if NETDEV_UP happens right after NETDEV_REGISTER and the net driver is still running module init code. As a result, the cnic device may not be discovered. We fix this by probing on all NETDEV events if the device's netif_running state is up. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index a529bde03c5..6c544b3411f 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -5342,7 +5342,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, dev = cnic_from_netdev(netdev); - if (!dev && (event == NETDEV_REGISTER || event == NETDEV_UP)) { + if (!dev && (event == NETDEV_REGISTER || netif_running(netdev))) { /* Check for the hot-plug device */ dev = is_cnic_dev(netdev); if (dev) { @@ -5358,7 +5358,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, else if (event == NETDEV_UNREGISTER) cnic_ulp_exit(dev); - if (event == NETDEV_UP) { + if (event == NETDEV_UP || (new_dev && netif_running(netdev))) { if (cnic_register_netdev(dev) != 0) { cnic_put(dev); goto done; -- cgit v1.2.3-70-g09d2 From 7625eb2f2fff7bfae41d3119b472c20b48874895 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 8 Jun 2011 19:29:36 +0000 Subject: cnic, bnx2: Check iSCSI support early in bnx2_init_one() Based on earlier patch from Neil Horman If iSCSI is not supported on a bnx2 device, bnx2_cnic_probe() will return NULL and the cnic device will not be visible to bnx2i. This will prevent bnx2i from registering and then unregistering during cnic_start() and cause the warning message: bnx2 0003:01:00.1: eth1: Failed waiting for ULP up call to complete Signed-off-by: Michael Chan Cc: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 7 +++++++ drivers/net/cnic.c | 12 ++---------- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 57d3293c65b..74580bb175f 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -416,6 +416,9 @@ struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + if (!cp->max_iscsi_conn) + return NULL; + cp->drv_owner = THIS_MODULE; cp->chip_id = bp->chip_id; cp->pdev = bp->pdev; @@ -8177,6 +8180,10 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2_timer; +#ifdef BCM_CNIC + bp->cnic_eth_dev.max_iscsi_conn = + bnx2_reg_rd_ind(bp, BNX2_FW_MAX_ISCSI_CONN); +#endif pci_save_state(pdev); return 0; diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 6c544b3411f..363c7f36890 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4225,14 +4225,6 @@ static void cnic_enable_bnx2_int(struct cnic_dev *dev) BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | cp->last_status_idx); } -static void cnic_get_bnx2_iscsi_info(struct cnic_dev *dev) -{ - u32 max_conn; - - max_conn = cnic_reg_rd_ind(dev, BNX2_FW_MAX_ISCSI_CONN); - dev->max_iscsi_conn = max_conn; -} - static void cnic_disable_bnx2_int_sync(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -4557,8 +4549,6 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) return err; } - cnic_get_bnx2_iscsi_info(dev); - return 0; } @@ -5224,6 +5214,8 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev) cdev->pcidev = pdev; cp->chip_id = ethdev->chip_id; + cdev->max_iscsi_conn = ethdev->max_iscsi_conn; + cp->cnic_ops = &cnic_bnx2_ops; cp->start_hw = cnic_start_bnx2_hw; cp->stop_hw = cnic_stop_bnx2_hw; -- cgit v1.2.3-70-g09d2 From a504b86e718a425ea4a34e2f95b5cf0545ddfd8d Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:33:07 +0000 Subject: tun: reserves space for network in skb The tun driver allocates skb's to hold data from user and then passes the data into the network stack as received data. Most network devices allocate the receive skb with routines like dev_alloc_skb() that reserves additional space for use by network protocol stack but tun does not. Because of the lack of padding, when the packet is passed through bridge netfilter a new skb has to be allocated. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 8a27cbf19dd..17db1942063 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -584,7 +584,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, { struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; struct sk_buff *skb; - size_t len = count, align = 0; + size_t len = count, align = NET_SKB_PAD; struct virtio_net_hdr gso = { 0 }; int offset = 0; @@ -614,7 +614,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, } if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { - align = NET_IP_ALIGN; + align += NET_IP_ALIGN; if (unlikely(len < ETH_HLEN || (gso.hdr_len && gso.hdr_len < ETH_HLEN))) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 6f7c156c08d5eaa9fff2bd062f0a2b9d09a1e7a9 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Jun 2011 14:33:08 +0000 Subject: tun: dont force inline of functions Current standard practice is to not mark most functions as inline and let compiler decide instead. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tun.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 17db1942063..2829badbae3 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -550,9 +550,9 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) /* prepad is the amount to reserve at front. len is length after that. * linear is a hint as to how much to copy (usually headers). */ -static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, - size_t prepad, size_t len, - size_t linear, int noblock) +static struct sk_buff *tun_alloc_skb(struct tun_struct *tun, + size_t prepad, size_t len, + size_t linear, int noblock) { struct sock *sk = tun->socket.sk; struct sk_buff *skb; @@ -578,9 +578,9 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, } /* Get packet from user space buffer */ -static __inline__ ssize_t tun_get_user(struct tun_struct *tun, - const struct iovec *iv, size_t count, - int noblock) +static ssize_t tun_get_user(struct tun_struct *tun, + const struct iovec *iv, size_t count, + int noblock) { struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; struct sk_buff *skb; @@ -729,9 +729,9 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, } /* Put packet to the user space buffer */ -static __inline__ ssize_t tun_put_user(struct tun_struct *tun, - struct sk_buff *skb, - const struct iovec *iv, int len) +static ssize_t tun_put_user(struct tun_struct *tun, + struct sk_buff *skb, + const struct iovec *iv, int len) { struct tun_pi pi = { 0, skb->protocol }; ssize_t total = 0; -- cgit v1.2.3-70-g09d2 From 61a5ff15ebdab87887861a6b128b108404e4706d Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Thu, 9 Jun 2011 00:27:10 -0700 Subject: tun: do not put self in waitq if doing a nonblock read Perf shows a relatively high rate (about 8%) race in spin_lock_irqsave() when doing netperf between external host and guest. It's mainly becuase the lock contention between the tun_do_read() and tun_xmit_skb(), so this patch do not put self into waitqueue to reduce this kind of race. After this patch, it drops to 4%. Signed-off-by: Jason Wang Signed-off-by: Amos Kong Signed-off-by: David S. Miller --- drivers/net/tun.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2829badbae3..ef68e13c042 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -817,7 +817,8 @@ static ssize_t tun_do_read(struct tun_struct *tun, tun_debug(KERN_INFO, tun, "tun_chr_read\n"); - add_wait_queue(&tun->wq.wait, &wait); + if (unlikely(!noblock)) + add_wait_queue(&tun->wq.wait, &wait); while (len) { current->state = TASK_INTERRUPTIBLE; @@ -848,7 +849,8 @@ static ssize_t tun_do_read(struct tun_struct *tun, } current->state = TASK_RUNNING; - remove_wait_queue(&tun->wq.wait, &wait); + if (unlikely(!noblock)) + remove_wait_queue(&tun->wq.wait, &wait); return ret; } -- cgit v1.2.3-70-g09d2 From 075cd29e307720dfde5b67d1715a102473bf4623 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 9 Jun 2011 01:29:13 -0700 Subject: net: emaclite: Add missing linux/interrupt.h header Log: drivers/net/xilinx_emaclite.c: In function 'xemaclite_open': drivers/net/xilinx_emaclite.c:961: error: implicit declaration of function 'request_irq' drivers/net/xilinx_emaclite.c: In function 'xemaclite_close': drivers/net/xilinx_emaclite.c:995: error: implicit declaration of function 'free_irq' make[2]: *** [drivers/net/xilinx_emaclite.o] Error 1 make[1]: *** [drivers/net] Error 2 make: *** [drivers] Error 2 Signed-off-by: Michal Simek Signed-off-by: David S. Miller --- drivers/net/xilinx_emaclite.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 372572c0adc..9cb4cdc2859 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -26,6 +26,7 @@ #include #include #include +#include #define DRIVER_NAME "xilinx_emaclite" -- cgit v1.2.3-70-g09d2 From 8757446d8df4446fc7f5d24ad6d53e9f265cc021 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 9 Jun 2011 10:36:52 +0000 Subject: enic: Pass 802.1p bits for packets tagged with vlan zero enic driver currently passes 802.1p bits to the upper layers for packets tagged with non-zero vlan ids only. This patch extends such behaviour to zero vlan tagged packets also. The patch is dependant on the following kernel patches: 1) vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet) - net-next-2.6 git commit: ad1afb00393915a51c21b1ae8704562bf036855f - Available 2.6.36 and later 2) vlan: Centralize handling of hardware acceleration. - net-next-2.6 git commit: 3701e51382a026cba10c60b03efabe534fba4ca4 - Available 2.6.37 and later Signed-off-by: Christian Benvenuti Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index c7797ecd90d..ea4aededbfe 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1266,8 +1266,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, skb->dev = netdev; - if (enic->vlan_group && vlan_stripped && - (vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) { + if (vlan_stripped) { if (netdev->features & NETIF_F_GRO) vlan_gro_receive(&enic->napi[q_number], -- cgit v1.2.3-70-g09d2 From e1fb77bfd062b8d38fb0e428ae0edcd2dc4ec07b Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 9 Jun 2011 10:36:57 +0000 Subject: enic: Log device configuration in detail during driver load Signed-off-by: Christian Benvenuti Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_res.c | 23 ++++++++++++++++++----- drivers/net/enic/vnic_enet.h | 7 +++++++ 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index e0d2ad181bb..23e21037410 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.16" +#define DRV_VERSION "2.1.1.17" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 6e5c6356e7d..34f42072b60 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -97,11 +97,24 @@ int enic_get_vnic_config(struct enic *enic) dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n", enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu); - dev_info(enic_get_dev(enic), "vNIC csum tx/rx %d/%d " - "tso %d intr timer %d usec rss %d\n", - ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM), - ENIC_SETTING(enic, TSO), - c->intr_timer_usec, ENIC_SETTING(enic, RSS)); + + dev_info(enic_get_dev(enic), "vNIC csum tx/rx %s/%s " + "tso/lro %s/%s rss %s intr mode %s type %s timer %d usec " + "loopback tag 0x%04x\n", + ENIC_SETTING(enic, TXCSUM) ? "yes" : "no", + ENIC_SETTING(enic, RXCSUM) ? "yes" : "no", + ENIC_SETTING(enic, TSO) ? "yes" : "no", + ENIC_SETTING(enic, LRO) ? "yes" : "no", + ENIC_SETTING(enic, RSS) ? "yes" : "no", + c->intr_mode == VENET_INTR_MODE_INTX ? "INTx" : + c->intr_mode == VENET_INTR_MODE_MSI ? "MSI" : + c->intr_mode == VENET_INTR_MODE_ANY ? "any" : + "unknown", + c->intr_timer_type == VENET_INTR_TYPE_MIN ? "min" : + c->intr_timer_type == VENET_INTR_TYPE_IDLE ? "idle" : + "unknown", + c->intr_timer_usec, + c->loop_tag); return 0; } diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h index e8740e3704e..061ad878079 100644 --- a/drivers/net/enic/vnic_enet.h +++ b/drivers/net/enic/vnic_enet.h @@ -51,4 +51,11 @@ struct vnic_enet_config { #define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */ #define VENETF_LOOP 0x800 /* Loopback enabled */ +#define VENET_INTR_TYPE_MIN 0 /* Timer specs min interrupt spacing */ +#define VENET_INTR_TYPE_IDLE 1 /* Timer specs idle time before irq */ + +#define VENET_INTR_MODE_ANY 0 /* Try MSI-X, then MSI, then INTx */ +#define VENET_INTR_MODE_MSI 1 /* Try MSI then INTx */ +#define VENET_INTR_MODE_INTX 2 /* Try INTx only */ + #endif /* _VNIC_ENIC_H_ */ -- cgit v1.2.3-70-g09d2 From 7d260ec26ee56495bcb32491d44ed4590cc838a0 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 9 Jun 2011 10:37:02 +0000 Subject: enic: Get/Set interrupt resource index for transmit and receive queues Instead of deriving the index of a transmit/receive interrupt resource from the transmit/receive queue index, always save and retrieve it using an additional variable. Signed-off-by: Christian Benvenuti Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 4 ++-- drivers/net/enic/vnic_cq.c | 2 ++ drivers/net/enic/vnic_cq.h | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 23e21037410..2dcf310d837 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.17" +#define DRV_VERSION "2.1.1.19" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index ea4aededbfe..e3bffe1aafb 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -153,12 +153,12 @@ static inline unsigned int enic_legacy_notify_intr(void) static inline unsigned int enic_msix_rq_intr(struct enic *enic, unsigned int rq) { - return rq; + return enic->cq[enic_cq_rq(enic, rq)].interrupt_offset; } static inline unsigned int enic_msix_wq_intr(struct enic *enic, unsigned int wq) { - return enic->rq_count + wq; + return enic->cq[enic_cq_wq(enic, wq)].interrupt_offset; } static inline unsigned int enic_msix_err_intr(struct enic *enic) diff --git a/drivers/net/enic/vnic_cq.c b/drivers/net/enic/vnic_cq.c index b86d6ef8dad..0daa1c7073c 100644 --- a/drivers/net/enic/vnic_cq.c +++ b/drivers/net/enic/vnic_cq.c @@ -74,6 +74,8 @@ void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable, iowrite32(cq_message_enable, &cq->ctrl->cq_message_enable); iowrite32(interrupt_offset, &cq->ctrl->interrupt_offset); writeq(cq_message_addr, &cq->ctrl->cq_message_addr); + + cq->interrupt_offset = interrupt_offset; } void vnic_cq_clean(struct vnic_cq *cq) diff --git a/drivers/net/enic/vnic_cq.h b/drivers/net/enic/vnic_cq.h index 552d3daf250..579315cbe80 100644 --- a/drivers/net/enic/vnic_cq.h +++ b/drivers/net/enic/vnic_cq.h @@ -57,6 +57,7 @@ struct vnic_cq { struct vnic_dev_ring ring; unsigned int to_clean; unsigned int last_color; + unsigned int interrupt_offset; }; static inline unsigned int vnic_cq_service(struct vnic_cq *cq, -- cgit v1.2.3-70-g09d2 From b880a954b9e2585ce325aedd76e4741880cab180 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 9 Jun 2011 10:37:07 +0000 Subject: enic: Bug Fix: Fix hardware transmit queue indexing in enic_poll_controller Signed-off-by: Christian Benvenuti Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 2dcf310d837..f747bceb75b 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.19" +#define DRV_VERSION "2.1.1.20" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index e3bffe1aafb..4b3a93a924e 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1777,8 +1777,12 @@ static void enic_poll_controller(struct net_device *netdev) enic_isr_msix_rq(enic->msix_entry[intr].vector, &enic->napi[i]); } - intr = enic_msix_wq_intr(enic, i); - enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); + + for (i = 0; i < enic->wq_count; i++) { + intr = enic_msix_wq_intr(enic, i); + enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); + } + break; case VNIC_DEV_INTR_MODE_MSI: enic_isr_msi(enic->pdev->irq, enic); -- cgit v1.2.3-70-g09d2 From ba824a8b2d77942d51ce45ed721f65764c00ab50 Mon Sep 17 00:00:00 2001 From: "Peter Pan(潘卫平)" Date: Wed, 8 Jun 2011 21:19:01 +0000 Subject: bonding: make 802.3ad use latest lacp_rate There is bug that when you modify lacp_rate via sysfs, 802.3ad won't use the new value of lacp_rate to transmit packets. This is because port->actor_oper_port_state isn't changed. Signed-off-by: Weiping Pan Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 31 +++++++++++++++++++++++++++++++ drivers/net/bonding/bond_3ad.h | 1 + drivers/net/bonding/bond_sysfs.c | 1 + 3 files changed, 33 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index c7537abca4f..4512bc459d3 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2473,3 +2473,34 @@ void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); read_unlock(&bond->lock); } + +/* + * When modify lacp_rate parameter via sysfs, + * update actor_oper_port_state of each port. + * + * Hold slave->state_machine_lock, + * so we can modify port->actor_oper_port_state, + * no matter bond is up or down. + */ +void bond_3ad_update_lacp_rate(struct bonding *bond) +{ + int i; + struct slave *slave; + struct port *port = NULL; + int lacp_fast; + + read_lock(&bond->lock); + lacp_fast = bond->params.lacp_fast; + + bond_for_each_slave(bond, slave, i) { + port = &(SLAVE_AD_INFO(slave).port); + __get_state_machine_lock(port); + if (lacp_fast) + port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; + else + port->actor_oper_port_state &= ~AD_STATE_LACP_TIMEOUT; + __release_state_machine_lock(port); + } + + read_unlock(&bond->lock); +} diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 0ee3f1632c4..e466faf3d6f 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -282,5 +282,6 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, struct slave *slave); int bond_3ad_set_carrier(struct bonding *bond); +void bond_3ad_update_lacp_rate(struct bonding *bond); #endif //__BOND_3AD_H__ diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 88fcb25e554..03d1196b844 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -804,6 +804,7 @@ static ssize_t bonding_store_lacp(struct device *d, if ((new_value == 1) || (new_value == 0)) { bond->params.lacp_fast = new_value; + bond_3ad_update_lacp_rate(bond); pr_info("%s: Setting LACP rate to %s (%d).\n", bond->dev->name, bond_lacp_tbl[new_value].modename, new_value); -- cgit v1.2.3-70-g09d2 From 56d00c677de0a6285587af4f6c6f10aef3209f9f Mon Sep 17 00:00:00 2001 From: "Peter Pan(潘卫平)" Date: Wed, 8 Jun 2011 21:19:02 +0000 Subject: bonding:delete lacp_fast from ad_bond_info These is also a bug, that if you modify lacp_rate via sysfs, and add new slaves in bonding, new slaves won't use the latest lacp_rate, since ad_bond_info->lacp_fast is initialized only once, in bond_3ad_initialize(). Since both struct bond_params and ad_bond_info have lacp_fast, they are duplicate and need extra synchronization. bond_3ad_bind_slave() can use bond_params->lacp_fast to initialize port. So we can just remove lacp_fast from struct ad_bond_info. Signed-off-by: Weiping Pan Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 7 +++---- drivers/net/bonding/bond_3ad.h | 5 +---- drivers/net/bonding/bond_main.c | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 4512bc459d3..013a8018daf 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -1868,11 +1868,10 @@ static u16 aggregator_identifier; * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures * @bond: bonding struct to work on * @tick_resolution: tick duration (millisecond resolution) - * @lacp_fast: boolean. whether fast periodic should be used * * Can be called only after the mac address of the bond is set. */ -void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast) +void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) { // check that the bond is not initialized yet if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), @@ -1880,7 +1879,6 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fas aggregator_identifier = 0; - BOND_AD_INFO(bond).lacp_fast = lacp_fast; BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); @@ -1903,6 +1901,7 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fas int bond_3ad_bind_slave(struct slave *slave) { struct bonding *bond = bond_get_bond_by_slave(slave); + int lacp_fast = bond->params.lacp_fast; struct port *port; struct aggregator *aggregator; @@ -1918,7 +1917,7 @@ int bond_3ad_bind_slave(struct slave *slave) // port initialization port = &(SLAVE_AD_INFO(slave).port); - ad_initialize_port(port, BOND_AD_INFO(bond).lacp_fast); + ad_initialize_port(port, lacp_fast); port->slave = slave; port->actor_port_number = SLAVE_AD_INFO(slave).id; diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index e466faf3d6f..97827857bf4 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -254,9 +254,6 @@ struct ad_bond_info { struct ad_system system; /* 802.3ad system structure */ u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes u32 agg_select_mode; // Mode of selection of active aggregator(bandwidth/count) - int lacp_fast; /* whether fast periodic tx should be - * requested - */ struct timer_list ad_timer; }; @@ -269,7 +266,7 @@ struct ad_slave_info { }; // ================= AD Exported functions to the main bonding code ================== -void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast); +void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution); int bond_3ad_bind_slave(struct slave *slave); void bond_3ad_unbind_slave(struct slave *slave); void bond_3ad_state_machine_handler(struct work_struct *); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 716c852a696..bb1af9c1629 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1843,8 +1843,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* Initialize AD with the number of times that the AD timer is called in 1 second * can be called only after the mac address of the bond is set */ - bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL, - bond->params.lacp_fast); + bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL); } else { SLAVE_AD_INFO(new_slave).id = SLAVE_AD_INFO(new_slave->prev).id + 1; -- cgit v1.2.3-70-g09d2 From 1a14fbcbc96bd098540eb54b66976c20a73b8473 Mon Sep 17 00:00:00 2001 From: "Peter Pan(潘卫平)" Date: Wed, 8 Jun 2011 21:19:03 +0000 Subject: bonding:delete agg_select_mode from ad_bond_info bond_params->ad_select and ad_bond_info->agg_select_mode have the same meaning, they are duplicate and need extra synchronization. __get_agg_selection_mode() get ad_select from bond_params directly. Signed-off-by: Weiping Pan Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 3 +-- drivers/net/bonding/bond_3ad.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 013a8018daf..6122725fc7c 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -262,7 +262,7 @@ static inline u32 __get_agg_selection_mode(struct port *port) if (bond == NULL) return BOND_AD_STABLE; - return BOND_AD_INFO(bond).agg_select_mode; + return bond->params.ad_select; } /** @@ -1859,7 +1859,6 @@ static void ad_marker_response_received(struct bond_marker *marker, void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) { BOND_AD_INFO(bond).agg_select_timer = timeout; - BOND_AD_INFO(bond).agg_select_mode = bond->params.ad_select; } static u16 aggregator_identifier; diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 97827857bf4..1682e691bbe 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -253,7 +253,6 @@ struct ad_system { struct ad_bond_info { struct ad_system system; /* 802.3ad system structure */ u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes - u32 agg_select_mode; // Mode of selection of active aggregator(bandwidth/count) struct timer_list ad_timer; }; -- cgit v1.2.3-70-g09d2 From 0cc42eb608954c1d68be7ac51af7434e5fc45659 Mon Sep 17 00:00:00 2001 From: "Peter Pan(潘卫平)" Date: Wed, 8 Jun 2011 21:19:04 +0000 Subject: bonding: delete unused ad_timer Now we use agg_select_timer and ad_work. Reviewed-by: WANG Cong Signed-off-by: Weiping Pan Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 1682e691bbe..235b2cc58b2 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -253,7 +253,6 @@ struct ad_system { struct ad_bond_info { struct ad_system system; /* 802.3ad system structure */ u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes - struct timer_list ad_timer; }; struct ad_slave_info { -- cgit v1.2.3-70-g09d2 From e357964ee66723d0ced63ac1dbd1db4a6a1d417e Mon Sep 17 00:00:00 2001 From: "Peter Pan(潘卫平)" Date: Wed, 8 Jun 2011 21:19:05 +0000 Subject: bonding: delete unused arp_mon_pt Now all received packets are handled by bond_handle_frame, and arp_mon_pt isn't used any more. Reviewed-by: WANG Cong Signed-off-by: Weiping Pan Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bonding.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index ea1d005be92..382903f0562 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -240,7 +240,6 @@ struct bonding { struct bond_params params; struct list_head vlan_list; struct vlan_group *vlgrp; - struct packet_type arp_mon_pt; struct workqueue_struct *wq; struct delayed_work mii_work; struct delayed_work arp_work; -- cgit v1.2.3-70-g09d2 From d9b24135b972ccdd5f5174fba06c730e895e6daf Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 13 May 2011 07:19:42 +0000 Subject: e1000e: disable far-end loopback mode on ESB2 The ESB2 LAN includes a debug feature that enables far-end loopback (FELB) of the SerDes/Kumeran interface. This feature is activated when receiving a sequence of symbols that includes a reserved codeword. On a perfect link, FELB would never be activated. In the presence of bit errors, there is a very small, but non-zero, probability of FELB being activated. If the FELB is activated, the SerDes link becomes non-functional and must be reset. It could also corrupt the switching tables in the switch since the ESB2 is transmitting packets with a different source MAC address. This patch disables the FELB feature. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/es2lan.c | 8 ++++++++ drivers/net/e1000e/hw.h | 1 + 2 files changed, 9 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index f4bbeb22f51..c0ecb2d9fdb 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -836,6 +836,7 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) struct e1000_mac_info *mac = &hw->mac; u32 reg_data; s32 ret_val; + u16 kum_reg_data; u16 i; e1000_initialize_hw_bits_80003es2lan(hw); @@ -861,6 +862,13 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = e1000e_setup_link(hw); + /* Disable IBIST slave mode (far-end loopback) */ + e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, + &kum_reg_data); + kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE; + e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, + kum_reg_data); + /* Set the transmit descriptor write-back policy */ reg_data = er32(TXDCTL(0)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 6c2fa8327f5..dde584f5ccc 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -312,6 +312,7 @@ enum e1e_registers { #define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ #define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */ #define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */ +#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */ #define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ #define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 #define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 -- cgit v1.2.3-70-g09d2 From 99730e4c13c8344b02dd96108945b48d28c14c25 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 13 May 2011 07:19:48 +0000 Subject: e1000e: 82579 intermittently disabled during S0->Sx When repeatedly cycling Sx->S0 states with the network cable unplugged, the 82579 PHY may not initialize as expected and may require a full power cycle to recover functionality to the device. Workaround this by testing access of the PHY registers after resuming; if that returns unexpected results toggle the LANPHYPC signal to power cycle the PHY. This is implemented in the new function e1000_resume_workarounds_pchlan() which calls another new function, e1000_toggle_lanphypc_value_ich8lan(), which has been created to reduce code duplication (same functionality required by a previous workaround). Also, e1000e_disable_gig_wol_ich8lan is now e1000_suspend_workarounds_ich8lan to better reflect what it does. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/e1000.h | 3 +- drivers/net/e1000e/ich8lan.c | 86 +++++++++++++++++++++++++++++++++++++------- drivers/net/e1000e/netdev.c | 5 ++- 3 files changed, 79 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 9549879e66a..f8cd56a1ade 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -533,7 +533,8 @@ extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, bool state); extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); -extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw); +extern void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw); +extern void e1000_resume_workarounds_pchlan(struct e1000_hw *hw); extern s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); extern s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable); extern void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw); diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 3369d1f6a39..dcd5db5e34e 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -275,6 +275,19 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) #define ew16flash(reg,val) __ew16flash(hw, (reg), (val)) #define ew32flash(reg,val) __ew32flash(hw, (reg), (val)) +static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) +{ + u32 ctrl; + + ctrl = er32(CTRL); + ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; + ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; + ew32(CTRL, ctrl); + udelay(10); + ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; + ew32(CTRL, ctrl); +} + /** * e1000_init_phy_params_pchlan - Initialize PHY function pointers * @hw: pointer to the HW structure @@ -284,7 +297,7 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - u32 ctrl, fwsm; + u32 fwsm; s32 ret_val = 0; phy->addr = 1; @@ -308,13 +321,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) */ fwsm = er32(FWSM); if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) { - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; - ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; - ew32(CTRL, ctrl); - udelay(10); - ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; - ew32(CTRL, ctrl); + e1000_toggle_lanphypc_value_ich8lan(hw); msleep(50); /* @@ -3586,17 +3593,16 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) } /** - * e1000e_disable_gig_wol_ich8lan - disable gig during WoL + * e1000_suspend_workarounds_ich8lan - workarounds needed during S0->Sx * @hw: pointer to the HW structure * * During S0 to Sx transition, it is possible the link remains at gig * instead of negotiating to a lower speed. Before going to Sx, set * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation - * to a lower speed. - * - * Should only be called for applicable parts. + * to a lower speed. For PCH and newer parts, the OEM bits PHY register + * (LED, GbE disable and LPLU configurations) also needs to be written. **/ -void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) +void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) { u32 phy_ctrl; s32 ret_val; @@ -3615,6 +3621,60 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) } } +/** + * e1000_resume_workarounds_pchlan - workarounds needed during Sx->S0 + * @hw: pointer to the HW structure + * + * During Sx to S0 transitions on non-managed devices or managed devices + * on which PHY resets are not blocked, if the PHY registers cannot be + * accessed properly by the s/w toggle the LANPHYPC value to power cycle + * the PHY. + **/ +void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) +{ + u32 fwsm; + + if (hw->mac.type != e1000_pch2lan) + return; + + fwsm = er32(FWSM); + if (!(fwsm & E1000_ICH_FWSM_FW_VALID) || !e1000_check_reset_block(hw)) { + u16 phy_id1, phy_id2; + s32 ret_val; + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) { + e_dbg("Failed to acquire PHY semaphore in resume\n"); + return; + } + + /* Test access to the PHY registers by reading the ID regs */ + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); + if (ret_val) + goto release; + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); + if (ret_val) + goto release; + + if (hw->phy.id == ((u32)(phy_id1 << 16) | + (u32)(phy_id2 & PHY_REVISION_MASK))) + goto release; + + e1000_toggle_lanphypc_value_ich8lan(hw); + + hw->phy.ops.release(hw); + msleep(50); + e1000_phy_hw_reset(hw); + msleep(50); + return; + } + +release: + hw->phy.ops.release(hw); + + return; +} + /** * e1000_cleanup_led_ich8lan - Restore the default LED operation * @hw: pointer to the HW structure diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 888bd9cc271..c4a23c7ac17 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5278,7 +5278,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, } if (adapter->flags & FLAG_IS_ICH) - e1000e_disable_gig_wol_ich8lan(&adapter->hw); + e1000_suspend_workarounds_ich8lan(&adapter->hw); /* Allow time for pending master requests to run */ e1000e_disable_pcie_master(&adapter->hw); @@ -5429,6 +5429,9 @@ static int __e1000_resume(struct pci_dev *pdev) return err; } + if (hw->mac.type == e1000_pch2lan) + e1000_resume_workarounds_pchlan(&adapter->hw); + e1000e_power_up_phy(adapter); /* report the system wakeup cause from S3/S4 */ -- cgit v1.2.3-70-g09d2 From c5caf4825b22957e4ad70fd94316e91ce8cfb51c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 13 May 2011 07:19:53 +0000 Subject: e1000e: log when swflag is cleared unexpectedly on ICH/PCH devices Since EXTCNF_CTRL.SWFLAG (used in the ownership arbitration of shared resources, e.g. the PHY shared between the s/w, f/w, and h/w clients) can be cleared by any of those clients, log a debug message when software attempts to clear it and it is already cleared unexpectedly. And since the swflag is cleared by a hardware reset, the driver does not need to do that, but the mutex acquired when the bit is set must still be cleared. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ich8lan.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index dcd5db5e34e..dddd0b3dd21 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -889,8 +889,13 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) u32 extcnf_ctrl; extcnf_ctrl = er32(EXTCNF_CTRL); - extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; - ew32(EXTCNF_CTRL, extcnf_ctrl); + + if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) { + extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; + ew32(EXTCNF_CTRL, extcnf_ctrl); + } else { + e_dbg("Semaphore unexpectedly released by sw/fw/hw\n"); + } mutex_unlock(&swflag_mutex); } @@ -3066,7 +3071,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) msleep(20); if (!ret_val) - e1000_release_swflag_ich8lan(hw); + mutex_unlock(&swflag_mutex); if (ctrl & E1000_CTRL_PHY_RST) { ret_val = hw->phy.ops.get_cfg_done(hw); -- cgit v1.2.3-70-g09d2 From 400484fa65ead1bbc3e86ea79e7505182a31bce1 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 13 May 2011 07:20:03 +0000 Subject: e1000e: do not schedule the Tx queue until ready Start the Tx queue when the interface is brought up in e1000e_up() but do not schedule the queue until link is up as detected in the watchdog task which sets netif_carrier_on. Also flush the descriptors and clean the Tx and Rx rings before resetting the hardware when bringing the interface down otherwise there is a small window where the watchdog task can be triggered with netif_carrier_off and the Tx ring not yet empty which causes an additional and unnecessary reset. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c4a23c7ac17..bc99458e039 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3347,7 +3347,7 @@ int e1000e_up(struct e1000_adapter *adapter) e1000_configure_msix(adapter); e1000_irq_enable(adapter); - netif_wake_queue(adapter->netdev); + netif_start_queue(adapter->netdev); /* fire a link change interrupt to start the watchdog */ if (adapter->msix_entries) @@ -3414,17 +3414,16 @@ void e1000e_down(struct e1000_adapter *adapter) e1000e_update_stats(adapter); spin_unlock(&adapter->stats64_lock); + e1000e_flush_descriptors(adapter); + e1000_clean_tx_ring(adapter); + e1000_clean_rx_ring(adapter); + adapter->link_speed = 0; adapter->link_duplex = 0; if (!pci_channel_offline(adapter->pdev)) e1000e_reset(adapter); - e1000e_flush_descriptors(adapter); - - e1000_clean_tx_ring(adapter); - e1000_clean_rx_ring(adapter); - /* * TODO: for power management, we could drop the link and * pci_disable_device here. -- cgit v1.2.3-70-g09d2 From 2b6b168d52aa044363647cfff8bda5cef8068ca3 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 13 May 2011 07:20:09 +0000 Subject: e1000e: access multiple PHY registers on same page at the same time Doing a PHY page select can take a long time, relatively speaking. This can cause a significant delay when updating a number of PHY registers on the same page by unnecessarily setting the page for each PHY access. For example when going to Sx, all the PHY wakeup registers (WUC, RAR[], MTA[], SHRAR[], IP4AT[], IP6AT[], etc.) on 82577/8/9 need to be updated which takes a long time which can cause issues when suspending. This patch introduces new PHY ops function pointers to allow callers to set the page directly and do any number of PHY accesses on that page. This feature is currently only implemented for 82577, 82578 and 82579 PHYs for both the normally addressed registers as well as the special- case addressing of the PHY wakeup registers on page 800. For the latter registers, the existing function for accessing the wakeup registers has been divided up into three- 1) enable access to the wakeup register page, 2) perform the register access and 3) disable access to the wakeup register page. The two functions that enable/disable access to the wakeup register page are necessarily available to the caller so that the caller can restore the value of the Port Control (a.k.a. Wakeup Enable) register after the wakeup register accesses are done. All instances of writing to multiple PHY registers on the same page are updated to use this new method and to acquire any PHY locking mechanism before setting the page and performing the register accesses, and release the locking mechanism afterward. Some affiliated magic number cleanup is done as well. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/e1000.h | 38 +++-- drivers/net/e1000e/hw.h | 20 ++- drivers/net/e1000e/ich8lan.c | 70 ++++++--- drivers/net/e1000e/netdev.c | 111 ++++++-------- drivers/net/e1000e/phy.c | 352 ++++++++++++++++++++++++++++--------------- 5 files changed, 366 insertions(+), 225 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index f8cd56a1ade..2c05b4f90e6 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -122,20 +122,21 @@ struct e1000_info; #define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */ #define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */ -#define HV_SCC_UPPER PHY_REG(778, 16) /* Single Collision Count */ -#define HV_SCC_LOWER PHY_REG(778, 17) -#define HV_ECOL_UPPER PHY_REG(778, 18) /* Excessive Collision Count */ -#define HV_ECOL_LOWER PHY_REG(778, 19) -#define HV_MCC_UPPER PHY_REG(778, 20) /* Multiple Collision Count */ -#define HV_MCC_LOWER PHY_REG(778, 21) -#define HV_LATECOL_UPPER PHY_REG(778, 23) /* Late Collision Count */ -#define HV_LATECOL_LOWER PHY_REG(778, 24) -#define HV_COLC_UPPER PHY_REG(778, 25) /* Collision Count */ -#define HV_COLC_LOWER PHY_REG(778, 26) -#define HV_DC_UPPER PHY_REG(778, 27) /* Defer Count */ -#define HV_DC_LOWER PHY_REG(778, 28) -#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ -#define HV_TNCRS_LOWER PHY_REG(778, 30) +#define HV_STATS_PAGE 778 +#define HV_SCC_UPPER PHY_REG(HV_STATS_PAGE, 16) /* Single Collision Count */ +#define HV_SCC_LOWER PHY_REG(HV_STATS_PAGE, 17) +#define HV_ECOL_UPPER PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. Count */ +#define HV_ECOL_LOWER PHY_REG(HV_STATS_PAGE, 19) +#define HV_MCC_UPPER PHY_REG(HV_STATS_PAGE, 20) /* Multiple Coll. Count */ +#define HV_MCC_LOWER PHY_REG(HV_STATS_PAGE, 21) +#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision Count */ +#define HV_LATECOL_LOWER PHY_REG(HV_STATS_PAGE, 24) +#define HV_COLC_UPPER PHY_REG(HV_STATS_PAGE, 25) /* Collision Count */ +#define HV_COLC_LOWER PHY_REG(HV_STATS_PAGE, 26) +#define HV_DC_UPPER PHY_REG(HV_STATS_PAGE, 27) /* Defer Count */ +#define HV_DC_LOWER PHY_REG(HV_STATS_PAGE, 28) +#define HV_TNCRS_UPPER PHY_REG(HV_STATS_PAGE, 29) /* Transmit with no CRS */ +#define HV_TNCRS_LOWER PHY_REG(HV_STATS_PAGE, 30) #define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ @@ -585,6 +586,7 @@ extern s32 e1000e_check_reset_block_generic(struct e1000_hw *hw); extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw); extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw); extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw); +extern s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page); extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data); @@ -605,6 +607,10 @@ extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id); extern s32 e1000e_determine_phy_address(struct e1000_hw *hw); extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); +extern s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, + u16 *phy_reg); +extern s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, + u16 *phy_reg); extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); @@ -625,9 +631,13 @@ extern s32 e1000e_check_downshift(struct e1000_hw *hw); extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data); +extern s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, + u16 *data); extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data); +extern s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, + u16 data); extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); extern s32 e1000_check_polarity_82577(struct e1000_hw *hw); diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index dde584f5ccc..29670397079 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -246,6 +246,7 @@ enum e1e_registers { #define BM_WUC_ENABLE_REG 17 #define BM_WUC_ENABLE_BIT (1 << 2) #define BM_WUC_HOST_WU_BIT (1 << 4) +#define BM_WUC_ME_WU_BIT (1 << 5) #define BM_WUC PHY_REG(BM_WUC_PAGE, 1) #define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) @@ -778,7 +779,21 @@ struct e1000_mac_operations { s32 (*read_mac_addr)(struct e1000_hw *); }; -/* Function pointers for the PHY. */ +/* + * When to use various PHY register access functions: + * + * Func Caller + * Function Does Does When to use + * ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * X_reg L,P,A n/a for simple PHY reg accesses + * X_reg_locked P,A L for multiple accesses of different regs + * on different pages + * X_reg_page A L,P for multiple accesses of different regs + * on the same page + * + * Where X=[read|write], L=locking, P=sets page, A=register access + * + */ struct e1000_phy_operations { s32 (*acquire)(struct e1000_hw *); s32 (*cfg_on_link_up)(struct e1000_hw *); @@ -789,14 +804,17 @@ struct e1000_phy_operations { s32 (*get_cfg_done)(struct e1000_hw *hw); s32 (*get_cable_length)(struct e1000_hw *); s32 (*get_info)(struct e1000_hw *); + s32 (*set_page)(struct e1000_hw *, u16); s32 (*read_reg)(struct e1000_hw *, u32, u16 *); s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *); + s32 (*read_reg_page)(struct e1000_hw *, u32, u16 *); void (*release)(struct e1000_hw *); s32 (*reset)(struct e1000_hw *); s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); s32 (*write_reg)(struct e1000_hw *, u32, u16); s32 (*write_reg_locked)(struct e1000_hw *, u32, u16); + s32 (*write_reg_page)(struct e1000_hw *, u32, u16); void (*power_up)(struct e1000_hw *); void (*power_down)(struct e1000_hw *); }; diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index dddd0b3dd21..1ede6e0f15a 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -303,12 +303,15 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->addr = 1; phy->reset_delay_us = 100; + phy->ops.set_page = e1000_set_page_igp; phy->ops.read_reg = e1000_read_phy_reg_hv; phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked; + phy->ops.read_reg_page = e1000_read_phy_reg_page_hv; phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan; phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; phy->ops.write_reg = e1000_write_phy_reg_hv; phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked; + phy->ops.write_reg_page = e1000_write_phy_reg_page_hv; phy->ops.power_up = e1000_power_up_phy_copper; phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; @@ -1409,17 +1412,36 @@ out: void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw) { u32 mac_reg; - u16 i; + u16 i, phy_reg = 0; + s32 ret_val; + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return; + ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg); + if (ret_val) + goto release; /* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */ for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) { mac_reg = er32(RAL(i)); - e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF)); - e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_RAR_L(i), + (u16)(mac_reg & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_RAR_M(i), + (u16)((mac_reg >> 16) & 0xFFFF)); + mac_reg = er32(RAH(i)); - e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF)); - e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0x8000)); + hw->phy.ops.write_reg_page(hw, BM_RAR_H(i), + (u16)(mac_reg & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_RAR_CTRL(i), + (u16)((mac_reg & E1000_RAH_AV) + >> 16)); } + + e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); + +release: + hw->phy.ops.release(hw); } /** @@ -3897,6 +3919,7 @@ static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) { u16 phy_data; + s32 ret_val; e1000e_clear_hw_cntrs_base(hw); @@ -3918,20 +3941,29 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82579) || (hw->phy.type == e1000_phy_82577)) { - e1e_rphy(hw, HV_SCC_UPPER, &phy_data); - e1e_rphy(hw, HV_SCC_LOWER, &phy_data); - e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); - e1e_rphy(hw, HV_MCC_UPPER, &phy_data); - e1e_rphy(hw, HV_MCC_LOWER, &phy_data); - e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); - e1e_rphy(hw, HV_COLC_UPPER, &phy_data); - e1e_rphy(hw, HV_COLC_LOWER, &phy_data); - e1e_rphy(hw, HV_DC_UPPER, &phy_data); - e1e_rphy(hw, HV_DC_LOWER, &phy_data); - e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); - e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return; + ret_val = hw->phy.ops.set_page(hw, + HV_STATS_PAGE << IGP_PAGE_SHIFT); + if (ret_val) + goto release; + hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data); + hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data); +release: + hw->phy.ops.release(hw); } } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index bc99458e039..51cf7159b38 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3833,6 +3833,8 @@ static void e1000_update_phy_info(unsigned long data) /** * e1000e_update_phy_stats - Update the PHY statistics counters * @adapter: board private structure + * + * Read/clear the upper 16-bit PHY registers and read/accumulate lower **/ static void e1000e_update_phy_stats(struct e1000_adapter *adapter) { @@ -3844,89 +3846,61 @@ static void e1000e_update_phy_stats(struct e1000_adapter *adapter) if (ret_val) return; - hw->phy.addr = 1; - -#define HV_PHY_STATS_PAGE 778 /* * A page set is expensive so check if already on desired page. * If not, set to the page with the PHY status registers. */ + hw->phy.addr = 1; ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, &phy_data); if (ret_val) goto release; - if (phy_data != (HV_PHY_STATS_PAGE << IGP_PAGE_SHIFT)) { - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (HV_PHY_STATS_PAGE << - IGP_PAGE_SHIFT)); + if (phy_data != (HV_STATS_PAGE << IGP_PAGE_SHIFT)) { + ret_val = hw->phy.ops.set_page(hw, + HV_STATS_PAGE << IGP_PAGE_SHIFT); if (ret_val) goto release; } - /* Read/clear the upper 16-bit registers and read/accumulate lower */ - /* Single Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_SCC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_SCC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data); if (!ret_val) adapter->stats.scc += phy_data; /* Excessive Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_ECOL_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_ECOL_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data); if (!ret_val) adapter->stats.ecol += phy_data; /* Multiple Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_MCC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_MCC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data); if (!ret_val) adapter->stats.mcc += phy_data; /* Late Collision Count */ - e1000e_read_phy_reg_mdic(hw, HV_LATECOL_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_LATECOL_LOWER & - MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data); if (!ret_val) adapter->stats.latecol += phy_data; /* Collision Count - also used for adaptive IFS */ - e1000e_read_phy_reg_mdic(hw, HV_COLC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_COLC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data); if (!ret_val) hw->mac.collision_delta = phy_data; /* Defer Count */ - e1000e_read_phy_reg_mdic(hw, HV_DC_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_DC_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data); if (!ret_val) adapter->stats.dc += phy_data; /* Transmit with no CRS */ - e1000e_read_phy_reg_mdic(hw, HV_TNCRS_UPPER & MAX_PHY_REG_ADDRESS, - &phy_data); - ret_val = e1000e_read_phy_reg_mdic(hw, - HV_TNCRS_LOWER & MAX_PHY_REG_ADDRESS, - &phy_data); + hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data); + ret_val = hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data); if (!ret_val) adapter->stats.tncrs += phy_data; @@ -5154,21 +5128,34 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) { struct e1000_hw *hw = &adapter->hw; u32 i, mac_reg; - u16 phy_reg; + u16 phy_reg, wuc_enable; int retval = 0; /* copy MAC RARs to PHY RARs */ e1000_copy_rx_addrs_to_phy_ich8lan(hw); - /* copy MAC MTA to PHY MTA */ + retval = hw->phy.ops.acquire(hw); + if (retval) { + e_err("Could not acquire PHY\n"); + return retval; + } + + /* Enable access to wakeup registers on and set page to BM_WUC_PAGE */ + retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable); + if (retval) + goto out; + + /* copy MAC MTA to PHY MTA - only needed for pchlan */ for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) { mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i); - e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF)); - e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_MTA(i), + (u16)(mac_reg & 0xFFFF)); + hw->phy.ops.write_reg_page(hw, BM_MTA(i) + 1, + (u16)((mac_reg >> 16) & 0xFFFF)); } /* configure PHY Rx Control register */ - e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg); + hw->phy.ops.read_reg_page(&adapter->hw, BM_RCTL, &phy_reg); mac_reg = er32(RCTL); if (mac_reg & E1000_RCTL_UPE) phy_reg |= BM_RCTL_UPE; @@ -5185,31 +5172,19 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) mac_reg = er32(CTRL); if (mac_reg & E1000_CTRL_RFCE) phy_reg |= BM_RCTL_RFCE; - e1e_wphy(&adapter->hw, BM_RCTL, phy_reg); + hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg); /* enable PHY wakeup in MAC register */ ew32(WUFC, wufc); ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); /* configure and enable PHY wakeup in PHY registers */ - e1e_wphy(&adapter->hw, BM_WUFC, wufc); - e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); + hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc); + hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); /* activate PHY wakeup */ - retval = hw->phy.ops.acquire(hw); - if (retval) { - e_err("Could not acquire PHY\n"); - return retval; - } - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); - retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); - if (retval) { - e_err("Could not read PHY page 769\n"); - goto out; - } - phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; - retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); + wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; + retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable); if (retval) e_err("Could not set PHY Host Wakeup bit\n"); out: diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 484774c13c2..2a6ee13285b 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -36,7 +36,7 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active); static s32 e1000_wait_autoneg(struct e1000_hw *hw); static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, - u16 *data, bool read); + u16 *data, bool read, bool page_set); static u32 e1000_get_phy_addr_for_hv_page(u32 page); static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, u16 *data, bool read); @@ -347,6 +347,24 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) return ret_val; } +/** + * e1000_set_page_igp - Set page as on IGP-like PHY(s) + * @hw: pointer to the HW structure + * @page: page to set (shifted left when necessary) + * + * Sets PHY page required for PHY register access. Assumes semaphore is + * already acquired. Note, this function sets phy.addr to 1 so the caller + * must set it appropriately (if necessary) after this function returns. + **/ +s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page) +{ + e_dbg("Setting page 0x%x\n", page); + + hw->phy.addr = 1; + + return e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, page); +} + /** * __e1000e_read_phy_reg_igp - Read igp PHY register * @hw: pointer to the HW structure @@ -2418,7 +2436,7 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, - false); + false, false); goto out; } @@ -2477,7 +2495,7 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, - true); + true, false); goto out; } @@ -2535,7 +2553,7 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, - true); + true, false); goto out; } @@ -2579,7 +2597,7 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, - false); + false, false); goto out; } @@ -2603,104 +2621,163 @@ out: } /** - * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register + * e1000_enable_phy_wakeup_reg_access_bm - enable access to BM wakeup registers * @hw: pointer to the HW structure - * @offset: register offset to be read or written - * @data: pointer to the data to read or write - * @read: determines if operation is read or write + * @phy_reg: pointer to store original contents of BM_WUC_ENABLE_REG * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired - * semaphores before exiting. Note that procedure to read the wakeup - * registers are different. It works as such: - * 1) Set page 769, register 17, bit 2 = 1 - * 2) Set page to 800 for host (801 if we were manageability) - * 3) Write the address using the address opcode (0x11) - * 4) Read or write the data using the data opcode (0x12) - * 5) Restore 769_17.2 to its original value - * - * Assumes semaphore already acquired. + * Assumes semaphore already acquired and phy_reg points to a valid memory + * address to store contents of the BM_WUC_ENABLE_REG register. **/ -static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, - u16 *data, bool read) +s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg) { s32 ret_val; - u16 reg = BM_PHY_REG_NUM(offset); - u16 phy_reg = 0; + u16 temp; - /* Gig must be disabled for MDIO accesses to page 800 */ - if ((hw->mac.type == e1000_pchlan) && - (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) - e_dbg("Attempting to access page 800 while gig enabled.\n"); - - /* All operations in this function are phy address 1 */ + /* All page select, port ctrl and wakeup registers use phy address 1 */ hw->phy.addr = 1; - /* Set page 769 */ - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); + /* Select Port Control Registers page */ + ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); + if (ret_val) { + e_dbg("Could not set Port Control page\n"); + goto out; + } - ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); + ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); if (ret_val) { - e_dbg("Could not read PHY page 769\n"); + e_dbg("Could not read PHY register %d.%d\n", + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); goto out; } - /* First clear bit 4 to avoid a power state change */ - phy_reg &= ~(BM_WUC_HOST_WU_BIT); - ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); + /* + * Enable both PHY wakeup mode and Wakeup register page writes. + * Prevent a power state change by disabling ME and Host PHY wakeup. + */ + temp = *phy_reg; + temp |= BM_WUC_ENABLE_BIT; + temp &= ~(BM_WUC_ME_WU_BIT | BM_WUC_HOST_WU_BIT); + + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, temp); if (ret_val) { - e_dbg("Could not clear PHY page 769 bit 4\n"); + e_dbg("Could not write PHY register %d.%d\n", + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); goto out; } - /* Write bit 2 = 1, and clear bit 4 to 769_17 */ - ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, - phy_reg | BM_WUC_ENABLE_BIT); + /* Select Host Wakeup Registers page */ + ret_val = e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT)); + + /* caller now able to write registers on the Wakeup registers page */ +out: + return ret_val; +} + +/** + * e1000_disable_phy_wakeup_reg_access_bm - disable access to BM wakeup regs + * @hw: pointer to the HW structure + * @phy_reg: pointer to original contents of BM_WUC_ENABLE_REG + * + * Restore BM_WUC_ENABLE_REG to its original value. + * + * Assumes semaphore already acquired and *phy_reg is the contents of the + * BM_WUC_ENABLE_REG before register(s) on BM_WUC_PAGE were accessed by + * caller. + **/ +s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg) +{ + s32 ret_val = 0; + + /* Select Port Control Registers page */ + ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); if (ret_val) { - e_dbg("Could not write PHY page 769 bit 2\n"); + e_dbg("Could not set Port Control page\n"); goto out; } - /* Select page 800 */ - ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_PAGE << IGP_PAGE_SHIFT)); + /* Restore 769.17 to its original value */ + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, *phy_reg); + if (ret_val) + e_dbg("Could not restore PHY register %d.%d\n", + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); +out: + return ret_val; +} - /* Write the page 800 offset value using opcode 0x11 */ +/** + * e1000_access_phy_wakeup_reg_bm - Read/write BM PHY wakeup register + * @hw: pointer to the HW structure + * @offset: register offset to be read or written + * @data: pointer to the data to read or write + * @read: determines if operation is read or write + * @page_set: BM_WUC_PAGE already set and access enabled + * + * Read the PHY register at offset and store the retrieved information in + * data, or write data to PHY register at offset. Note the procedure to + * access the PHY wakeup registers is different than reading the other PHY + * registers. It works as such: + * 1) Set 769.17.2 (page 769, register 17, bit 2) = 1 + * 2) Set page to 800 for host (801 if we were manageability) + * 3) Write the address using the address opcode (0x11) + * 4) Read or write the data using the data opcode (0x12) + * 5) Restore 769.17.2 to its original value + * + * Steps 1 and 2 are done by e1000_enable_phy_wakeup_reg_access_bm() and + * step 5 is done by e1000_disable_phy_wakeup_reg_access_bm(). + * + * Assumes semaphore is already acquired. When page_set==true, assumes + * the PHY page is set to BM_WUC_PAGE (i.e. a function in the call stack + * is responsible for calls to e1000_[enable|disable]_phy_wakeup_reg_bm()). + **/ +static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, + u16 *data, bool read, bool page_set) +{ + s32 ret_val; + u16 reg = BM_PHY_REG_NUM(offset); + u16 page = BM_PHY_REG_PAGE(offset); + u16 phy_reg = 0; + + /* Gig must be disabled for MDIO accesses to Host Wakeup reg page */ + if ((hw->mac.type == e1000_pchlan) && + (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) + e_dbg("Attempting to access page %d while gig enabled.\n", + page); + + if (!page_set) { + /* Enable access to PHY wakeup registers */ + ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg); + if (ret_val) { + e_dbg("Could not enable PHY wakeup reg access\n"); + goto out; + } + } + + e_dbg("Accessing PHY page %d reg 0x%x\n", page, reg); + + /* Write the Wakeup register page offset value using opcode 0x11 */ ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg); if (ret_val) { - e_dbg("Could not write address opcode to page 800\n"); + e_dbg("Could not write address opcode to page %d\n", page); goto out; } if (read) { - /* Read the page 800 value using opcode 0x12 */ + /* Read the Wakeup register page value using opcode 0x12 */ ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, data); } else { - /* Write the page 800 value using opcode 0x12 */ + /* Write the Wakeup register page value using opcode 0x12 */ ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, *data); } if (ret_val) { - e_dbg("Could not access data value from page 800\n"); + e_dbg("Could not access PHY reg %d.%d\n", page, reg); goto out; } - /* - * Restore 769_17.2 to its original value - * Set page 769 - */ - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); - - /* Clear 769_17.2 */ - ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); - if (ret_val) { - e_dbg("Could not clear PHY page 769 bit 2\n"); - goto out; - } + if (!page_set) + ret_val = e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); out: return ret_val; @@ -2792,11 +2869,12 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) * semaphore before exiting. **/ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, - bool locked) + bool locked, bool page_set) { s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); + u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); if (!locked) { ret_val = hw->phy.ops.acquire(hw); @@ -2806,8 +2884,8 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, - data, true); + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, + true, page_set); goto out; } @@ -2817,26 +2895,25 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, goto out; } - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); - - if (page == HV_INTC_FC_PAGE_START) - page = 0; + if (!page_set) { + if (page == HV_INTC_FC_PAGE_START) + page = 0; - if (reg > MAX_PHY_MULTI_PAGE_REG) { - u32 phy_addr = hw->phy.addr; + if (reg > MAX_PHY_MULTI_PAGE_REG) { + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000_set_page_igp(hw, + (page << IGP_PAGE_SHIFT)); - hw->phy.addr = 1; - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - hw->phy.addr = phy_addr; + hw->phy.addr = phy_addr; - if (ret_val) - goto out; + if (ret_val) + goto out; + } } + e_dbg("reading PHY page %d (or 0x%x shifted) reg 0x%x\n", page, + page << IGP_PAGE_SHIFT, reg); + ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); out: @@ -2858,7 +2935,7 @@ out: **/ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) { - return __e1000_read_phy_reg_hv(hw, offset, data, false); + return __e1000_read_phy_reg_hv(hw, offset, data, false, false); } /** @@ -2872,7 +2949,21 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) **/ s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data) { - return __e1000_read_phy_reg_hv(hw, offset, data, true); + return __e1000_read_phy_reg_hv(hw, offset, data, true, false); +} + +/** + * e1000_read_phy_reg_page_hv - Read HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Reads the PHY register at offset and stores the retrieved information + * in data. Assumes semaphore already acquired and page already set. + **/ +s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_phy_reg_hv(hw, offset, data, true, true); } /** @@ -2886,11 +2977,12 @@ s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data) * at the offset. Release any acquired semaphores before exiting. **/ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, - bool locked) + bool locked, bool page_set) { s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); + u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); if (!locked) { ret_val = hw->phy.ops.acquire(hw); @@ -2900,8 +2992,8 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, - &data, false); + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, + false, page_set); goto out; } @@ -2911,42 +3003,41 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, goto out; } - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); - - if (page == HV_INTC_FC_PAGE_START) - page = 0; - - /* - * Workaround MDIO accesses being disabled after entering IEEE Power - * Down (whenever bit 11 of the PHY Control register is set) - */ - if ((hw->phy.type == e1000_phy_82578) && - (hw->phy.revision >= 1) && - (hw->phy.addr == 2) && - ((MAX_PHY_REG_ADDRESS & reg) == 0) && - (data & (1 << 11))) { - u16 data2 = 0x7EFF; - ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, - &data2, false); - if (ret_val) - goto out; - } + if (!page_set) { + if (page == HV_INTC_FC_PAGE_START) + page = 0; - if (reg > MAX_PHY_MULTI_PAGE_REG) { - u32 phy_addr = hw->phy.addr; + /* + * Workaround MDIO accesses being disabled after entering IEEE + * Power Down (when bit 11 of the PHY Control register is set) + */ + if ((hw->phy.type == e1000_phy_82578) && + (hw->phy.revision >= 1) && + (hw->phy.addr == 2) && + ((MAX_PHY_REG_ADDRESS & reg) == 0) && (data & (1 << 11))) { + u16 data2 = 0x7EFF; + ret_val = e1000_access_phy_debug_regs_hv(hw, + (1 << 6) | 0x3, + &data2, false); + if (ret_val) + goto out; + } - hw->phy.addr = 1; + if (reg > MAX_PHY_MULTI_PAGE_REG) { + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000_set_page_igp(hw, + (page << IGP_PAGE_SHIFT)); - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - hw->phy.addr = phy_addr; + hw->phy.addr = phy_addr; - if (ret_val) - goto out; + if (ret_val) + goto out; + } } + e_dbg("writing PHY page %d (or 0x%x shifted) reg 0x%x\n", page, + page << IGP_PAGE_SHIFT, reg); + ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); @@ -2968,7 +3059,7 @@ out: **/ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) { - return __e1000_write_phy_reg_hv(hw, offset, data, false); + return __e1000_write_phy_reg_hv(hw, offset, data, false, false); } /** @@ -2982,7 +3073,21 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) **/ s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data) { - return __e1000_write_phy_reg_hv(hw, offset, data, true); + return __e1000_write_phy_reg_hv(hw, offset, data, true, false); +} + +/** + * e1000_write_phy_reg_page_hv - Write HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Writes the data to PHY register at the offset. Assumes semaphore + * already acquired and page already set. + **/ +s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_phy_reg_hv(hw, offset, data, true, true); } /** @@ -3004,11 +3109,12 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page) * @hw: pointer to the HW structure * @offset: register offset to be read or written * @data: pointer to the data to be read or written - * @read: determines if operation is read or written + * @read: determines if operation is read or write * * Reads the PHY register at offset and stores the retreived information * in data. Assumes semaphore already acquired. Note that the procedure - * to read these regs uses the address port and data port to read/write. + * to access these regs uses the address port and data port to read/write. + * These accesses done with PHY address 2 and without using pages. **/ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, u16 *data, bool read) @@ -3028,7 +3134,7 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, /* masking with 0x3F to remove the page from offset */ ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F); if (ret_val) { - e_dbg("Could not write PHY the HV address register\n"); + e_dbg("Could not write the Address Offset port register\n"); goto out; } @@ -3039,7 +3145,7 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data); if (ret_val) { - e_dbg("Could not read data value from HV data register\n"); + e_dbg("Could not access the Data port register\n"); goto out; } -- cgit v1.2.3-70-g09d2 From 3ebfc7c9a6177794e0a1635483bd64268bed5d3c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 13 May 2011 07:20:14 +0000 Subject: e1000e: Clear host wakeup bit on 82577/8 without touching PHY page 800 The Host Wakeup Active bit in the PHY Port General Configuration register (page 769 register 17) must be cleared after every PHY reset to prevent an unexpected wake signal from the PHY. Originally, this was accomplished by simply reading the PHY Wakeup Control register on page 800 which clears the Host Wakeup Active bit as a side-effect. Unfortunately, a hardware bug on the 82577 and 82578 PHY can cause unexpected behavior when registers on page 800 are accessed while in gigabit mode. This patch changes the remaining instances when the Host Wakeup Active bit needs to be cleared while possibly in gigabit mode by accessing the Port General Configuration register directly instead of accessing any register on page 800. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/e1000.h | 1 + drivers/net/e1000e/ich8lan.c | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 2c05b4f90e6..c1e7f943054 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -104,6 +104,7 @@ struct e1000_info; (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT))) /* PHY Wakeup Registers and defines */ +#define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17) #define BM_RCTL PHY_REG(BM_WUC_PAGE, 0) #define BM_WUC PHY_REG(BM_WUC_PAGE, 1) #define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 1ede6e0f15a..c1752124f3c 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -1391,14 +1391,11 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; - ret_val = hw->phy.ops.read_reg_locked(hw, - PHY_REG(BM_PORT_CTRL_PAGE, 17), - &phy_data); + ret_val = hw->phy.ops.read_reg_locked(hw, BM_PORT_GEN_CFG, &phy_data); if (ret_val) goto release; - ret_val = hw->phy.ops.write_reg_locked(hw, - PHY_REG(BM_PORT_CTRL_PAGE, 17), - phy_data & 0x00FF); + ret_val = hw->phy.ops.write_reg_locked(hw, BM_PORT_GEN_CFG, + phy_data & 0x00FF); release: hw->phy.ops.release(hw); out: @@ -1760,9 +1757,12 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) break; } - /* Dummy read to clear the phy wakeup bit after lcd reset */ - if (hw->mac.type >= e1000_pchlan) - e1e_rphy(hw, BM_WUC, ®); + /* Clear the host wakeup bit after lcd reset */ + if (hw->mac.type >= e1000_pchlan) { + e1e_rphy(hw, BM_PORT_GEN_CFG, ®); + reg &= ~BM_WUC_HOST_WU_BIT; + e1e_wphy(hw, BM_PORT_GEN_CFG, reg); + } /* Configure the LCD with the extended configuration region in NVM */ ret_val = e1000_sw_lcd_config_ich8lan(hw); @@ -3161,11 +3161,13 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) /* * The 82578 Rx buffer will stall if wakeup is enabled in host and - * the ME. Reading the BM_WUC register will clear the host wakeup bit. + * the ME. Disable wakeup by clearing the host wakeup bit. * Reset the phy after disabling host wakeup to reset the Rx buffer. */ if (hw->phy.type == e1000_phy_82578) { - e1e_rphy(hw, BM_WUC, &i); + e1e_rphy(hw, BM_PORT_GEN_CFG, &i); + i &= ~BM_WUC_HOST_WU_BIT; + e1e_wphy(hw, BM_PORT_GEN_CFG, i); ret_val = e1000_phy_hw_reset_ich8lan(hw); if (ret_val) return ret_val; -- cgit v1.2.3-70-g09d2 From 7ff1c8bb7c4fd81b627eedec4f30973c269fd8d8 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 26 May 2011 05:24:38 +0000 Subject: e1000e: remove redundant reverse dependency on CRC32 Commit 5d03078a6804bf4c7f943c5b68bef80468c0717f added a redundant 'select CRC32'; remove it. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 19f04a34783..fa0ea6d291b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2115,7 +2115,6 @@ config E1000 config E1000E tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support" - select CRC32 depends on PCI && (!SPARC32 || BROKEN) select CRC32 ---help--- -- cgit v1.2.3-70-g09d2 From b3ccf26704f80cd9959c4d2a83c2278bcc93425c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 19 May 2011 01:53:41 +0000 Subject: e1000e: update driver version Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 51cf7159b38..3bf52499743 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -54,9 +54,9 @@ #include "e1000.h" -#define DRV_EXTRAVERSION "-k2" +#define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "1.3.10" DRV_EXTRAVERSION +#define DRV_VERSION "1.3.16" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -- cgit v1.2.3-70-g09d2 From cabe0700c56c1e28fc55674e8c1fc9e4495dded9 Mon Sep 17 00:00:00 2001 From: "Williams, Mitch A" Date: Thu, 19 May 2011 05:37:59 +0000 Subject: igbvf: update version number Update the version number to match version conventions. Bump the major version to indicate that new hardware support (i350) has been added. Signed-off-by: Mitch Williams Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 1c77fb3bf4a..64b47bf01e1 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -45,7 +45,7 @@ #include "igbvf.h" -#define DRV_VERSION "1.0.8-k0" +#define DRV_VERSION "2.0.0-k" char igbvf_driver_name[] = "igbvf"; const char igbvf_driver_version[] = DRV_VERSION; static const char igbvf_driver_string[] = -- cgit v1.2.3-70-g09d2 From 929dd047720785f099e12113780b3d7914ce6d9f Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Thu, 26 May 2011 03:02:26 +0000 Subject: igb: Change version to remove number after -k in kernel versions. This patch changes the way versioning is done for igb in the kernel by removing the number after the "k." It has been determined that just the "k" is sufficient to identify a kernel version and the following number was used in an inconsistent manner. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 18fccf91363..c2e9670d154 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -54,9 +54,8 @@ #define MAJ 3 #define MIN 0 #define BUILD 6 -#define KFIX 2 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ -__stringify(BUILD) "-k" __stringify(KFIX) +__stringify(BUILD) "-k" char igb_driver_name[] = "igb"; char igb_driver_version[] = DRV_VERSION; static const char igb_driver_string[] = -- cgit v1.2.3-70-g09d2 From 1057c42747ebf4d1cbaa2ab6125b92914b8ec622 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 19 May 2011 02:11:45 +0000 Subject: ixgbevf: Update the driver string Signed-off-by: Greg Rose Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 28d3cb21d37..b2c5ecda797 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -52,7 +52,7 @@ char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = "Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver"; -#define DRV_VERSION "2.0.0-k2" +#define DRV_VERSION "2.1.0-k" const char ixgbevf_driver_version[] = DRV_VERSION; static char ixgbevf_copyright[] = "Copyright (c) 2009 - 2010 Intel Corporation."; -- cgit v1.2.3-70-g09d2 From 2c333366a4ec1f4cdbaec285ba448d5943df8ffd Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 6 Jun 2011 23:12:08 +0900 Subject: rtlwifi: Remove unnecessary indent Signed-off-by: Mike McCormack Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 176 +++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 95 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index e502db0532e..fbb4c130956 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -654,128 +654,114 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) /*rx pkt */ struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ index]; + struct ieee80211_hdr *hdr; + __le16 fc; + struct sk_buff *new_skb = NULL; own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, HW_DESC_OWN); - if (own) { - /*wait data to be filled by hardware */ + /*wait data to be filled by hardware */ + if (own) break; - } else { - struct ieee80211_hdr *hdr; - __le16 fc; - struct sk_buff *new_skb = NULL; - - rtlpriv->cfg->ops->query_rx_desc(hw, &stats, - &rx_status, - (u8 *) pdesc, skb); - - new_skb = dev_alloc_skb(rtlpci->rxbuffersize); - if (unlikely(!new_skb)) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), - DBG_DMESG, - ("can't alloc skb for rx\n")); - goto done; - } - pci_unmap_single(rtlpci->pdev, - *((dma_addr_t *) skb->cb), - rtlpci->rxbuffersize, - PCI_DMA_FROMDEVICE); + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, + &rx_status, + (u8 *) pdesc, skb); + + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (unlikely(!new_skb)) { + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), + DBG_DMESG, + ("can't alloc skb for rx\n")); + goto done; + } - skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, - false, - HW_DESC_RXPKT_LEN)); - skb_reserve(skb, - stats.rx_drvinfo_size + stats.rx_bufshift); + pci_unmap_single(rtlpci->pdev, + *((dma_addr_t *) skb->cb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); - /* - *NOTICE This can not be use for mac80211, - *this is done in mac80211 code, - *if you done here sec DHCP will fail - *skb_trim(skb, skb->len - 4); - */ + skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, + HW_DESC_RXPKT_LEN)); + skb_reserve(skb, stats.rx_drvinfo_size + stats.rx_bufshift); - hdr = rtl_get_hdr(skb); - fc = rtl_get_fc(skb); + /* + * NOTICE This can not be use for mac80211, + * this is done in mac80211 code, + * if you done here sec DHCP will fail + * skb_trim(skb, skb->len - 4); + */ + + hdr = rtl_get_hdr(skb); + fc = rtl_get_fc(skb); - if (!stats.crc && !stats.hwerror) { - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, + if (!stats.crc && !stats.hwerror) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - if (is_broadcast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else if (is_multicast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else { - unicast = true; - rtlpriv->stats.rxbytesunicast += - skb->len; - } + if (is_broadcast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else if (is_multicast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } - rtl_is_special_data(hw, skb, false); + rtl_is_special_data(hw, skb, false); - if (ieee80211_is_data(fc)) { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_RX); + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); - if (unicast) - rtlpriv->link_info. - num_rx_inperiod++; - } + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } - /* for sw lps */ - rtl_swlps_beacon(hw, (void *)skb->data, - skb->len); - rtl_recognize_peer(hw, (void *)skb->data, - skb->len); - if ((rtlpriv->mac80211.opmode == - NL80211_IFTYPE_AP) && - (rtlpriv->rtlhal.current_bandtype == - BAND_ON_2_4G) && - (ieee80211_is_beacon(fc) || - ieee80211_is_probe_resp(fc))) { + /* for sw lps */ + rtl_swlps_beacon(hw, (void *)skb->data, skb->len); + rtl_recognize_peer(hw, (void *)skb->data, skb->len); + if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && + (rtlpriv->rtlhal.current_bandtype == + BAND_ON_2_4G) && + (ieee80211_is_beacon(fc) || + ieee80211_is_probe_resp(fc))) { + dev_kfree_skb_any(skb); + } else { + if (unlikely(!rtl_action_proc(hw, skb, + false))) { dev_kfree_skb_any(skb); } else { - if (unlikely(!rtl_action_proc(hw, skb, - false))) { - dev_kfree_skb_any(skb); - } else { - struct sk_buff *uskb = NULL; - u8 *pdata; - uskb = dev_alloc_skb(skb->len - + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), - &rx_status, - sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, - skb->len); - memcpy(pdata, skb->data, - skb->len); - dev_kfree_skb_any(skb); - - ieee80211_rx_irqsafe(hw, uskb); - } + struct sk_buff *uskb = NULL; + u8 *pdata; + uskb = dev_alloc_skb(skb->len + 128); + memcpy(IEEE80211_SKB_RXCB(uskb), + &rx_status, sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + dev_kfree_skb_any(skb); + + ieee80211_rx_irqsafe(hw, uskb); } - } else { - dev_kfree_skb_any(skb); } + } else { + dev_kfree_skb_any(skb); + } - if (((rtlpriv->link_info.num_rx_inperiod + - rtlpriv->link_info.num_tx_inperiod) > 8) || - (rtlpriv->link_info.num_rx_inperiod > 2)) { - tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); - } + if (((rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod) > 8) || + (rtlpriv->link_info.num_rx_inperiod > 2)) { + tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); + } - skb = new_skb; + skb = new_skb; - rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; - *((dma_addr_t *) skb->cb) = + rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; + *((dma_addr_t *) skb->cb) = pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); - } done: bufferaddress = (*((dma_addr_t *)skb->cb)); tmp_one = 1; -- cgit v1.2.3-70-g09d2 From 8db8ddf13dda0fc96937bcb6e10563e7b9a20387 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 6 Jun 2011 23:12:42 +0900 Subject: rtlwifi: Resubmit skbs with bad CRC early Once we realize a bad packet was received, don't waste time unmapping it, freeing it, then allocation a new skb and mapping it, just resubmit the existing skb. Signed-off-by: Mike McCormack Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 81 ++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 42 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index fbb4c130956..c89d6d740ad 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -669,6 +669,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) &rx_status, (u8 *) pdesc, skb); + if (stats.crc || stats.hwerror) + goto done; + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); if (unlikely(!new_skb)) { RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), @@ -696,56 +699,50 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) hdr = rtl_get_hdr(skb); fc = rtl_get_fc(skb); - if (!stats.crc && !stats.hwerror) { - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, - sizeof(rx_status)); + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, + sizeof(rx_status)); - if (is_broadcast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else if (is_multicast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else { - unicast = true; - rtlpriv->stats.rxbytesunicast += skb->len; - } + if (is_broadcast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else if (is_multicast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } - rtl_is_special_data(hw, skb, false); + rtl_is_special_data(hw, skb, false); - if (ieee80211_is_data(fc)) { - rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); - if (unicast) - rtlpriv->link_info.num_rx_inperiod++; - } + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } - /* for sw lps */ - rtl_swlps_beacon(hw, (void *)skb->data, skb->len); - rtl_recognize_peer(hw, (void *)skb->data, skb->len); - if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && - (rtlpriv->rtlhal.current_bandtype == - BAND_ON_2_4G) && - (ieee80211_is_beacon(fc) || - ieee80211_is_probe_resp(fc))) { + /* for sw lps */ + rtl_swlps_beacon(hw, (void *)skb->data, skb->len); + rtl_recognize_peer(hw, (void *)skb->data, skb->len); + if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && + (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) && + (ieee80211_is_beacon(fc) || + ieee80211_is_probe_resp(fc))) { + dev_kfree_skb_any(skb); + } else { + if (unlikely(!rtl_action_proc(hw, skb, false))) { dev_kfree_skb_any(skb); } else { - if (unlikely(!rtl_action_proc(hw, skb, - false))) { - dev_kfree_skb_any(skb); - } else { - struct sk_buff *uskb = NULL; - u8 *pdata; - uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), - &rx_status, sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); - dev_kfree_skb_any(skb); - - ieee80211_rx_irqsafe(hw, uskb); - } + struct sk_buff *uskb = NULL; + u8 *pdata; + uskb = dev_alloc_skb(skb->len + 128); + memcpy(IEEE80211_SKB_RXCB(uskb), + &rx_status, sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + dev_kfree_skb_any(skb); + + ieee80211_rx_irqsafe(hw, uskb); } - } else { - dev_kfree_skb_any(skb); } if (((rtlpriv->link_info.num_rx_inperiod + -- cgit v1.2.3-70-g09d2 From 14058adddd4fd40e45c434c801e8ed8baf09251e Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 6 Jun 2011 23:12:53 +0900 Subject: rtlwifi: Free skb in one place Signed-off-by: Mike McCormack Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c89d6d740ad..b60c1abb1a3 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -727,11 +727,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) && (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc))) { - dev_kfree_skb_any(skb); + ; } else { - if (unlikely(!rtl_action_proc(hw, skb, false))) { - dev_kfree_skb_any(skb); - } else { + if (likely(rtl_action_proc(hw, skb, false))) { struct sk_buff *uskb = NULL; u8 *pdata; uskb = dev_alloc_skb(skb->len + 128); @@ -739,7 +737,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) &rx_status, sizeof(rx_status)); pdata = (u8 *)skb_put(uskb, skb->len); memcpy(pdata, skb->data, skb->len); - dev_kfree_skb_any(skb); ieee80211_rx_irqsafe(hw, uskb); } @@ -751,6 +748,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); } + dev_kfree_skb_any(skb); skb = new_skb; rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; -- cgit v1.2.3-70-g09d2 From fd854772c11d6ad0377f0b613142e397bec58a3a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 6 Jun 2011 23:13:06 +0900 Subject: rtlwifi: Factor out code to receive one packet Signed-off-by: Mike McCormack Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 99 ++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 48 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index b60c1abb1a3..cb4e5e80c9c 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -626,6 +626,56 @@ tx_status_ok: } } +static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ieee80211_rx_status rx_status) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = rtl_get_fc(skb); + bool unicast = false; + struct sk_buff *uskb = NULL; + u8 *pdata; + + + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else if (is_multicast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } + + rtl_is_special_data(hw, skb, false); + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); + + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } + + /* for sw lps */ + rtl_swlps_beacon(hw, (void *)skb->data, skb->len); + rtl_recognize_peer(hw, (void *)skb->data, skb->len); + if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && + (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) && + (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc))) + return; + + if (unlikely(!rtl_action_proc(hw, skb, false))) + return; + + uskb = dev_alloc_skb(skb->len + 128); + memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + + ieee80211_rx_irqsafe(hw, uskb); +} + static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -637,7 +687,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) u8 own; u8 tmp_one; u32 bufferaddress; - bool unicast = false; struct rtl_stats stats = { .signal = 0, @@ -654,8 +703,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) /*rx pkt */ struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ index]; - struct ieee80211_hdr *hdr; - __le16 fc; struct sk_buff *new_skb = NULL; own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, @@ -696,51 +743,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) * skb_trim(skb, skb->len - 4); */ - hdr = rtl_get_hdr(skb); - fc = rtl_get_fc(skb); - - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, - sizeof(rx_status)); - - if (is_broadcast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else if (is_multicast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else { - unicast = true; - rtlpriv->stats.rxbytesunicast += skb->len; - } - - rtl_is_special_data(hw, skb, false); - - if (ieee80211_is_data(fc)) { - rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); - - if (unicast) - rtlpriv->link_info.num_rx_inperiod++; - } - - /* for sw lps */ - rtl_swlps_beacon(hw, (void *)skb->data, skb->len); - rtl_recognize_peer(hw, (void *)skb->data, skb->len); - if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && - (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) && - (ieee80211_is_beacon(fc) || - ieee80211_is_probe_resp(fc))) { - ; - } else { - if (likely(rtl_action_proc(hw, skb, false))) { - struct sk_buff *uskb = NULL; - u8 *pdata; - uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), - &rx_status, sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); - - ieee80211_rx_irqsafe(hw, uskb); - } - } + _rtl_receive_one(hw, skb, rx_status); if (((rtlpriv->link_info.num_rx_inperiod + rtlpriv->link_info.num_tx_inperiod) > 8) || -- cgit v1.2.3-70-g09d2 From 9a821f5d0fc36425e95f0f4ade4bbca8f0ebff4d Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 7 Jun 2011 18:15:57 +0100 Subject: libertas: add sd8686 reset_card support At http://dev.laptop.org/ticket/10748 we are seeing a case of the libertas firmware randomly stopping responding to commands after resume. Careful monitoring of communications indicates a firmware or hardware bug, which has been reported to Marvell. Work around this issue by adding a reset_card method; this is automatically called when command timeouts are detected and provides an instant recovery to this situation. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_sdio.c | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 224e9853c48..387786e1b39 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -892,6 +892,37 @@ static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv) } +static struct mmc_host *reset_host; + +static void if_sdio_reset_card_worker(struct work_struct *work) +{ + /* + * The actual reset operation must be run outside of lbs_thread. This + * is because mmc_remove_host() will cause the device to be instantly + * destroyed, and the libertas driver then needs to end lbs_thread, + * leading to a deadlock. + * + * We run it in a workqueue totally independent from the if_sdio_card + * instance for that reason. + */ + + pr_info("Resetting card..."); + mmc_remove_host(reset_host); + mmc_add_host(reset_host); +} +static DECLARE_WORK(card_reset_work, if_sdio_reset_card_worker); + +static void if_sdio_reset_card(struct lbs_private *priv) +{ + struct if_sdio_card *card = priv->card; + + if (work_pending(&card_reset_work)) + return; + + reset_host = card->func->card->host; + schedule_work(&card_reset_work); +} + /*******************************************************************/ /* SDIO callbacks */ /*******************************************************************/ @@ -1065,6 +1096,7 @@ static int if_sdio_probe(struct sdio_func *func, priv->enter_deep_sleep = if_sdio_enter_deep_sleep; priv->exit_deep_sleep = if_sdio_exit_deep_sleep; priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; + priv->reset_card = if_sdio_reset_card; sdio_claim_host(func); @@ -1301,6 +1333,8 @@ static void __exit if_sdio_exit_module(void) /* Set the flag as user is removing this module. */ user_rmmod = 1; + cancel_work_sync(&card_reset_work); + sdio_unregister_driver(&if_sdio_driver); lbs_deb_leave(LBS_DEB_SDIO); -- cgit v1.2.3-70-g09d2 From 3c09b174da3de867e61c4dcca765417a98ba961e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 8 Jun 2011 15:28:24 +0200 Subject: iwlegacy: remove unused power commands defines Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-commands.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-commands.h b/drivers/net/wireless/iwlegacy/iwl-commands.h index 17a1d504348..ee21210bea9 100644 --- a/drivers/net/wireless/iwlegacy/iwl-commands.h +++ b/drivers/net/wireless/iwlegacy/iwl-commands.h @@ -2297,14 +2297,7 @@ struct iwl_spectrum_notification { #define IWL_POWER_VEC_SIZE 5 #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) -#define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0)) -#define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1)) -#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) -#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) -#define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5)) -#define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) -#define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) struct iwl3945_powertable_cmd { __le16 flags; -- cgit v1.2.3-70-g09d2 From ecaee0ff07d429a8571ea015c00a211c17a86494 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 8 Jun 2011 15:28:25 +0200 Subject: iwlegacy: remove recover from statistics Recover from statistics code was added during 6xxx devices development, I don't think is needed on old devices. Also it is suspicious to cause random, unreproducible microcode errors and hangs. So remove it. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-3945.c | 1 - drivers/net/wireless/iwlegacy/iwl-4965-rx.c | 78 +---------------------------- drivers/net/wireless/iwlegacy/iwl-4965.c | 1 - drivers/net/wireless/iwlegacy/iwl-core.h | 3 -- drivers/net/wireless/iwlegacy/iwl-rx.c | 21 -------- 5 files changed, 1 insertion(+), 103 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c index d096dc28204..5e99584aa9a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -408,7 +408,6 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, #ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); #endif - iwl_legacy_recover_from_statistics(priv, pkt); memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); } diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rx.c b/drivers/net/wireless/iwlegacy/iwl-4965-rx.c index b9fa2f6411a..2b144bbfc3c 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rx.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rx.c @@ -151,81 +151,6 @@ static void iwl4965_accumulative_statistics(struct iwl_priv *priv, #define REG_RECALIB_PERIOD (60) -/** - * iwl4965_good_plcp_health - checks for plcp error. - * - * When the plcp error is exceeding the thresholds, reset the radio - * to improve the throughput. - */ -bool iwl4965_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - bool rc = true; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; - - if (priv->cfg->base_params->plcp_delta_threshold == - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { - IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); - return rc; - } - - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - struct statistics_rx_phy *ofdm; - struct statistics_rx_ht_phy *ofdm_ht; - - ofdm = &pkt->u.stats.rx.ofdm; - ofdm_ht = &pkt->u.stats.rx.ofdm_ht; - combined_plcp_delta = - (le32_to_cpu(ofdm->plcp_err) - - le32_to_cpu(priv->_4965.statistics. - rx.ofdm.plcp_err)) + - (le32_to_cpu(ofdm_ht->plcp_err) - - le32_to_cpu(priv->_4965.statistics. - rx.ofdm_ht.plcp_err)); - - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->base_params->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, - * the following data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * Received ofdm_ht.plcp_err, - * Current ofdm_ht.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %u, %u, %u, %d, %u mSecs\n", - priv->cfg->base_params->plcp_delta_threshold, - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - combined_plcp_delta, plcp_msec); - - rc = false; - } - } - return rc; -} - void iwl4965_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -248,8 +173,7 @@ void iwl4965_rx_statistics(struct iwl_priv *priv, iwl4965_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); #endif - iwl_legacy_recover_from_statistics(priv, pkt); - + /* TODO: reading some of statistics is unneeded */ memcpy(&priv->_4965.statistics, &pkt->u.stats, sizeof(priv->_4965.statistics)); diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index 9cf96cb5171..f59f588ca05 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -2100,7 +2100,6 @@ static struct iwl_lib_ops iwl4965_lib = { .tx_stats_read = iwl4965_ucode_tx_stats_read, .general_stats_read = iwl4965_ucode_general_stats_read, }, - .check_plcp_health = iwl4965_good_plcp_health, }; static const struct iwl_legacy_ops iwl4965_legacy_ops = { diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index c5fbda0760d..a821bdbe3e1 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -161,9 +161,6 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; - /* check for plcp health */ - bool (*check_plcp_health)(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); struct iwl_debugfs_ops debugfs_ops; diff --git a/drivers/net/wireless/iwlegacy/iwl-rx.c b/drivers/net/wireless/iwlegacy/iwl-rx.c index 654cf233a38..9b5d0abe8be 100644 --- a/drivers/net/wireless/iwlegacy/iwl-rx.c +++ b/drivers/net/wireless/iwlegacy/iwl-rx.c @@ -227,27 +227,6 @@ void iwl_legacy_rx_spectrum_measure_notif(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_legacy_rx_spectrum_measure_notif); -void iwl_legacy_recover_from_statistics(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - if (iwl_legacy_is_any_associated(priv)) { - if (priv->cfg->ops->lib->check_plcp_health) { - if (!priv->cfg->ops->lib->check_plcp_health( - priv, pkt)) { - /* - * high plcp error detected - * reset Radio - */ - iwl_legacy_force_reset(priv, - IWL_RF_RESET, false); - } - } - } -} -EXPORT_SYMBOL(iwl_legacy_recover_from_statistics); - /* * returns non-zero if packet should be dropped */ -- cgit v1.2.3-70-g09d2 From dd6d2a8aef69cfef8acf1ff7ebb22a763c9ba56f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 8 Jun 2011 15:28:26 +0200 Subject: iwlegacy: remove reset rf infrastructure We do not reset radio anymore, hence don't need that code too. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-3945.c | 1 - drivers/net/wireless/iwlegacy/iwl-4965-lib.c | 79 +++-------------------- drivers/net/wireless/iwlegacy/iwl-4965.c | 1 - drivers/net/wireless/iwlegacy/iwl-core.c | 90 +++++++++----------------- drivers/net/wireless/iwlegacy/iwl-core.h | 5 +- drivers/net/wireless/iwlegacy/iwl-debugfs.c | 95 ++++++---------------------- drivers/net/wireless/iwlegacy/iwl-dev.h | 25 +------- drivers/net/wireless/iwlegacy/iwl-scan.c | 92 +++------------------------ drivers/net/wireless/iwlegacy/iwl3945-base.c | 95 ++++------------------------ drivers/net/wireless/iwlegacy/iwl4965-base.c | 5 +- 10 files changed, 81 insertions(+), 407 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c index 5e99584aa9a..8aa018dfa46 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -2697,7 +2697,6 @@ static struct iwl_base_params iwl3945_base_params = { .set_l0s = false, .use_bsm = true, .led_compensation = 64, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, }; diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index a7a4739880d..2be6d9e3b01 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c @@ -694,47 +694,6 @@ void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, sizeof(struct iwl_rx_phy_res)); } -static int iwl4965_get_single_channel_for_scan(struct iwl_priv *priv, - struct ieee80211_vif *vif, - enum ieee80211_band band, - struct iwl_scan_channel *scan_ch) -{ - const struct ieee80211_supported_band *sband; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added = 0; - u16 channel = 0; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) { - IWL_ERR(priv, "invalid band\n"); - return added; - } - - active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); - passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - channel = iwl_legacy_get_single_channel_number(priv, band); - if (channel) { - scan_ch->channel = cpu_to_le16(channel); - scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* Set txpower levels to defaults */ - scan_ch->dsp_atten = 110; - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tx_gain = ((1 << 5) | (5 << 3)); - added++; - } else - IWL_ERR(priv, "no valid channel found\n"); - return added; -} - static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, struct ieee80211_vif *vif, enum ieee80211_band band, @@ -858,16 +817,13 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_time = IWL_ACTIVE_QUIET_TIME; if (iwl_legacy_is_any_associated(priv)) { - u16 interval = 0; + u16 interval; u32 extra; u32 suspend_time = 100; u32 scan_suspend_time = 100; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - if (priv->is_internal_short_scan) - interval = 0; - else - interval = vif->bss_conf.beacon_int; + interval = vif->bss_conf.beacon_int; scan->suspend_time = 0; scan->max_out_time = cpu_to_le32(200 * 1024); @@ -882,9 +838,7 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan_suspend_time, interval); } - if (priv->is_internal_short_scan) { - IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); - } else if (priv->scan_request->n_ssids) { + if (priv->scan_request->n_ssids) { int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); for (i = 0; i < priv->scan_request->n_ssids; i++) { @@ -981,38 +935,21 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; scan->rx_chain = cpu_to_le16(rx_chain); - if (!priv->is_internal_short_scan) { - cmd_len = iwl_legacy_fill_probe_req(priv, + + cmd_len = iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, vif->addr, priv->scan_request->ie, priv->scan_request->ie_len, IWL_MAX_SCAN_SIZE - sizeof(*scan)); - } else { - /* use bcast addr, will not be transmitted but must be valid */ - cmd_len = iwl_legacy_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - iwlegacy_bcast_addr, NULL, 0, - IWL_MAX_SCAN_SIZE - sizeof(*scan)); - - } scan->tx_cmd.len = cpu_to_le16(cmd_len); scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | RXON_FILTER_BCON_AWARE_MSK); - if (priv->is_internal_short_scan) { - scan->channel_count = - iwl4965_get_single_channel_for_scan(priv, vif, band, - (void *)&scan->data[le16_to_cpu( - scan->tx_cmd.len)]); - } else { - scan->channel_count = - iwl4965_get_channels_for_scan(priv, vif, band, - is_active, n_probes, - (void *)&scan->data[le16_to_cpu( - scan->tx_cmd.len)]); - } + scan->channel_count = iwl4965_get_channels_for_scan(priv, vif, band, + is_active, n_probes, + (void *)&scan->data[cmd_len]); if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); return -EIO; diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index f59f588ca05..59a4b53218e 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -2149,7 +2149,6 @@ static struct iwl_base_params iwl4965_base_params = { .use_bsm = true, .led_compensation = 61, .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, .wd_timeout = IWL_DEF_WD_TIMEOUT, .temperature_kelvin = true, .max_event_log_size = 512, diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index 3be76bd5499..240d3a80c7b 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -1707,41 +1707,14 @@ iwl_legacy_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) EXPORT_SYMBOL(iwl_legacy_update_stats); #endif -static void _iwl_legacy_force_rf_reset(struct iwl_priv *priv) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!iwl_legacy_is_any_associated(priv)) { - IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); - return; - } - /* - * There is no easy and better way to force reset the radio, - * the only known method is switching channel which will force to - * reset and tune the radio. - * Use internal short scan (single channel) operation to should - * achieve this objective. - * Driver should reset the radio when number of consecutive missed - * beacon, or any other uCode error condition detected. - */ - IWL_DEBUG_INFO(priv, "perform radio reset.\n"); - iwl_legacy_internal_short_hw_scan(priv); -} - - -int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external) +int iwl_legacy_force_reset(struct iwl_priv *priv, bool external) { struct iwl_force_reset *force_reset; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EINVAL; - if (mode >= IWL_MAX_FORCE_RESET) { - IWL_DEBUG_INFO(priv, "invalid reset request.\n"); - return -EINVAL; - } - force_reset = &priv->force_reset[mode]; + force_reset = &priv->force_reset; force_reset->reset_request_count++; if (!external) { if (force_reset->last_force_reset_jiffies && @@ -1754,37 +1727,34 @@ int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external) } force_reset->reset_success_count++; force_reset->last_force_reset_jiffies = jiffies; - IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode); - switch (mode) { - case IWL_RF_RESET: - _iwl_legacy_force_rf_reset(priv); - break; - case IWL_FW_RESET: - /* - * if the request is from external(ex: debugfs), - * then always perform the request in regardless the module - * parameter setting - * if the request is from internal (uCode error or driver - * detect failure), then fw_restart module parameter - * need to be check before performing firmware reload - */ - if (!external && !priv->cfg->mod_params->restart_fw) { - IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " - "module parameter setting\n"); - break; - } - IWL_ERR(priv, "On demand firmware reload\n"); - /* Set the FW error flag -- cleared on iwl_down */ - set_bit(STATUS_FW_ERROR, &priv->status); - wake_up_interruptible(&priv->wait_command_queue); - /* - * Keep the restart process from trying to send host - * commands by clearing the INIT status bit - */ - clear_bit(STATUS_READY, &priv->status); - queue_work(priv->workqueue, &priv->restart); - break; + + /* + * if the request is from external(ex: debugfs), + * then always perform the request in regardless the module + * parameter setting + * if the request is from internal (uCode error or driver + * detect failure), then fw_restart module parameter + * need to be check before performing firmware reload + */ + + if (!external && !priv->cfg->mod_params->restart_fw) { + IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " + "module parameter setting\n"); + return 0; } + + IWL_ERR(priv, "On demand firmware reload\n"); + + /* Set the FW error flag -- cleared on iwl_down */ + set_bit(STATUS_FW_ERROR, &priv->status); + wake_up_interruptible(&priv->wait_command_queue); + /* + * Keep the restart process from trying to send host + * commands by clearing the INIT status bit + */ + clear_bit(STATUS_READY, &priv->status); + queue_work(priv->workqueue, &priv->restart); + return 0; } @@ -1879,7 +1849,7 @@ static int iwl_legacy_check_stuck_queue(struct iwl_priv *priv, int cnt) if (time_after(jiffies, timeout)) { IWL_ERR(priv, "Queue %d stuck for %u ms.\n", q->id, priv->cfg->base_params->wd_timeout); - ret = iwl_legacy_force_reset(priv, IWL_FW_RESET, false); + ret = iwl_legacy_force_reset(priv, false); return (ret == -EAGAIN) ? 0 : 1; } diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index a821bdbe3e1..8f766e94881 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -204,8 +204,6 @@ struct iwl_mod_params { * to the deviation to achieve the desired led frequency. * The detail algorithm is described in iwl-led.c * @chain_noise_num_beacons: number of beacons used to compute chain noise - * @plcp_delta_threshold: plcp error rate threshold used to trigger - * radio tuning when there is a high receiving plcp error rate * @wd_timeout: TX queues watchdog timeout * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging @@ -226,7 +224,6 @@ struct iwl_base_params { u16 led_compensation; int chain_noise_num_beacons; - u8 plcp_delta_threshold; unsigned int wd_timeout; bool temperature_kelvin; u32 max_event_log_size; @@ -438,7 +435,7 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv); -int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external); +int iwl_legacy_force_reset(struct iwl_priv *priv, bool external); u16 iwl_legacy_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, const u8 *ta, const u8 *ie, int ie_len, int left); diff --git a/drivers/net/wireless/iwlegacy/iwl-debugfs.c b/drivers/net/wireless/iwlegacy/iwl-debugfs.c index 2d32438b4cb..88ffc92ef0b 100644 --- a/drivers/net/wireless/iwlegacy/iwl-debugfs.c +++ b/drivers/net/wireless/iwlegacy/iwl-debugfs.c @@ -1236,72 +1236,31 @@ static ssize_t iwl_legacy_dbgfs_missed_beacon_write(struct file *file, return count; } -static ssize_t iwl_legacy_dbgfs_plcp_delta_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) { - - struct iwl_priv *priv = file->private_data; - int pos = 0; - char buf[12]; - const size_t bufsz = sizeof(buf); - - pos += scnprintf(buf + pos, bufsz - pos, "%u\n", - priv->cfg->base_params->plcp_delta_threshold); - - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); -} - -static ssize_t iwl_legacy_dbgfs_plcp_delta_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) { - - struct iwl_priv *priv = file->private_data; - char buf[8]; - int buf_size; - int plcp; - - memset(buf, 0, sizeof(buf)); - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - if (sscanf(buf, "%d", &plcp) != 1) - return -EINVAL; - if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || - (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) - priv->cfg->base_params->plcp_delta_threshold = - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; - else - priv->cfg->base_params->plcp_delta_threshold = plcp; - return count; -} - static ssize_t iwl_legacy_dbgfs_force_reset_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; - int i, pos = 0; + int pos = 0; char buf[300]; const size_t bufsz = sizeof(buf); struct iwl_force_reset *force_reset; - for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { - force_reset = &priv->force_reset[i]; - pos += scnprintf(buf + pos, bufsz - pos, - "Force reset method %d\n", i); - pos += scnprintf(buf + pos, bufsz - pos, - "\tnumber of reset request: %d\n", - force_reset->reset_request_count); - pos += scnprintf(buf + pos, bufsz - pos, - "\tnumber of reset request success: %d\n", - force_reset->reset_success_count); - pos += scnprintf(buf + pos, bufsz - pos, - "\tnumber of reset request reject: %d\n", - force_reset->reset_reject_count); - pos += scnprintf(buf + pos, bufsz - pos, - "\treset duration: %lu\n", - force_reset->reset_duration); - } + force_reset = &priv->force_reset; + + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request: %d\n", + force_reset->reset_request_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request success: %d\n", + force_reset->reset_success_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request reject: %d\n", + force_reset->reset_reject_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\treset duration: %lu\n", + force_reset->reset_duration); + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -1309,25 +1268,11 @@ static ssize_t iwl_legacy_dbgfs_force_reset_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { + int ret; struct iwl_priv *priv = file->private_data; - char buf[8]; - int buf_size; - int reset, ret; - memset(buf, 0, sizeof(buf)); - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - if (sscanf(buf, "%d", &reset) != 1) - return -EINVAL; - switch (reset) { - case IWL_RF_RESET: - case IWL_FW_RESET: - ret = iwl_legacy_force_reset(priv, reset, true); - break; - default: - return -EINVAL; - } + ret = iwl_legacy_force_reset(priv, true); + return ret ? ret : count; } @@ -1370,7 +1315,6 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); -DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); DEBUGFS_READ_WRITE_FILE_OPS(force_reset); DEBUGFS_READ_FILE_OPS(rxon_flags); DEBUGFS_READ_FILE_OPS(rxon_filter_flags); @@ -1420,7 +1364,6 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); - DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index ea30122669e..c5a135a7131 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -895,18 +895,6 @@ struct iwl_event_log { #define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) #define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) -/* - * This is the threshold value of plcp error rate per 100mSecs. It is - * used to set and check for the validity of plcp_delta. - */ -#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (1) -#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) -#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) -#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200) -#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) -#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) - -#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) /* TX queue watchdog timeouts in mSecs */ @@ -914,12 +902,6 @@ struct iwl_event_log { #define IWL_LONG_WD_TIMEOUT (10000) #define IWL_MAX_WD_TIMEOUT (120000) -enum iwl_reset { - IWL_RF_RESET = 0, - IWL_FW_RESET, - IWL_MAX_FORCE_RESET, -}; - struct iwl_force_reset { int reset_request_count; int reset_success_count; @@ -1032,11 +1014,8 @@ struct iwl_priv { /* track IBSS manager (last beacon) status */ u32 ibss_manager; - /* storing the jiffies when the plcp error rate is received */ - unsigned long plcp_jiffies; - /* force reset */ - struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; + struct iwl_force_reset force_reset; /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ @@ -1057,7 +1036,6 @@ struct iwl_priv { enum ieee80211_band scan_band; struct cfg80211_scan_request *scan_request; struct ieee80211_vif *scan_vif; - bool is_internal_short_scan; u8 scan_tx_ant[IEEE80211_NUM_BANDS]; u8 mgmt_tx_ant; @@ -1256,7 +1234,6 @@ struct iwl_priv { struct iwl_rxon_context *beacon_ctx; struct sk_buff *beacon_skb; - struct work_struct start_internal_scan; struct work_struct tx_flush; struct tasklet_struct irq_tasklet; diff --git a/drivers/net/wireless/iwlegacy/iwl-scan.c b/drivers/net/wireless/iwlegacy/iwl-scan.c index 353234a02c6..a6b5222fc59 100644 --- a/drivers/net/wireless/iwlegacy/iwl-scan.c +++ b/drivers/net/wireless/iwlegacy/iwl-scan.c @@ -101,7 +101,6 @@ static void iwl_legacy_complete_scan(struct iwl_priv *priv, bool aborted) ieee80211_scan_completed(priv->hw, aborted); } - priv->is_internal_short_scan = false; priv->scan_vif = NULL; priv->scan_request = NULL; } @@ -329,10 +328,8 @@ void iwl_legacy_init_scan_params(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_legacy_init_scan_params); -static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv, - struct ieee80211_vif *vif, - bool internal, - enum ieee80211_band band) +static int iwl_legacy_scan_initiate(struct iwl_priv *priv, + struct ieee80211_vif *vif) { int ret; @@ -359,18 +356,14 @@ static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv, return -EBUSY; } - IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", - internal ? "internal short " : ""); + IWL_DEBUG_SCAN(priv, "Starting scan...\n"); set_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = internal; priv->scan_start = jiffies; - priv->scan_band = band; ret = priv->cfg->ops->utils->request_scan(priv, vif); if (ret) { clear_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = false; return ret; } @@ -394,8 +387,7 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status) && - !priv->is_internal_short_scan) { + if (test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); ret = -EAGAIN; goto out_unlock; @@ -404,17 +396,9 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, /* mac80211 will only ask for one band at a time */ priv->scan_request = req; priv->scan_vif = vif; + priv->scan_band = req->channels[0]->band; - /* - * If an internal scan is in progress, just set - * up the scan_request as per above. - */ - if (priv->is_internal_short_scan) { - IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); - ret = 0; - } else - ret = iwl_legacy_scan_initiate(priv, vif, false, - req->channels[0]->band); + ret = iwl_legacy_scan_initiate(priv, vif); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -425,40 +409,6 @@ out_unlock: } EXPORT_SYMBOL(iwl_legacy_mac_hw_scan); -/* - * internal short scan, this function should only been called while associated. - * It will reset and tune the radio to prevent possible RF related problem - */ -void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv) -{ - queue_work(priv->workqueue, &priv->start_internal_scan); -} - -static void iwl_legacy_bg_start_internal_scan(struct work_struct *work) -{ - struct iwl_priv *priv = - container_of(work, struct iwl_priv, start_internal_scan); - - IWL_DEBUG_SCAN(priv, "Start internal scan\n"); - - mutex_lock(&priv->mutex); - - if (priv->is_internal_short_scan == true) { - IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); - goto unlock; - } - - if (test_bit(STATUS_SCANNING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); - goto unlock; - } - - if (iwl_legacy_scan_initiate(priv, NULL, true, priv->band)) - IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); - unlock: - mutex_unlock(&priv->mutex); -} - static void iwl_legacy_bg_scan_check(struct work_struct *data) { struct iwl_priv *priv = @@ -542,8 +492,7 @@ static void iwl_legacy_bg_scan_completed(struct work_struct *work) container_of(work, struct iwl_priv, scan_completed); bool aborted; - IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", - priv->is_internal_short_scan ? "internal short " : ""); + IWL_DEBUG_SCAN(priv, "Completed scan.\n"); cancel_delayed_work(&priv->scan_check); @@ -558,27 +507,6 @@ static void iwl_legacy_bg_scan_completed(struct work_struct *work) goto out_settings; } - if (priv->is_internal_short_scan && !aborted) { - int err; - - /* Check if mac80211 requested scan during our internal scan */ - if (priv->scan_request == NULL) - goto out_complete; - - /* If so request a new scan */ - err = iwl_legacy_scan_initiate(priv, priv->scan_vif, false, - priv->scan_request->channels[0]->band); - if (err) { - IWL_DEBUG_SCAN(priv, - "failed to initiate pending scan: %d\n", err); - aborted = true; - goto out_complete; - } - - goto out; - } - -out_complete: iwl_legacy_complete_scan(priv, aborted); out_settings: @@ -590,8 +518,7 @@ out_settings: * We do not commit power settings while scan is pending, * do it now if the settings changed. */ - iwl_legacy_power_set_mode(priv, &priv->power_data.sleep_cmd_next, - false); + iwl_legacy_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); priv->cfg->ops->utils->post_scan(priv); @@ -604,15 +531,12 @@ void iwl_legacy_setup_scan_deferred_work(struct iwl_priv *priv) { INIT_WORK(&priv->scan_completed, iwl_legacy_bg_scan_completed); INIT_WORK(&priv->abort_scan, iwl_legacy_bg_abort_scan); - INIT_WORK(&priv->start_internal_scan, - iwl_legacy_bg_start_internal_scan); INIT_DELAYED_WORK(&priv->scan_check, iwl_legacy_bg_scan_check); } EXPORT_SYMBOL(iwl_legacy_setup_scan_deferred_work); void iwl_legacy_cancel_scan_deferred_work(struct iwl_priv *priv) { - cancel_work_sync(&priv->start_internal_scan); cancel_work_sync(&priv->abort_scan); cancel_work_sync(&priv->scan_completed); diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index 0ee6be6a9c5..da42442106c 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -1762,49 +1762,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) #endif } -static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, - struct ieee80211_vif *vif, - enum ieee80211_band band, - struct iwl3945_scan_channel *scan_ch) -{ - const struct ieee80211_supported_band *sband; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added = 0; - u8 channel = 0; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) { - IWL_ERR(priv, "invalid band\n"); - return added; - } - - active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); - passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - - channel = iwl_legacy_get_single_channel_number(priv, band); - - if (channel) { - scan_ch->channel = channel; - scan_ch->type = 0; /* passive */ - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* Set txpower levels to defaults */ - scan_ch->tpc.dsp_atten = 110; - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); - added++; - } else - IWL_ERR(priv, "no valid channel found\n"); - return added; -} - static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, enum ieee80211_band band, u8 is_active, u8 n_probes, @@ -2816,6 +2773,7 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) enum ieee80211_band band; bool is_active = false; int ret; + u16 len; lockdep_assert_held(&priv->mutex); @@ -2834,17 +2792,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_time = IWL_ACTIVE_QUIET_TIME; if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { - u16 interval = 0; + u16 interval; u32 extra; u32 suspend_time = 100; u32 scan_suspend_time = 100; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - if (priv->is_internal_short_scan) - interval = 0; - else - interval = vif->bss_conf.beacon_int; + interval = vif->bss_conf.beacon_int; scan->suspend_time = 0; scan->max_out_time = cpu_to_le32(200 * 1024); @@ -2866,9 +2821,7 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan_suspend_time, interval); } - if (priv->is_internal_short_scan) { - IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); - } else if (priv->scan_request->n_ssids) { + if (priv->scan_request->n_ssids) { int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); for (i = 0; i < priv->scan_request->n_ssids; i++) { @@ -2919,36 +2872,17 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : IWL_GOOD_CRC_TH_DISABLED; - if (!priv->is_internal_short_scan) { - scan->tx_cmd.len = cpu_to_le16( - iwl_legacy_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - vif->addr, - priv->scan_request->ie, - priv->scan_request->ie_len, - IWL_MAX_SCAN_SIZE - sizeof(*scan))); - } else { - /* use bcast addr, will not be transmitted but must be valid */ - scan->tx_cmd.len = cpu_to_le16( - iwl_legacy_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - iwlegacy_bcast_addr, NULL, 0, - IWL_MAX_SCAN_SIZE - sizeof(*scan))); - } + len = iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, + vif->addr, priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + scan->tx_cmd.len = cpu_to_le16(len); + /* select Rx antennas */ scan->flags |= iwl3945_get_antenna_flags(priv); - if (priv->is_internal_short_scan) { - scan->channel_count = - iwl3945_get_single_channel_for_scan(priv, vif, band, - (void *)&scan->data[le16_to_cpu( - scan->tx_cmd.len)]); - } else { - scan->channel_count = - iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, - (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); - } - + scan->channel_count = iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, + (void *)&scan->data[len], vif); if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); return -EIO; @@ -3824,10 +3758,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; /* initialize force reset */ - priv->force_reset[IWL_RF_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_RF_RESET; - priv->force_reset[IWL_FW_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_FW_RELOAD; + priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 7157ba52968..ed86b221d06 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -3135,10 +3135,7 @@ static int iwl4965_init_drv(struct iwl_priv *priv) priv->_4965.agg_tids_count = 0; /* initialize force reset */ - priv->force_reset[IWL_RF_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_RF_RESET; - priv->force_reset[IWL_FW_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_FW_RELOAD; + priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; /* Choose which receivers/antennas to use */ if (priv->cfg->ops->hcmd->set_rxon_chain) -- cgit v1.2.3-70-g09d2 From 1ba2f121f9e1d98dd838644f76fa23837dd28913 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 8 Jun 2011 15:28:27 +0200 Subject: iwlegacy: remove firmware event log Messages like that iwl4965 0000:03:00.0: Start IWL Event Log Dump: display last 20 entries iwl4965 0000:03:00.0: EVT_LOGT:1821445332:0x00000000:1352 iwl4965 0000:03:00.0: EVT_LOGT:1821445332:0x00000001:1353 iwl4965 0000:03:00.0: EVT_LOGT:1821445336:0x0000000c:0357 iwl4965 0000:03:00.0: EVT_LOGT:1821445533:0x00000107:0106 iwl4965 0000:03:00.0: EVT_LOGT:1821445534:0x00000000:0302 iwl4965 0000:03:00.0: EVT_LOGT:1821445574:0x000000d4:0321 iwl4965 0000:03:00.0: EVT_LOGT:1821445575:0x00000000:1350 iwl4965 0000:03:00.0: EVT_LOGT:1821445576:0x00000000:1351 iwl4965 0000:03:00.0: EVT_LOGT:1821445576:0x00000000:1352 iwl4965 0000:03:00.0: EVT_LOGT:1821445577:0x00000001:1353 iwl4965 0000:03:00.0: EVT_LOGT:1821445581:0x0000000d:0357 iwl4965 0000:03:00.0: EVT_LOGT:1821446327:0x00000107:0106 iwl4965 0000:03:00.0: EVT_LOGT:1821446328:0x00000000:0302 iwl4965 0000:03:00.0: EVT_LOGT:1821446368:0x000000d4:0321 iwl4965 0000:03:00.0: EVT_LOGT:1821446369:0x00000000:1350 iwl4965 0000:03:00.0: EVT_LOGT:1821446370:0x00000000:1351 iwl4965 0000:03:00.0: EVT_LOGT:1821446370:0x00000000:1352 iwl4965 0000:03:00.0: EVT_LOGT:1821446371:0x00000001:1353 iwl4965 0000:03:00.0: EVT_LOGT:1821446375:0x0000000e:0357 iwl4965 0000:03:00.0: EVT_LOGT:1821446383:0x00000000:0125 are completely useless for me. Remove bunch of code that generate them. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-3945.c | 2 - drivers/net/wireless/iwlegacy/iwl-4965.c | 2 - drivers/net/wireless/iwlegacy/iwl-core.c | 1 - drivers/net/wireless/iwlegacy/iwl-core.h | 7 +- drivers/net/wireless/iwlegacy/iwl-debugfs.c | 97 -------- drivers/net/wireless/iwlegacy/iwl-dev.h | 29 --- drivers/net/wireless/iwlegacy/iwl-devtrace.c | 3 - drivers/net/wireless/iwlegacy/iwl-devtrace.h | 60 ----- drivers/net/wireless/iwlegacy/iwl3945-base.c | 206 ---------------- drivers/net/wireless/iwlegacy/iwl4965-base.c | 336 --------------------------- 10 files changed, 1 insertion(+), 742 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c index 8aa018dfa46..dab67a12d73 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -2639,7 +2639,6 @@ static struct iwl_lib_ops iwl3945_lib = { .txq_free_tfd = iwl3945_hw_txq_free_tfd, .txq_init = iwl3945_hw_tx_queue_init, .load_ucode = iwl3945_load_bsm, - .dump_nic_event_log = iwl3945_dump_nic_event_log, .dump_nic_error_log = iwl3945_dump_nic_error_log, .apm_ops = { .init = iwl3945_apm_init, @@ -2698,7 +2697,6 @@ static struct iwl_base_params iwl3945_base_params = { .use_bsm = true, .led_compensation = 64, .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 512, }; static struct iwl_cfg iwl3945_bg_cfg = { diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index 59a4b53218e..bd4b000733f 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -2069,7 +2069,6 @@ static struct iwl_lib_ops iwl4965_lib = { .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, .init_alive_start = iwl4965_init_alive_start, .load_ucode = iwl4965_load_bsm, - .dump_nic_event_log = iwl4965_dump_nic_event_log, .dump_nic_error_log = iwl4965_dump_nic_error_log, .dump_fh = iwl4965_dump_fh, .set_channel_switch = iwl4965_hw_channel_switch, @@ -2151,7 +2150,6 @@ static struct iwl_base_params iwl4965_base_params = { .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, .wd_timeout = IWL_DEF_WD_TIMEOUT, .temperature_kelvin = true, - .max_event_log_size = 512, .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index 240d3a80c7b..35cd2537e7f 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -931,7 +931,6 @@ void iwl_legacy_irq_handle_error(struct iwl_priv *priv) priv->cfg->ops->lib->dump_nic_error_log(priv); if (priv->cfg->ops->lib->dump_fh) priv->cfg->ops->lib->dump_fh(priv, NULL, false); - priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG if (iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) iwl_legacy_print_rx_config_cmd(priv, diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index 8f766e94881..a2de7e99170 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -143,8 +143,7 @@ struct iwl_lib_ops { int (*is_valid_rtc_data_addr)(u32 addr); /* 1st ucode load */ int (*load_ucode)(struct iwl_priv *priv); - int (*dump_nic_event_log)(struct iwl_priv *priv, - bool full_log, char **buf, bool display); + void (*dump_nic_error_log)(struct iwl_priv *priv); int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); int (*set_channel_switch)(struct iwl_priv *priv, @@ -206,7 +205,6 @@ struct iwl_mod_params { * @chain_noise_num_beacons: number of beacons used to compute chain noise * @wd_timeout: TX queues watchdog timeout * @temperature_kelvin: temperature report by uCode in kelvin - * @max_event_log_size: size of event log buffer size for ucode event logging * @ucode_tracing: support ucode continuous tracing * @sensitivity_calib_by_driver: driver has the capability to perform * sensitivity calibration operation @@ -226,7 +224,6 @@ struct iwl_base_params { int chain_noise_num_beacons; unsigned int wd_timeout; bool temperature_kelvin; - u32 max_event_log_size; const bool ucode_tracing; const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; @@ -515,8 +512,6 @@ extern const struct dev_pm_ops iwl_legacy_pm_ops; * Error Handling Debugging ******************************************************/ void iwl4965_dump_nic_error_log(struct iwl_priv *priv); -int iwl4965_dump_nic_event_log(struct iwl_priv *priv, - bool full_log, char **buf, bool display); #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG void iwl_legacy_print_rx_config_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); diff --git a/drivers/net/wireless/iwlegacy/iwl-debugfs.c b/drivers/net/wireless/iwlegacy/iwl-debugfs.c index 88ffc92ef0b..996996a7165 100644 --- a/drivers/net/wireless/iwlegacy/iwl-debugfs.c +++ b/drivers/net/wireless/iwlegacy/iwl-debugfs.c @@ -391,48 +391,6 @@ static ssize_t iwl_legacy_dbgfs_nvm_read(struct file *file, return ret; } -static ssize_t iwl_legacy_dbgfs_log_event_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - char *buf; - int pos = 0; - ssize_t ret = -ENOMEM; - - ret = pos = priv->cfg->ops->lib->dump_nic_event_log( - priv, true, &buf, true); - if (buf) { - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - } - return ret; -} - -static ssize_t iwl_legacy_dbgfs_log_event_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - u32 event_log_flag; - char buf[8]; - int buf_size; - - memset(buf, 0, sizeof(buf)); - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - if (sscanf(buf, "%d", &event_log_flag) != 1) - return -EFAULT; - if (event_log_flag == 1) - priv->cfg->ops->lib->dump_nic_event_log(priv, true, - NULL, false); - - return count; -} - - - static ssize_t iwl_legacy_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -706,7 +664,6 @@ static ssize_t iwl_legacy_dbgfs_disable_ht40_read(struct file *file, } DEBUGFS_READ_WRITE_FILE_OPS(sram); -DEBUGFS_READ_WRITE_FILE_OPS(log_event); DEBUGFS_READ_FILE_OPS(nvm); DEBUGFS_READ_FILE_OPS(stations); DEBUGFS_READ_FILE_OPS(channels); @@ -1098,56 +1055,6 @@ static ssize_t iwl_legacy_dbgfs_clear_ucode_statistics_write(struct file *file, return count; } -static ssize_t iwl_legacy_dbgfs_ucode_tracing_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) { - - struct iwl_priv *priv = file->private_data; - int pos = 0; - char buf[128]; - const size_t bufsz = sizeof(buf); - - pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", - priv->event_log.ucode_trace ? "On" : "Off"); - pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", - priv->event_log.non_wraps_count); - pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", - priv->event_log.wraps_once_count); - pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", - priv->event_log.wraps_more_count); - - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); -} - -static ssize_t iwl_legacy_dbgfs_ucode_tracing_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - char buf[8]; - int buf_size; - int trace; - - memset(buf, 0, sizeof(buf)); - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - if (sscanf(buf, "%d", &trace) != 1) - return -EFAULT; - - if (trace) { - priv->event_log.ucode_trace = true; - /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ - mod_timer(&priv->ucode_trace, - jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); - } else { - priv->event_log.ucode_trace = false; - del_timer_sync(&priv->ucode_trace); - } - - return count; -} - static ssize_t iwl_legacy_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1312,7 +1219,6 @@ DEBUGFS_READ_FILE_OPS(chain_noise); DEBUGFS_READ_FILE_OPS(power_save_status); DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); -DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); DEBUGFS_READ_WRITE_FILE_OPS(force_reset); @@ -1347,7 +1253,6 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); @@ -1373,8 +1278,6 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); - if (priv->cfg->base_params->ucode_tracing) - DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index c5a135a7131..fd792e15fab 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -854,32 +854,6 @@ struct traffic_stats { #endif }; -/* - * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds - * to perform continuous uCode event logging operation if enabled - */ -#define UCODE_TRACE_PERIOD (100) - -/* - * iwl_event_log: current uCode event log position - * - * @ucode_trace: enable/disable ucode continuous trace timer - * @num_wraps: how many times the event buffer wraps - * @next_entry: the entry just before the next one that uCode would fill - * @non_wraps_count: counter for no wrap detected when dump ucode events - * @wraps_once_count: counter for wrap once detected when dump ucode events - * @wraps_more_count: counter for wrap more than once detected - * when dump ucode events - */ -struct iwl_event_log { - bool ucode_trace; - u32 num_wraps; - u32 next_entry; - int non_wraps_count; - int wraps_once_count; - int wraps_more_count; -}; - /* * host interrupt timeout value * used with setting interrupt coalescing timer @@ -1270,12 +1244,9 @@ struct iwl_priv { u32 disable_tx_power_cal; struct work_struct run_time_calib_work; struct timer_list statistics_periodic; - struct timer_list ucode_trace; struct timer_list watchdog; bool hw_ready; - struct iwl_event_log event_log; - struct led_classdev led; unsigned long blink_on, blink_off; bool led_registered; diff --git a/drivers/net/wireless/iwlegacy/iwl-devtrace.c b/drivers/net/wireless/iwlegacy/iwl-devtrace.c index 080b852b33b..acec99197ce 100644 --- a/drivers/net/wireless/iwlegacy/iwl-devtrace.c +++ b/drivers/net/wireless/iwlegacy/iwl-devtrace.c @@ -38,8 +38,5 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ioread32); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite32); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_rx); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_tx); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_event); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_error); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_cont_event); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_wrap_event); #endif diff --git a/drivers/net/wireless/iwlegacy/iwl-devtrace.h b/drivers/net/wireless/iwlegacy/iwl-devtrace.h index 9612aa0f6ec..a443725ba6b 100644 --- a/drivers/net/wireless/iwlegacy/iwl-devtrace.h +++ b/drivers/net/wireless/iwlegacy/iwl-devtrace.h @@ -96,47 +96,6 @@ TRACE_EVENT(iwlwifi_legacy_dev_iowrite32, #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_legacy_ucode -TRACE_EVENT(iwlwifi_legacy_dev_ucode_cont_event, - TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), - TP_ARGS(priv, time, data, ev), - TP_STRUCT__entry( - PRIV_ENTRY - - __field(u32, time) - __field(u32, data) - __field(u32, ev) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->time = time; - __entry->data = data; - __entry->ev = ev; - ), - TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", - __entry->priv, __entry->time, __entry->data, __entry->ev) -); - -TRACE_EVENT(iwlwifi_legacy_dev_ucode_wrap_event, - TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry), - TP_ARGS(priv, wraps, n_entry, p_entry), - TP_STRUCT__entry( - PRIV_ENTRY - - __field(u32, wraps) - __field(u32, n_entry) - __field(u32, p_entry) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->wraps = wraps; - __entry->n_entry = n_entry; - __entry->p_entry = p_entry; - ), - TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X", - __entry->priv, __entry->wraps, __entry->n_entry, - __entry->p_entry) -); - #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi @@ -242,25 +201,6 @@ TRACE_EVENT(iwlwifi_legacy_dev_ucode_error, __entry->blink2, __entry->ilink1, __entry->ilink2) ); -TRACE_EVENT(iwlwifi_legacy_dev_ucode_event, - TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), - TP_ARGS(priv, time, data, ev), - TP_STRUCT__entry( - PRIV_ENTRY - - __field(u32, time) - __field(u32, data) - __field(u32, ev) - ), - TP_fast_assign( - PRIV_ASSIGN; - __entry->time = time; - __entry->data = data; - __entry->ev = ev; - ), - TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", - __entry->priv, __entry->time, __entry->data, __entry->ev) -); #endif /* __IWLWIFI_DEVICE_TRACE */ #undef TRACE_INCLUDE_PATH diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index da42442106c..795826a014e 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -1409,212 +1409,6 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv) } } -#define EVENT_START_OFFSET (6 * sizeof(u32)) - -/** - * iwl3945_print_event_log - Dump error event log to syslog - * - */ -static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, - u32 num_events, u32 mode, - int pos, char **buf, size_t bufsz) -{ - u32 i; - u32 base; /* SRAM byte address of event log header */ - u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ - u32 ptr; /* SRAM byte address of log data */ - u32 ev, time, data; /* event log data */ - unsigned long reg_flags; - - if (num_events == 0) - return pos; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - - if (mode == 0) - event_size = 2 * sizeof(u32); - else - event_size = 3 * sizeof(u32); - - ptr = base + EVENT_START_OFFSET + (start_idx * event_size); - - /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - - /* Set starting address; reads will auto-increment */ - _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); - rmb(); - - /* "time" is actually "data" for mode 0 (no timestamp). - * place event id # at far right for easier visual parsing. */ - for (i = 0; i < num_events; i++) { - ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); - time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (mode == 0) { - /* data, ev */ - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "0x%08x:%04u\n", - time, ev); - } else { - IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); - trace_iwlwifi_legacy_dev_ucode_event(priv, 0, - time, ev); - } - } else { - data = _iwl_legacy_read_direct32(priv, - HBUS_TARG_MEM_RDAT); - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "%010u:0x%08x:%04u\n", - time, data, ev); - } else { - IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", - time, data, ev); - trace_iwlwifi_legacy_dev_ucode_event(priv, time, - data, ev); - } - } - } - - /* Allow device to power down */ - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return pos; -} - -/** - * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog - */ -static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, - u32 num_wraps, u32 next_entry, - u32 size, u32 mode, - int pos, char **buf, size_t bufsz) -{ - /* - * display the newest DEFAULT_LOG_ENTRIES entries - * i.e the entries just before the next ont that uCode would fill. - */ - if (num_wraps) { - if (next_entry < size) { - pos = iwl3945_print_event_log(priv, - capacity - (size - next_entry), - size - next_entry, mode, - pos, buf, bufsz); - pos = iwl3945_print_event_log(priv, 0, - next_entry, mode, - pos, buf, bufsz); - } else - pos = iwl3945_print_event_log(priv, next_entry - size, - size, mode, - pos, buf, bufsz); - } else { - if (next_entry < size) - pos = iwl3945_print_event_log(priv, 0, - next_entry, mode, - pos, buf, bufsz); - else - pos = iwl3945_print_event_log(priv, next_entry - size, - size, mode, - pos, buf, bufsz); - } - return pos; -} - -#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) - -int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, - char **buf, bool display) -{ - u32 base; /* SRAM byte address of event log header */ - u32 capacity; /* event log capacity in # entries */ - u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ - u32 num_wraps; /* # times uCode wrapped to top of log */ - u32 next_entry; /* index of next entry to be written by uCode */ - u32 size; /* # entries that we'll print */ - int pos = 0; - size_t bufsz = 0; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl3945_hw_valid_rtc_data_addr(base)) { - IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); - return -EINVAL; - } - - /* event log header */ - capacity = iwl_legacy_read_targ_mem(priv, base); - mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); - num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); - next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); - - if (capacity > priv->cfg->base_params->max_event_log_size) { - IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", - capacity, priv->cfg->base_params->max_event_log_size); - capacity = priv->cfg->base_params->max_event_log_size; - } - - if (next_entry > priv->cfg->base_params->max_event_log_size) { - IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", - next_entry, priv->cfg->base_params->max_event_log_size); - next_entry = priv->cfg->base_params->max_event_log_size; - } - - size = num_wraps ? capacity : next_entry; - - /* bail out if nothing in log */ - if (size == 0) { - IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); - return pos; - } - -#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG - if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) - size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; -#else - size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; -#endif - - IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", - size); - -#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG - if (display) { - if (full_log) - bufsz = capacity * 48; - else - bufsz = size * 48; - *buf = kmalloc(bufsz, GFP_KERNEL); - if (!*buf) - return -ENOMEM; - } - if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { - /* if uCode has wrapped back to top of log, - * start at the oldest entry, - * i.e the next one that uCode would fill. - */ - if (num_wraps) - pos = iwl3945_print_event_log(priv, next_entry, - capacity - next_entry, mode, - pos, buf, bufsz); - - /* (then/else) start at top of log */ - pos = iwl3945_print_event_log(priv, 0, next_entry, mode, - pos, buf, bufsz); - } else - pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#else - pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#endif - return pos; -} - static void iwl3945_irq_tasklet(struct iwl_priv *priv) { u32 inta, handled = 0; diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index ed86b221d06..98e42a11b71 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -488,134 +488,6 @@ static void iwl4965_bg_statistics_periodic(unsigned long data) iwl_legacy_send_statistics_request(priv, CMD_ASYNC, false); } - -static void iwl4965_print_cont_event_trace(struct iwl_priv *priv, u32 base, - u32 start_idx, u32 num_events, - u32 mode) -{ - u32 i; - u32 ptr; /* SRAM byte address of log data */ - u32 ev, time, data; /* event log data */ - unsigned long reg_flags; - - if (mode == 0) - ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32)); - else - ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); - - /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&priv->reg_lock, reg_flags); - if (iwl_grab_nic_access(priv)) { - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return; - } - - /* Set starting address; reads will auto-increment */ - _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); - rmb(); - - /* - * "time" is actually "data" for mode 0 (no timestamp). - * place event id # at far right for easier visual parsing. - */ - for (i = 0; i < num_events; i++) { - ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); - time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (mode == 0) { - trace_iwlwifi_legacy_dev_ucode_cont_event(priv, - 0, time, ev); - } else { - data = _iwl_legacy_read_direct32(priv, - HBUS_TARG_MEM_RDAT); - trace_iwlwifi_legacy_dev_ucode_cont_event(priv, - time, data, ev); - } - } - /* Allow device to power down */ - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} - -static void iwl4965_continuous_event_trace(struct iwl_priv *priv) -{ - u32 capacity; /* event log capacity in # entries */ - u32 base; /* SRAM byte address of event log header */ - u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ - u32 num_wraps; /* # times uCode wrapped to top of log */ - u32 next_entry; /* index of next entry to be written by uCode */ - - if (priv->ucode_type == UCODE_INIT) - base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); - else - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { - capacity = iwl_legacy_read_targ_mem(priv, base); - num_wraps = iwl_legacy_read_targ_mem(priv, - base + (2 * sizeof(u32))); - mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); - next_entry = iwl_legacy_read_targ_mem(priv, - base + (3 * sizeof(u32))); - } else - return; - - if (num_wraps == priv->event_log.num_wraps) { - iwl4965_print_cont_event_trace(priv, - base, priv->event_log.next_entry, - next_entry - priv->event_log.next_entry, - mode); - priv->event_log.non_wraps_count++; - } else { - if ((num_wraps - priv->event_log.num_wraps) > 1) - priv->event_log.wraps_more_count++; - else - priv->event_log.wraps_once_count++; - trace_iwlwifi_legacy_dev_ucode_wrap_event(priv, - num_wraps - priv->event_log.num_wraps, - next_entry, priv->event_log.next_entry); - if (next_entry < priv->event_log.next_entry) { - iwl4965_print_cont_event_trace(priv, base, - priv->event_log.next_entry, - capacity - priv->event_log.next_entry, - mode); - - iwl4965_print_cont_event_trace(priv, base, 0, - next_entry, mode); - } else { - iwl4965_print_cont_event_trace(priv, base, - next_entry, capacity - next_entry, - mode); - - iwl4965_print_cont_event_trace(priv, base, 0, - next_entry, mode); - } - } - priv->event_log.num_wraps = num_wraps; - priv->event_log.next_entry = next_entry; -} - -/** - * iwl4965_bg_ucode_trace - Timer callback to log ucode event - * - * The timer is continually set to execute every - * UCODE_TRACE_PERIOD milliseconds after the last timer expired - * this function is to perform continuous uCode event logging operation - * if enabled - */ -static void iwl4965_bg_ucode_trace(unsigned long data) -{ - struct iwl_priv *priv = (struct iwl_priv *)data; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (priv->event_log.ucode_trace) { - iwl4965_continuous_event_trace(priv); - /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */ - mod_timer(&priv->ucode_trace, - jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); - } -} - static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -1711,209 +1583,6 @@ void iwl4965_dump_nic_error_log(struct iwl_priv *priv) pc, blink1, blink2, ilink1, ilink2, hcmd); } -#define EVENT_START_OFFSET (4 * sizeof(u32)) - -/** - * iwl4965_print_event_log - Dump error event log to syslog - * - */ -static int iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx, - u32 num_events, u32 mode, - int pos, char **buf, size_t bufsz) -{ - u32 i; - u32 base; /* SRAM byte address of event log header */ - u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ - u32 ptr; /* SRAM byte address of log data */ - u32 ev, time, data; /* event log data */ - unsigned long reg_flags; - - if (num_events == 0) - return pos; - - if (priv->ucode_type == UCODE_INIT) { - base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); - } else { - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - } - - if (mode == 0) - event_size = 2 * sizeof(u32); - else - event_size = 3 * sizeof(u32); - - ptr = base + EVENT_START_OFFSET + (start_idx * event_size); - - /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - - /* Set starting address; reads will auto-increment */ - _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); - rmb(); - - /* "time" is actually "data" for mode 0 (no timestamp). - * place event id # at far right for easier visual parsing. */ - for (i = 0; i < num_events; i++) { - ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); - time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (mode == 0) { - /* data, ev */ - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "EVT_LOG:0x%08x:%04u\n", - time, ev); - } else { - trace_iwlwifi_legacy_dev_ucode_event(priv, 0, - time, ev); - IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", - time, ev); - } - } else { - data = _iwl_legacy_read_direct32(priv, - HBUS_TARG_MEM_RDAT); - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "EVT_LOGT:%010u:0x%08x:%04u\n", - time, data, ev); - } else { - IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", - time, data, ev); - trace_iwlwifi_legacy_dev_ucode_event(priv, time, - data, ev); - } - } - } - - /* Allow device to power down */ - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return pos; -} - -/** - * iwl4965_print_last_event_logs - Dump the newest # of event log to syslog - */ -static int iwl4965_print_last_event_logs(struct iwl_priv *priv, u32 capacity, - u32 num_wraps, u32 next_entry, - u32 size, u32 mode, - int pos, char **buf, size_t bufsz) -{ - /* - * display the newest DEFAULT_LOG_ENTRIES entries - * i.e the entries just before the next ont that uCode would fill. - */ - if (num_wraps) { - if (next_entry < size) { - pos = iwl4965_print_event_log(priv, - capacity - (size - next_entry), - size - next_entry, mode, - pos, buf, bufsz); - pos = iwl4965_print_event_log(priv, 0, - next_entry, mode, - pos, buf, bufsz); - } else - pos = iwl4965_print_event_log(priv, next_entry - size, - size, mode, pos, buf, bufsz); - } else { - if (next_entry < size) { - pos = iwl4965_print_event_log(priv, 0, next_entry, - mode, pos, buf, bufsz); - } else { - pos = iwl4965_print_event_log(priv, next_entry - size, - size, mode, pos, buf, bufsz); - } - } - return pos; -} - -#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) - -int iwl4965_dump_nic_event_log(struct iwl_priv *priv, bool full_log, - char **buf, bool display) -{ - u32 base; /* SRAM byte address of event log header */ - u32 capacity; /* event log capacity in # entries */ - u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ - u32 num_wraps; /* # times uCode wrapped to top of log */ - u32 next_entry; /* index of next entry to be written by uCode */ - u32 size; /* # entries that we'll print */ - int pos = 0; - size_t bufsz = 0; - - if (priv->ucode_type == UCODE_INIT) { - base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); - } else { - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - } - - if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { - IWL_ERR(priv, - "Invalid event log pointer 0x%08X for %s uCode\n", - base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); - return -EINVAL; - } - - /* event log header */ - capacity = iwl_legacy_read_targ_mem(priv, base); - mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); - num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); - next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); - - size = num_wraps ? capacity : next_entry; - - /* bail out if nothing in log */ - if (size == 0) { - IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); - return pos; - } - -#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG - if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) - size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; -#else - size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; -#endif - IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", - size); - -#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG - if (display) { - if (full_log) - bufsz = capacity * 48; - else - bufsz = size * 48; - *buf = kmalloc(bufsz, GFP_KERNEL); - if (!*buf) - return -ENOMEM; - } - if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { - /* - * if uCode has wrapped back to top of log, - * start at the oldest entry, - * i.e the next one that uCode would fill. - */ - if (num_wraps) - pos = iwl4965_print_event_log(priv, next_entry, - capacity - next_entry, mode, - pos, buf, bufsz); - /* (then/else) start at top of log */ - pos = iwl4965_print_event_log(priv, 0, - next_entry, mode, pos, buf, bufsz); - } else - pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#else - pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#endif - return pos; -} - static void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; @@ -3034,10 +2703,6 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv) priv->statistics_periodic.data = (unsigned long)priv; priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; - init_timer(&priv->ucode_trace); - priv->ucode_trace.data = (unsigned long)priv; - priv->ucode_trace.function = iwl4965_bg_ucode_trace; - init_timer(&priv->watchdog); priv->watchdog.data = (unsigned long)priv; priv->watchdog.function = iwl_legacy_bg_watchdog; @@ -3056,7 +2721,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) iwl_legacy_cancel_scan_deferred_work(priv); del_timer_sync(&priv->statistics_periodic); - del_timer_sync(&priv->ucode_trace); } static void iwl4965_init_hw_rates(struct iwl_priv *priv, -- cgit v1.2.3-70-g09d2 From 0d01550f3dec4efc8e88bdefb27b9fa7522603f7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 8 Jun 2011 15:28:28 +0200 Subject: iwlegacy: remove unused agg_tids_count Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-dev.h | 6 ------ drivers/net/wireless/iwlegacy/iwl4965-base.c | 11 ----------- 2 files changed, 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index fd792e15fab..62e8cc07f04 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -1164,12 +1164,6 @@ struct iwl_priv { #endif #if defined(CONFIG_IWL4965) || defined(CONFIG_IWL4965_MODULE) struct { - /* - * reporting the number of tids has AGG on. 0 means - * no AGGREGATION - */ - u8 agg_tids_count; - struct iwl_rx_phy_res last_phy_res; bool last_phy_res_valid; diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 98e42a11b71..c0ea858d03b 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -2442,20 +2442,10 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_START: IWL_DEBUG_HT(priv, "start Tx\n"); ret = iwl4965_tx_agg_start(priv, vif, sta, tid, ssn); - if (ret == 0) { - priv->_4965.agg_tids_count++; - IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", - priv->_4965.agg_tids_count); - } break; case IEEE80211_AMPDU_TX_STOP: IWL_DEBUG_HT(priv, "stop Tx\n"); ret = iwl4965_tx_agg_stop(priv, vif, sta, tid); - if ((ret == 0) && (priv->_4965.agg_tids_count > 0)) { - priv->_4965.agg_tids_count--; - IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", - priv->_4965.agg_tids_count); - } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) ret = 0; break; @@ -2796,7 +2786,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv) priv->iw_mode = NL80211_IFTYPE_STATION; priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; - priv->_4965.agg_tids_count = 0; /* initialize force reset */ priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; -- cgit v1.2.3-70-g09d2 From 7f1f974251493d3929ebd422796e6f9f2bcd6956 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 8 Jun 2011 15:28:29 +0200 Subject: iwlegacy: refactor iwl4965_mac_channel_switch Use less indentions and remove uneeded irq-save flags. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl4965-base.c | 111 +++++++++++++-------------- 1 file changed, 55 insertions(+), 56 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index c0ea858d03b..49a80bb7063 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -2510,7 +2510,6 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u16 ch; - unsigned long flags = 0; IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -2527,64 +2526,64 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, if (!iwl_legacy_is_associated_ctx(ctx)) goto out; - if (priv->cfg->ops->lib->set_channel_switch) { + if (priv->cfg->ops->lib->set_channel_switch) + goto out; - ch = channel->hw_value; - if (le16_to_cpu(ctx->active.channel) != ch) { - ch_info = iwl_legacy_get_channel_info(priv, - channel->band, - ch); - if (!iwl_legacy_is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "invalid channel\n"); - goto out; - } - spin_lock_irqsave(&priv->lock, flags); - - priv->current_ht_config.smps = conf->smps_mode; - - /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) { - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } - } else - ctx->ht.is_40mhz = false; - - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; - - iwl_legacy_set_rxon_channel(priv, channel, ctx); - iwl_legacy_set_rxon_ht(priv, ht_conf); - iwl_legacy_set_flags_for_band(priv, ctx, channel->band, - ctx->vif); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_legacy_set_rate(priv); - /* - * at this point, staging_rxon has the - * configuration for channel switch - */ - set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); - priv->switch_channel = cpu_to_le16(ch); - if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { - clear_bit(STATUS_CHANNEL_SWITCH_PENDING, - &priv->status); - priv->switch_channel = 0; - ieee80211_chswitch_done(ctx->vif, false); - } + ch = channel->hw_value; + if (le16_to_cpu(ctx->active.channel) == ch) + goto out; + + ch_info = iwl_legacy_get_channel_info(priv, channel->band, ch); + if (!iwl_legacy_is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "invalid channel\n"); + goto out; + } + + spin_lock(&priv->lock); + + priv->current_ht_config.smps = conf->smps_mode; + + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; } + } else + ctx->ht.is_40mhz = false; + + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_legacy_set_rxon_channel(priv, channel, ctx); + iwl_legacy_set_rxon_ht(priv, ht_conf); + iwl_legacy_set_flags_for_band(priv, ctx, channel->band, ctx->vif); + + spin_unlock_irq(&priv->lock); + + iwl_legacy_set_rate(priv); + /* + * at this point, staging_rxon has the + * configuration for channel switch + */ + set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); + priv->switch_channel = cpu_to_le16(ch); + if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { + clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); + priv->switch_channel = 0; + ieee80211_chswitch_done(ctx->vif, false); } + out: mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); -- cgit v1.2.3-70-g09d2 From 287546df342daaa146c840ce26b3ed012a055de5 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 8 Jun 2011 20:39:20 +0530 Subject: mwifiex: get rid of global adapter pointer 1) Avoid global adapter pointer usage a) in sdio.c by moving some code from mwifiex_cleanup_module() to mwifiex_sdio_remove(). b) in main.c by passing an extra parameter to few functions. 2) Add new variable "user_rmmod" to identify if mwifiex_sdio_remove() callback function is called in card removal or rmmod context. These code changes are adapted from Libertas driver. 3) Remove unnecessary NULL pointer check for "func" pointer in mwifiex_sdio_remove(). Signed-off-by: Amitkumar Karwar Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 16 +++----- drivers/net/wireless/mwifiex/main.h | 1 - drivers/net/wireless/mwifiex/sdio.c | 81 +++++++++++++++++++++++-------------- 3 files changed, 56 insertions(+), 42 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 4f43443036f..054a5c348a2 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -26,9 +26,6 @@ const char driver_version[] = "mwifiex " VERSION " (%s) "; -struct mwifiex_adapter *g_adapter; -EXPORT_SYMBOL_GPL(g_adapter); - static struct mwifiex_bss_attr mwifiex_bss_sta[] = { {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0}, }; @@ -60,7 +57,8 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { * proper cleanup before exiting. */ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, - struct mwifiex_drv_mode *drv_mode_ptr) + struct mwifiex_drv_mode *drv_mode_ptr, + void **padapter) { struct mwifiex_adapter *adapter; int i; @@ -69,7 +67,7 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, if (!adapter) return -ENOMEM; - g_adapter = adapter; + *padapter = adapter; adapter->card = card; /* Save interface specific operations in adapter */ @@ -324,7 +322,7 @@ exit_main_proc: * and initializing the private structures. */ static int -mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) +mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter) { int i; struct mwifiex_drv_mode *drv_mode_ptr; @@ -343,7 +341,7 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) return -1; } - if (mwifiex_register(card, if_ops, drv_mode_ptr)) + if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter)) return -1; return 0; @@ -855,13 +853,11 @@ mwifiex_add_card(void *card, struct semaphore *sem, if (down_interruptible(sem)) goto exit_sem_err; - if (mwifiex_init_sw(card, if_ops)) { + if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) { pr_err("%s: software init failed\n", __func__); goto err_init_sw; } - adapter = g_adapter; - adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; adapter->surprise_removed = false; init_waitqueue_head(&adapter->init_wait_q); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 57b183af72d..db201cc1473 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -39,7 +39,6 @@ #include "fw.h" extern const char driver_version[]; -extern struct mwifiex_adapter *g_adapter; enum { MWIFIEX_ASYNC_CMD, diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 4327b6d099c..711fa689a95 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -31,10 +31,27 @@ #define SDIO_VERSION "1.0" +/* The mwifiex_sdio_remove() callback function is called when + * user removes this module from kernel space or ejects + * the card from the slot. The driver handles these 2 cases + * differently. + * If the user is removing the module, the few commands (FUNC_SHUTDOWN, + * HS_CANCEL etc.) are sent to the firmware. + * If the card is removed, there is no need to send these command. + * + * The variable 'user_rmmod' is used to distinguish these two + * scenarios. This flag is initialized as FALSE in case the card + * is removed, and will be set to TRUE for module removal when + * module_exit function is called. + */ +static u8 user_rmmod; + static struct mwifiex_if_ops sdio_ops; static struct semaphore add_remove_card_sem; +static int mwifiex_sdio_resume(struct device *dev); + /* * SDIO probe. * @@ -93,17 +110,36 @@ static void mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; + struct mwifiex_adapter *adapter; + int i; pr_debug("info: SDIO func num=%d\n", func->num); - if (func) { - card = sdio_get_drvdata(func); - if (card) { - mwifiex_remove_card(card->adapter, - &add_remove_card_sem); - kfree(card); - } + card = sdio_get_drvdata(func); + if (!card) + return; + + adapter = card->adapter; + if (!adapter || !adapter->priv_num) + return; + + if (user_rmmod) { + if (adapter->is_suspended) + mwifiex_sdio_resume(adapter->dev); + + for (i = 0; i < adapter->priv_num; i++) + if ((GET_BSS_ROLE(adapter->priv[i]) == + MWIFIEX_BSS_ROLE_STA) && + adapter->priv[i]->media_connected) + mwifiex_deauthenticate(adapter->priv[i], NULL); + + mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), + MWIFIEX_FUNC_SHUTDOWN); } + + mwifiex_remove_card(card->adapter, &add_remove_card_sem); + kfree(card); } /* @@ -1696,6 +1732,9 @@ mwifiex_sdio_init_module(void) { sema_init(&add_remove_card_sem, 1); + /* Clear the flag in case user removes the card. */ + user_rmmod = 0; + return sdio_register_driver(&mwifiex_sdio); } @@ -1711,32 +1750,12 @@ mwifiex_sdio_init_module(void) static void mwifiex_sdio_cleanup_module(void) { - struct mwifiex_adapter *adapter = g_adapter; - int i; - - if (down_interruptible(&add_remove_card_sem)) - goto exit_sem_err; - - if (!adapter || !adapter->priv_num) - goto exit; - - if (adapter->is_suspended) - mwifiex_sdio_resume(adapter->dev); - - for (i = 0; i < adapter->priv_num; i++) - if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) - mwifiex_deauthenticate(adapter->priv[i], NULL); - - if (!adapter->surprise_removed) - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + if (!down_interruptible(&add_remove_card_sem)) + up(&add_remove_card_sem); -exit: - up(&add_remove_card_sem); + /* Set the flag as user is removing this module. */ + user_rmmod = 1; -exit_sem_err: sdio_unregister_driver(&mwifiex_sdio); } -- cgit v1.2.3-70-g09d2 From 5b49b35a671e59c16c33611ea2d5650438388663 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 Jun 2011 10:09:34 +0300 Subject: b43: check for allocation failures Add some error handling if the allocation fails. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 6 +++++- drivers/net/wireless/b43/main.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 6c63aecd6ab..8a10b82f8ea 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -83,7 +83,11 @@ void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer, struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) { - struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct b43_bus_dev *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; dev->bus_type = B43_BUS_SSB; dev->sdev = sdev; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1d8d98324d1..7aed9a0eabc 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -5025,6 +5025,8 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) int first = 0; dev = b43_bus_dev_ssb_init(sdev); + if (!dev) + return -ENOMEM; wl = ssb_get_devtypedata(sdev); if (!wl) { -- cgit v1.2.3-70-g09d2 From 7101f4043cdaa5dc2bf8974313744246f3955de7 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 10 Jun 2011 11:05:23 -0500 Subject: rtlwifi: Fix warnings on parisc arch In "Build regressions/improvements in v3.0-rc2", Geert Uytterhoeven reports a number of warnings that occur for parisc builds of rtlwifi and dependents. Reported-by: Geert Uytterhoeven Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/reg.h | 6 +----- drivers/net/wireless/rtlwifi/wifi.h | 2 +- 6 files changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index d2ec2535aa3..605514bdd24 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -650,7 +650,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, ("BSS_CHANGED_HT\n")); rcu_read_lock(); - sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); + sta = get_sta(hw, vif, bss_conf->bssid); if (sta) { if (sta->ht_cap.ampdu_density > mac->current_ampdu_density) @@ -685,7 +685,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_network_type(hw, vif->type); rcu_read_lock(); - sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); + sta = get_sta(hw, vif, bss_conf->bssid); if (!sta) { rcu_read_unlock(); goto out; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 97183829b9b..57d52e914f1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -670,7 +670,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; int i; bool is2t = IS_92C_SERIAL(rtlhal->version); - u8 txpwr_level[2] = {0, 0}; + s8 txpwr_level[2] = {0, 0}; u8 ofdm_min_index = 6, rf; rtlpriv->dm.txpower_trackinginit = true; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 2492cc234c0..be375214ad9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -225,7 +225,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct phy_sts_cck_8192s_t *cck_buf; - s8 rx_pwr_all, rx_pwr[4]; + s8 rx_pwr_all = 0, rx_pwr[4]; u8 evm, pwdb_all, rf_rx_num = 0; u8 i, max_spatial_stream; u32 rssi, total_rssi = 0; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 35dd12d0dcf..5fab47b2218 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -516,7 +516,7 @@ static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw) mdelay(10); /* check GPIO3 */ - u1tmp = rtl_read_byte(rtlpriv, GPIO_IN); + u1tmp = rtl_read_byte(rtlpriv, GPIO_IN_SE); retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF; return retval; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index 0116eaddbfa..ea32ef2d409 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -248,12 +248,8 @@ #define PSTIME 0x02E0 #define TIMER0 0x02E4 #define TIMER1 0x02E8 -#define GPIO_CTRL 0x02EC -#define GPIO_IN 0x02EC -#define GPIO_OUT 0x02ED +#define GPIO_IN_SE 0x02EC #define GPIO_IO_SEL 0x02EE -#define GPIO_MOD 0x02EF -#define GPIO_INTCTRL 0x02F0 #define MAC_PINMUX_CFG 0x02F1 #define LEDCFG 0x02F2 #define PHY_REG 0x02F3 diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 9d003e0864f..fcf2c9f5437 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1983,7 +1983,7 @@ static inline u16 rtl_get_tid(struct sk_buff *skb) static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u8 *bssid) + const u8 *bssid) { return ieee80211_find_sta(vif, bssid); } -- cgit v1.2.3-70-g09d2 From 49b72100165e3b2046be15a8e4f766f5169e708d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 30 May 2011 10:29:37 -0700 Subject: iwlagn: usersapce application decide the size of trace buffer For testmode trace function, allow userspace application to request the size of trace buffer. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-sv-open.c | 28 ++++++++++++++++++++++------ drivers/net/wireless/iwlwifi/iwl-testmode.h | 7 +++++-- 3 files changed, 29 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c8de236c141..a7d2159537a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1170,6 +1170,8 @@ enum iwl_scan_type { #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL struct iwl_testmode_trace { + u32 buff_size; + u32 total_size; u8 *cpu_addr; u8 *trace_addr; dma_addr_t dma_addr; diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 69b7e6bf2d6..135c1b5f25a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -69,7 +69,6 @@ #include #include - #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-debug.h" @@ -102,8 +101,10 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, }, [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, + }; /* @@ -185,13 +186,15 @@ static void iwl_trace_cleanup(struct iwl_priv *priv) if (priv->testmode_trace.cpu_addr && priv->testmode_trace.dma_addr) dma_free_coherent(dev, - TRACE_TOTAL_SIZE, + priv->testmode_trace.total_size, priv->testmode_trace.cpu_addr, priv->testmode_trace.dma_addr); priv->testmode_trace.trace_enabled = false; priv->testmode_trace.cpu_addr = NULL; priv->testmode_trace.trace_addr = NULL; priv->testmode_trace.dma_addr = 0; + priv->testmode_trace.buff_size = 0; + priv->testmode_trace.total_size = 0; } } @@ -489,9 +492,22 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) if (priv->testmode_trace.trace_enabled) return -EBUSY; + if (!tb[IWL_TM_ATTR_TRACE_SIZE]) + priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF; + else + priv->testmode_trace.buff_size = + nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]); + if (!priv->testmode_trace.buff_size) + return -EINVAL; + if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN || + priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX) + return -EINVAL; + + priv->testmode_trace.total_size = + priv->testmode_trace.buff_size + TRACE_BUFF_PADD; priv->testmode_trace.cpu_addr = dma_alloc_coherent(dev, - TRACE_TOTAL_SIZE, + priv->testmode_trace.total_size, &priv->testmode_trace.dma_addr, GFP_KERNEL); if (!priv->testmode_trace.cpu_addr) @@ -500,7 +516,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN( priv->testmode_trace.cpu_addr, 0x100); memset(priv->testmode_trace.trace_addr, 0x03B, - TRACE_BUFF_SIZE); + priv->testmode_trace.buff_size); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, sizeof(priv->testmode_trace.dma_addr) + 20); if (!skb) { @@ -528,14 +544,14 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) if (priv->testmode_trace.trace_enabled && priv->testmode_trace.trace_addr) { skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, - 20 + TRACE_BUFF_SIZE); + 20 + priv->testmode_trace.buff_size); if (skb == NULL) { IWL_DEBUG_INFO(priv, "Error allocating memory\n"); return -ENOMEM; } NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA, - TRACE_BUFF_SIZE, + priv->testmode_trace.buff_size, priv->testmode_trace.trace_addr); status = cfg80211_testmode_reply(skb); if (status < 0) { diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index a88085e9b36..f3f406e1766 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -167,6 +167,7 @@ enum iwl_tm_attr_t { */ IWL_TM_ATTR_TRACE_ADDR, IWL_TM_ATTR_TRACE_DATA, + IWL_TM_ATTR_TRACE_SIZE, /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, * The mandatory fields are: @@ -178,8 +179,10 @@ enum iwl_tm_attr_t { }; /* uCode trace buffer */ -#define TRACE_BUFF_SIZE 0x20000 +#define TRACE_BUFF_SIZE_MAX 0x200000 +#define TRACE_BUFF_SIZE_MIN 0x20000 +#define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN + #define TRACE_BUFF_PADD 0x2000 -#define TRACE_TOTAL_SIZE (TRACE_BUFF_SIZE + TRACE_BUFF_PADD) #endif -- cgit v1.2.3-70-g09d2 From eb64dca0c9d73e191026ed37d1075f22e48b3f1c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 31 May 2011 08:03:02 -0700 Subject: iwlagn: add dumpit support for testmode trace function For testmode trace function, huge amout of data need to pass to userspace. Use the build-in nl80211 dumpt it function Require nl80211 testmode dumpit support patch. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.h | 10 +++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-sv-open.c | 106 +++++++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-testmode.h | 4 +- 5 files changed, 96 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 099c2795ec0..6f1edb4f388 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3352,6 +3352,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .offchannel_tx = iwl_mac_offchannel_tx, .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, CFG80211_TESTMODE_CMD(iwl_testmode_cmd) + CFG80211_TESTMODE_DUMP(iwl_testmode_dump) }; static u32 iwl_hw_detect(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d1716844002..d074e6c7a57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -343,6 +343,9 @@ extern int iwl_alive_start(struct iwl_priv *priv); /* svtool */ #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); +extern int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, + struct netlink_callback *cb, + void *data, int len); extern void iwl_testmode_init(struct iwl_priv *priv); extern void iwl_testmode_cleanup(struct iwl_priv *priv); #else @@ -352,6 +355,13 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) return -ENOSYS; } static inline +int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, + struct netlink_callback *cb, + void *data, int len) +{ + return -ENOSYS; +} +static inline void iwl_testmode_init(struct iwl_priv *priv) { } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index a7d2159537a..d23430e1000 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1172,6 +1172,7 @@ enum iwl_scan_type { struct iwl_testmode_trace { u32 buff_size; u32 total_size; + u32 num_chunks; u8 *cpu_addr; u8 *trace_addr; dma_addr_t dma_addr; diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 135c1b5f25a..038c6961c46 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -100,7 +100,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, - [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, }, [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, @@ -534,34 +534,14 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) "Error sending msg : %d\n", status); } + priv->testmode_trace.num_chunks = + DIV_ROUND_UP(priv->testmode_trace.buff_size, + TRACE_CHUNK_SIZE); break; case IWL_TM_CMD_APP2DEV_END_TRACE: iwl_trace_cleanup(priv); break; - - case IWL_TM_CMD_APP2DEV_READ_TRACE: - if (priv->testmode_trace.trace_enabled && - priv->testmode_trace.trace_addr) { - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, - 20 + priv->testmode_trace.buff_size); - if (skb == NULL) { - IWL_DEBUG_INFO(priv, - "Error allocating memory\n"); - return -ENOMEM; - } - NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA, - priv->testmode_trace.buff_size, - priv->testmode_trace.trace_addr); - status = cfg80211_testmode_reply(skb); - if (status < 0) { - IWL_DEBUG_INFO(priv, - "Error sending msg : %d\n", status); - } - } else - return -EFAULT; - break; - default: IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n"); return -ENOSYS; @@ -576,6 +556,37 @@ nla_put_failure: return -EMSGSIZE; } +static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, + struct sk_buff *skb, + struct netlink_callback *cb) +{ + struct iwl_priv *priv = hw->priv; + int idx, length; + + if (priv->testmode_trace.trace_enabled && + priv->testmode_trace.trace_addr) { + idx = cb->args[4]; + if (idx >= priv->testmode_trace.num_chunks) + return -ENOENT; + length = TRACE_CHUNK_SIZE; + if (((idx + 1) == priv->testmode_trace.num_chunks) && + (priv->testmode_trace.buff_size % TRACE_CHUNK_SIZE)) + length = priv->testmode_trace.buff_size % + TRACE_CHUNK_SIZE; + + NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length, + priv->testmode_trace.trace_addr + + (TRACE_CHUNK_SIZE * idx)); + idx++; + cb->args[4] = idx; + return 0; + } else + return -EFAULT; + + nla_put_failure: + return -ENOBUFS; +} + /* The testmode gnl message handler that takes the gnl message from the * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then * invoke the corresponding handlers. @@ -654,3 +665,50 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) mutex_unlock(&priv->mutex); return result; } + +int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, + struct netlink_callback *cb, + void *data, int len) +{ + struct nlattr *tb[IWL_TM_ATTR_MAX]; + struct iwl_priv *priv = hw->priv; + int result; + u32 cmd; + + if (cb->args[3]) { + /* offset by 1 since commands start at 0 */ + cmd = cb->args[3] - 1; + } else { + result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, + iwl_testmode_gnl_msg_policy); + if (result) { + IWL_DEBUG_INFO(priv, + "Error parsing the gnl message : %d\n", result); + return result; + } + + /* IWL_TM_ATTR_COMMAND is absolutely mandatory */ + if (!tb[IWL_TM_ATTR_COMMAND]) { + IWL_DEBUG_INFO(priv, + "Error finding testmode command type\n"); + return -ENOMSG; + } + cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); + cb->args[3] = cmd + 1; + } + + /* in case multiple accesses to the device happens */ + mutex_lock(&priv->mutex); + switch (cmd) { + case IWL_TM_CMD_APP2DEV_READ_TRACE: + IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); + result = iwl_testmode_trace_dump(hw, tb, skb, cb); + break; + default: + result = -EINVAL; + break; + } + + mutex_unlock(&priv->mutex); + return result; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index f3f406e1766..160911a3716 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -166,8 +166,8 @@ enum iwl_tm_attr_t { * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address */ IWL_TM_ATTR_TRACE_ADDR, - IWL_TM_ATTR_TRACE_DATA, IWL_TM_ATTR_TRACE_SIZE, + IWL_TM_ATTR_TRACE_DUMP, /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, * The mandatory fields are: @@ -182,7 +182,7 @@ enum iwl_tm_attr_t { #define TRACE_BUFF_SIZE_MAX 0x200000 #define TRACE_BUFF_SIZE_MIN 0x20000 #define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN - #define TRACE_BUFF_PADD 0x2000 +#define TRACE_CHUNK_SIZE (PAGE_SIZE - 1024) #endif -- cgit v1.2.3-70-g09d2 From b60eec9bf07307ad40e9304d39eb9107acb2fb0c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 13:52:38 -0700 Subject: iwlagn: move bt_coex_active as part of iwlagn_mod_params Move bt_coex_active module parameter into iwlagn_mod_params structure along with all the other iwlagn module parameters Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 +++- drivers/net/wireless/iwlwifi/iwl-agn.c | 20 ++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 23 +---------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- 4 files changed, 25 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 677f73c4c1e..f0dacfbe8e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -622,6 +622,7 @@ struct iwl_mod_params iwlagn_mod_params = { .amsdu_size_8K = 1, .restart_fw = 1, .plcp_check = true, + .bt_coex_active = true, /* the rest are 0 by default */ }; @@ -1699,7 +1700,8 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) * (might be in monitor mode), or the interface is in * IBSS mode (no proper uCode support for coex then). */ - if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { + if (!iwlagn_mod_params.bt_coex_active || + priv->iw_mode == NL80211_IFTYPE_ADHOC) { basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; } else { basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6f1edb4f388..6ecee3cafca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4075,3 +4075,23 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); + +/* + * set bt_coex_active to true, uCode will do kill/defer + * every time the priority line is asserted (BT is sending signals on the + * priority line in the PCIx). + * set bt_coex_active to false, uCode will ignore the BT activity and + * perform the normal operation + * + * User might experience transmit issue on some platform due to WiFi/BT + * co-exist problem. The possible behaviors are: + * Able to scan and finding all the available AP + * Not able to associate with any AP + * On those platforms, WiFi communication can be restored by set + * "bt_coex_active" module parameter to "false" + * + * default: bt_coex_active = true (BT_COEX_ENABLE) + */ +module_param_named(bt_coex_active, iwlagn_mod_params.bt_coex_active, + bool, S_IRUGO); +MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5416b12cd93..ad54f82597c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -43,27 +43,6 @@ #include "iwl-helpers.h" #include "iwl-agn.h" - -/* - * set bt_coex_active to true, uCode will do kill/defer - * every time the priority line is asserted (BT is sending signals on the - * priority line in the PCIx). - * set bt_coex_active to false, uCode will ignore the BT activity and - * perform the normal operation - * - * User might experience transmit issue on some platform due to WiFi/BT - * co-exist problem. The possible behaviors are: - * Able to scan and finding all the available AP - * Not able to associate with any AP - * On those platforms, WiFi communication can be restored by set - * "bt_coex_active" module parameter to "false" - * - * default: bt_coex_active = true (BT_COEX_ENABLE) - */ -bool bt_coex_active = true; -module_param(bt_coex_active, bool, S_IRUGO); -MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); - u32 iwl_debug_level; const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -1179,7 +1158,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) .kill_cts_mask = 0, }; - if (!bt_coex_active) + if (!iwlagn_mod_params.bt_coex_active) bt_cmd.flags = BT_COEX_DISABLE; else bt_cmd.flags = BT_COEX_ENABLE; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 05ea88aa76e..1a43a629683 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -173,6 +173,7 @@ struct iwl_mod_params { int restart_fw; /* def: 1 = restart firmware */ bool plcp_check; /* def: true = enable plcp health check */ bool ack_check; /* def: false = disable ack health check */ + bool bt_coex_active; /* def: true = enable bt coex */ }; /* @@ -624,7 +625,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) priv->cfg->bt_params->advanced_bt_coexist; } -extern bool bt_coex_active; extern bool bt_siso_mode; -- cgit v1.2.3-70-g09d2 From 6b0184c4c62beb15443fd6dd5080f0e18941b67b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 13:52:39 -0700 Subject: iwlagn: move led_mode as part of iwlagn_mod_params Move led_mode module parameter into iwlagn_mod_params structure along with all the other iwlagn module parameters Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-led.c | 9 ++------- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6ecee3cafca..32683568d39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4095,3 +4095,7 @@ MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); module_param_named(bt_coex_active, iwlagn_mod_params.bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); + +module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO); +MODULE_PARM_DESC(led_mode, "0=system default, " + "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 1a43a629683..f950da02b21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -174,6 +174,7 @@ struct iwl_mod_params { bool plcp_check; /* def: true = enable plcp health check */ bool ack_check; /* def: false = disable ack health check */ bool bt_coex_active; /* def: true = enable bt coex */ + int led_mode; /* def: 0 = system default */ }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 7c23beb49d7..1a8ce4a8f82 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -40,14 +40,9 @@ #include "iwl-dev.h" #include "iwl-core.h" +#include "iwl-agn.h" #include "iwl-io.h" -/* default: IWL_LED_BLINK(0) using blinking index table */ -static int led_mode; -module_param(led_mode, int, S_IRUGO); -MODULE_PARM_DESC(led_mode, "0=system default, " - "1=On(RF On)/Off(RF Off), 2=blinking"); - /* Throughput OFF time(ms) ON time (ms) * >300 25 25 * >200 to 300 40 40 @@ -181,7 +176,7 @@ static int iwl_led_blink_set(struct led_classdev *led_cdev, void iwl_leds_init(struct iwl_priv *priv) { - int mode = led_mode; + int mode = iwlagn_mod_params.led_mode; int ret; if (mode == IWL_LED_DEFAULT) -- cgit v1.2.3-70-g09d2 From 3f1e5f4a2b0993b6e81b5665b28568624f581b0f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Jun 2011 13:52:40 -0700 Subject: iwlagn: move no_sleep_autoadjust as part of iwlagn_mod_params Move no_sleep_autoadjust module parameter into iwlagn_mod_params structure along with all the other iwlagn module parameters Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-power.c | 13 ++----------- 4 files changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f0dacfbe8e9..58f6da0acfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -623,6 +623,7 @@ struct iwl_mod_params iwlagn_mod_params = { .restart_fw = 1, .plcp_check = true, .bt_coex_active = true, + .no_sleep_autoadjust = true, /* the rest are 0 by default */ }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 32683568d39..8bed31539c5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4099,3 +4099,13 @@ MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO); MODULE_PARM_DESC(led_mode, "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)"); + +/* + * For now, keep using power level 1 instead of automatically + * adjusting ... + */ +module_param_named(no_sleep_autoadjust, iwlagn_mod_params.no_sleep_autoadjust, + bool, S_IRUGO); +MODULE_PARM_DESC(no_sleep_autoadjust, + "don't automatically adjust sleep level " + "according to maximum network latency (default: true)"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f950da02b21..a16daf72e67 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -175,6 +175,7 @@ struct iwl_mod_params { bool ack_check; /* def: false = disable ack health check */ bool bt_coex_active; /* def: true = enable bt coex */ int led_mode; /* def: 0 = system default */ + bool no_sleep_autoadjust; /* def: true = disable autoadjust */ }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 595c930b28a..a69b5512417 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -36,6 +36,7 @@ #include "iwl-eeprom.h" #include "iwl-dev.h" +#include "iwl-agn.h" #include "iwl-core.h" #include "iwl-io.h" #include "iwl-commands.h" @@ -50,16 +51,6 @@ * also use pre-defined power levels. */ -/* - * For now, keep using power level 1 instead of automatically - * adjusting ... - */ -bool no_sleep_autoadjust = true; -module_param(no_sleep_autoadjust, bool, S_IRUGO); -MODULE_PARM_DESC(no_sleep_autoadjust, - "don't automatically adjust sleep level " - "according to maximum network latency"); - /* * This defines the old power levels. They are still used by default * (level 1) and for thermal throttle (levels 3 through 5) @@ -367,7 +358,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, iwl_static_sleep_cmd(priv, cmd, priv->power_data.debug_sleep_level_override, dtimper); - else if (no_sleep_autoadjust) + else if (iwlagn_mod_params.no_sleep_autoadjust) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper); else iwl_power_fill_sleep_cmd(priv, cmd, -- cgit v1.2.3-70-g09d2 From 872907bb17fe2d8d01d0e9723f72f91cb4ea103f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 6 Jun 2011 09:41:15 -0700 Subject: iwlagn: don't check ucode subtype The ucode subtypes keep changing, and there's no particular reason to be checking them (other than a paranoid sanity check). Since the numbers are also in conflict between different ucode images now, simply don't check them any more and rely on the images being built correctly. Also, to indicate that, rename the constants and the enum, moving it to a different file. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 19 +++++-------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 15 ++++++--------- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 12 ------------ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 9 ++++++++- drivers/net/wireless/iwlwifi/iwl-sv-open.c | 5 ++--- 7 files changed, 23 insertions(+), 41 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 97de5d9de67..a5cb1f63563 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -602,12 +602,12 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, struct fw_img *image, - int subtype, int alternate_subtype) + enum iwlagn_ucode_type ucode_type) { struct iwl_notification_wait alive_wait; struct iwlagn_alive_data alive_data; int ret; - enum iwlagn_ucode_subtype old_type; + enum iwlagn_ucode_type old_type; ret = iwlagn_start_device(priv); if (ret) @@ -617,7 +617,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, iwlagn_alive_fn, &alive_data); old_type = priv->ucode_type; - priv->ucode_type = subtype; + priv->ucode_type = ucode_type; ret = iwlagn_load_given_ucode(priv, image); if (ret) { @@ -645,15 +645,6 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, return -EIO; } - if (alive_data.subtype != subtype && - alive_data.subtype != alternate_subtype) { - IWL_ERR(priv, - "Loaded ucode is not expected type (got %d, expected %d)!\n", - alive_data.subtype, subtype); - priv->ucode_type = old_type; - return -EIO; - } - ret = iwl_verify_ucode(priv, image); if (ret) { priv->ucode_type = old_type; @@ -685,7 +676,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) if (!priv->ucode_init.code.len) return 0; - if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED) + if (priv->ucode_type != IWL_UCODE_NONE) return 0; iwlagn_init_notification_wait(priv, &calib_wait, @@ -694,7 +685,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) /* Will also start the device */ ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, - UCODE_SUBTYPE_INIT, -1); + IWL_UCODE_INIT); if (ret) goto error; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8bed31539c5..3cd42a52095 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1626,7 +1626,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) struct iwl_error_event_table table; base = priv->device_pointers.error_event_table; - if (priv->ucode_type == UCODE_SUBTYPE_INIT) { + if (priv->ucode_type == IWL_UCODE_INIT) { if (!base) base = priv->_agn.init_errlog_ptr; } else { @@ -1638,7 +1638,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) IWL_ERR(priv, "Not valid error log pointer 0x%08X for %s uCode\n", base, - (priv->ucode_type == UCODE_SUBTYPE_INIT) + (priv->ucode_type == IWL_UCODE_INIT) ? "Init" : "RT"); return; } @@ -1702,7 +1702,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, return pos; base = priv->device_pointers.log_event_table; - if (priv->ucode_type == UCODE_SUBTYPE_INIT) { + if (priv->ucode_type == IWL_UCODE_INIT) { if (!base) base = priv->_agn.init_evtlog_ptr; } else { @@ -1815,7 +1815,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, size_t bufsz = 0; base = priv->device_pointers.log_event_table; - if (priv->ucode_type == UCODE_SUBTYPE_INIT) { + if (priv->ucode_type == IWL_UCODE_INIT) { logsize = priv->_agn.init_evtlog_size; if (!base) base = priv->_agn.init_evtlog_ptr; @@ -1829,7 +1829,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, IWL_ERR(priv, "Invalid event log pointer 0x%08X for %s uCode\n", base, - (priv->ucode_type == UCODE_SUBTYPE_INIT) + (priv->ucode_type == IWL_UCODE_INIT) ? "Init" : "RT"); return -EINVAL; } @@ -2210,8 +2210,7 @@ static int __iwl_up(struct iwl_priv *priv) ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_rt, - UCODE_SUBTYPE_REGULAR, - UCODE_SUBTYPE_REGULAR_NEW); + IWL_UCODE_REGULAR); if (ret) { IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); goto error; @@ -3448,8 +3447,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv = hw->priv; /* At this point both hw and priv are allocated. */ - priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED; - /* * The default context is always valid, * more may be discovered when firmware diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d074e6c7a57..94ee1416fb9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -161,7 +161,7 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv); int iwlagn_run_init_ucode(struct iwl_priv *priv); int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, struct fw_img *image, - int subtype, int alternate_subtype); + enum iwlagn_ucode_type ucode_type); /* lib */ void iwl_check_abort_status(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 6ee5f1aa555..8dcb2108bce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -384,18 +384,6 @@ struct iwl_tx_ant_config_cmd { #define UCODE_VALID_OK cpu_to_le32(0x1) -enum iwlagn_ucode_subtype { - UCODE_SUBTYPE_REGULAR = 0, - UCODE_SUBTYPE_REGULAR_NEW = 1, - UCODE_SUBTYPE_INIT = 9, - - /* - * Not a valid subtype, the ucode has just a u8, so - * we can use something > 0xff for this value. - */ - UCODE_SUBTYPE_NONE_LOADED = 0x100, -}; - /** * REPLY_ALIVE = 0x1 (response only, not a command) * diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 0e6a04b739a..5f335c7815b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -227,7 +227,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, /* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { priv->dbgfs_sram_offset = 0x800000; - if (priv->ucode_type == UCODE_SUBTYPE_INIT) + if (priv->ucode_type == IWL_UCODE_INIT) priv->dbgfs_sram_len = priv->ucode_init.data.len; else priv->dbgfs_sram_len = priv->ucode_rt.data.len; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index d23430e1000..ffed30207e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1168,6 +1168,13 @@ enum iwl_scan_type { IWL_SCAN_OFFCH_TX, }; +enum iwlagn_ucode_type { + IWL_UCODE_NONE, + IWL_UCODE_REGULAR, + IWL_UCODE_INIT, + IWL_UCODE_WOWLAN, +}; + #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL struct iwl_testmode_trace { u32 buff_size; @@ -1273,7 +1280,7 @@ struct iwl_priv { struct fw_img ucode_rt; struct fw_img ucode_init; - enum iwlagn_ucode_subtype ucode_type; + enum iwlagn_ucode_type ucode_type; u8 ucode_write_complete; /* the image write is complete */ char firmware_name[25]; diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 038c6961c46..6f626425144 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -397,7 +397,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, - UCODE_SUBTYPE_INIT, -1); + IWL_UCODE_INIT); if (status) IWL_DEBUG_INFO(priv, "Error loading init ucode: %d\n", status); @@ -411,8 +411,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_rt, - UCODE_SUBTYPE_REGULAR, - UCODE_SUBTYPE_REGULAR_NEW); + IWL_UCODE_REGULAR); if (status) { IWL_DEBUG_INFO(priv, "Error loading runtime ucode: %d\n", status); -- cgit v1.2.3-70-g09d2 From 052692976e40bc124a8615ec880dd83046d71c24 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 12:05:45 -0700 Subject: iwlagn: Band capabilities in EEPROM Add define for band capabilities in EEPROM Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index c960c6fa009..508631888c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -110,12 +110,13 @@ enum { }; /* SKU Capabilities */ -/* 5000 and up */ #define EEPROM_SKU_CAP_BAND_POS (4) #define EEPROM_SKU_CAP_BAND_SELECTION \ (3 << EEPROM_SKU_CAP_BAND_POS) +#define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) +#define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) -#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) +#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) /* *regulatory* channel data format in eeprom, one for each channel. -- cgit v1.2.3-70-g09d2 From 8895075886bbcfdab6ad7923ae8ab3b3314549c4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 12:05:46 -0700 Subject: iwlagn: use sku capabilities information from EEPROM Instead of having the separated define, use the sku capabilities in EEPROM Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 9 +-------- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-core.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-core.h | 6 +----- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 3 --- 6 files changed, 12 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 2ef9448b1c2..512d8beb3df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -108,18 +108,11 @@ err: int iwl_eeprom_check_sku(struct iwl_priv *priv) { - u16 eeprom_sku; u16 radio_cfg; - eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); - if (!priv->cfg->sku) { /* not using sku overwrite */ - priv->cfg->sku = - ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >> - EEPROM_SKU_CAP_BAND_POS); - if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE) - priv->cfg->sku |= IWL_SKU_N; + priv->cfg->sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); } if (!priv->cfg->sku) { IWL_ERR(priv, "Invalid device sku\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 58f6da0acfd..90cd647088a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1532,7 +1532,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) memset(&flush_cmd, 0, sizeof(flush_cmd)); flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK | IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK; - if (priv->cfg->sku & IWL_SKU_N) + if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", @@ -2318,7 +2318,8 @@ int iwlagn_start_device(struct iwl_priv *priv) { int ret; - if (iwl_prepare_card_hw(priv)) { + if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) && + iwl_prepare_card_hw(priv)) { IWL_WARN(priv, "Exit HW not ready\n"); return -EIO; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3cd42a52095..488081fe183 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2515,7 +2515,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; - if (priv->cfg->sku & IWL_SKU_N) + if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; @@ -2756,7 +2756,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", sta->addr, tid); - if (!(priv->cfg->sku & IWL_SKU_N)) + if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) return -EACCES; mutex_lock(&priv->mutex); @@ -3375,7 +3375,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; if (iwlagn_mod_params.disable_11n) - priv->cfg->sku &= ~IWL_SKU_N; + priv->cfg->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; /* Device-specific setup */ return priv->cfg->ops->lib->set_hw_params(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index ad54f82597c..445ddac0654 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -143,7 +143,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; - if (priv->cfg->sku & IWL_SKU_N) + if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_5GHZ); @@ -153,7 +153,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) sband->bitrates = rates; sband->n_bitrates = IWL_RATE_COUNT_LEGACY; - if (priv->cfg->sku & IWL_SKU_N) + if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_2GHZ); @@ -208,12 +208,12 @@ int iwlcore_init_geos(struct iwl_priv *priv) priv->tx_power_next = max_tx_power; if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && - priv->cfg->sku & IWL_SKU_A) { + priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) { IWL_INFO(priv, "Incorrectly detected BG card as ABG. " "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n", priv->pci_dev->device, priv->pci_dev->subsystem_device); - priv->cfg->sku &= ~IWL_SKU_A; + priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; } IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a16daf72e67..83ec5eb64ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -83,10 +83,6 @@ struct iwl_cmd; #define TIME_UNIT 1024 -#define IWL_SKU_G 0x1 -#define IWL_SKU_A 0x2 -#define IWL_SKU_N 0x8 - #define IWL_CMD(x) case x: return #x struct iwl_hcmd_ops { @@ -292,7 +288,7 @@ struct iwl_cfg { const unsigned int ucode_api_min; u8 valid_tx_ant; u8 valid_rx_ant; - unsigned int sku; + u16 sku; u16 eeprom_ver; u16 eeprom_calib_ver; const struct iwl_ops *ops; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 508631888c1..2d7005385be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -110,9 +110,6 @@ enum { }; /* SKU Capabilities */ -#define EEPROM_SKU_CAP_BAND_POS (4) -#define EEPROM_SKU_CAP_BAND_SELECTION \ - (3 << EEPROM_SKU_CAP_BAND_POS) #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) -- cgit v1.2.3-70-g09d2 From ebbb491e8efac3c0a6f880f676374fc1605469f5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 12:49:24 -0700 Subject: iwlagn: add coex debug flag Replace IWL_DEBUG_AP with IWL_DEBUG_COEX for debug COEX related stuffs Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-debug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 2824ccbcc1f..fd68ce89bb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -131,7 +131,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) #define IWL_DL_ASSOC (1 << 12) #define IWL_DL_DROP (1 << 13) #define IWL_DL_TXPOWER (1 << 14) -#define IWL_DL_AP (1 << 15) +#define IWL_DL_COEX (1 << 15) /* 0x000F0000 - 0x00010000 */ #define IWL_DL_FW (1 << 16) #define IWL_DL_RF_KILL (1 << 17) @@ -171,7 +171,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) #define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a) #define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) -#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a) +#define IWL_DEBUG_COEX(p, f, a...) IWL_DEBUG(p, IWL_DL_COEX, f, ## a) #define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) #define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) #define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ -- cgit v1.2.3-70-g09d2 From fa7f1413ed93a662839460e90dd6a5d045df2c03 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 12:49:25 -0700 Subject: iwlagn: add debug message for coex related activities Adding dedicated debug message for coex related activities Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 90cd647088a..a8c1e2493dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -438,7 +438,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) { - IWL_WARN(priv, "receive reply tx with bt_kill\n"); + IWL_DEBUG_COEX(priv, "receive reply tx with bt_kill\n"); } iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); @@ -1713,7 +1713,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) if (priv->bt_ch_announce) basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; - IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", basic.flags); + IWL_DEBUG_COEX(priv, "BT coex flag: 0X%x\n", basic.flags); } priv->bt_enable_flag = basic.flags; if (priv->bt_full_concurrent) @@ -1723,7 +1723,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) memcpy(basic.bt3_lookup_table, iwlagn_def_3w_lookup, sizeof(iwlagn_def_3w_lookup)); - IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", + IWL_DEBUG_COEX(priv, "BT coex %s in %s mode\n", basic.flags ? "active" : "disabled", priv->bt_full_concurrent ? "full concurrency" : "3-wire"); @@ -1761,7 +1761,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) * coex profile notifications. Ignore that since only bad consequence * can be not matching debug print with actual state. */ - IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", + IWL_DEBUG_COEX(priv, "BT traffic load changes: %d\n", priv->bt_traffic_load); switch (priv->bt_traffic_load) { @@ -1813,7 +1813,7 @@ out: static void iwlagn_print_uartmsg(struct iwl_priv *priv, struct iwl_bt_uart_msg *uart_msg) { - IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, " + IWL_DEBUG_COEX(priv, "Message Type = 0x%X, SSN = 0x%X, " "Update Req = 0x%X", (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> BT_UART_MSG_FRAME1MSGTYPE_POS, @@ -1822,7 +1822,7 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> BT_UART_MSG_FRAME1UPDATEREQ_POS); - IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, " + IWL_DEBUG_COEX(priv, "Open connections = 0x%X, Traffic load = 0x%X, " "Chl_SeqN = 0x%X, In band = 0x%X", (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, @@ -1833,7 +1833,7 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> BT_UART_MSG_FRAME2INBAND_POS); - IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " + IWL_DEBUG_COEX(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> BT_UART_MSG_FRAME3SCOESCO_POS, @@ -1848,11 +1848,11 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> BT_UART_MSG_FRAME3OBEX_POS); - IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X", + IWL_DEBUG_COEX(priv, "Idle duration = 0x%X", (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> BT_UART_MSG_FRAME4IDLEDURATION_POS); - IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " + IWL_DEBUG_COEX(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " "eSCO Retransmissions = 0x%X", (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> BT_UART_MSG_FRAME5TXACTIVITY_POS, @@ -1861,13 +1861,13 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); - IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", + IWL_DEBUG_COEX(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> BT_UART_MSG_FRAME6DISCOVERABLE_POS); - IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Page = " + IWL_DEBUG_COEX(priv, "Sniff Activity = 0x%X, Page = " "0x%X, Inquiry = 0x%X, Connectable = 0x%X", (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, @@ -1917,10 +1917,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, return; } - IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); - IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); - IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); - IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", + IWL_DEBUG_COEX(priv, "BT Coex notification:\n"); + IWL_DEBUG_COEX(priv, " status: %d\n", coex->bt_status); + IWL_DEBUG_COEX(priv, " traffic load: %d\n", coex->bt_traffic_load); + IWL_DEBUG_COEX(priv, " CI compliance: %d\n", coex->bt_ci_compliance); iwlagn_print_uartmsg(priv, uart_msg); -- cgit v1.2.3-70-g09d2 From f38f884b3b291c895d1033f02e351532d1d3f1dc Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 14:26:39 -0700 Subject: iwlagn: use IWL_DEBUG_TEMP for temperature related debug Instead of IWL_DEBUG_POWER, IWL_DEBUG_TEMP should be used for temperature related debug messages Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 348f74f1c8e..f501d742984 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -198,7 +198,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) /* Reschedule the ct_kill timer to occur in * CT_KILL_EXIT_DURATION seconds to ensure we get a * thermal update */ - IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n"); + IWL_DEBUG_TEMP(priv, "schedule ct_kill exit timer\n"); mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + CT_KILL_EXIT_DURATION * HZ); } @@ -208,15 +208,15 @@ static void iwl_perform_ct_kill_task(struct iwl_priv *priv, bool stop) { if (stop) { - IWL_DEBUG_POWER(priv, "Stop all queues\n"); + IWL_DEBUG_TEMP(priv, "Stop all queues\n"); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); - IWL_DEBUG_POWER(priv, + IWL_DEBUG_TEMP(priv, "Schedule 5 seconds CT_KILL Timer\n"); mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + CT_KILL_EXIT_DURATION * HZ); } else { - IWL_DEBUG_POWER(priv, "Wake all queues\n"); + IWL_DEBUG_TEMP(priv, "Wake all queues\n"); if (priv->mac80211_registered) ieee80211_wake_queues(priv->hw); } @@ -232,7 +232,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) /* temperature timer expired, ready to go into CT_KILL state */ if (tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_POWER(priv, "entering CT_KILL state when " + IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " "temperature timer expired\n"); tt->state = IWL_TI_CT_KILL; set_bit(STATUS_CT_KILL, &priv->status); @@ -242,7 +242,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) { - IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); + IWL_DEBUG_TEMP(priv, "Prepare to enter IWL_TI_CT_KILL\n"); /* make request to retrieve statistics information */ iwl_send_statistics_request(priv, CMD_SYNC, false); /* Reschedule the ct_kill wait timer */ @@ -273,7 +273,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) (temp > tt->tt_previous_temp) && ((temp - tt->tt_previous_temp) > IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_POWER(priv, + IWL_DEBUG_TEMP(priv, "Temperature increase %d degree Celsius\n", (temp - tt->tt_previous_temp)); } @@ -338,9 +338,9 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) } else if (old_state == IWL_TI_CT_KILL && tt->state != IWL_TI_CT_KILL) iwl_perform_ct_kill_task(priv, false); - IWL_DEBUG_POWER(priv, "Temperature state changed %u\n", + IWL_DEBUG_TEMP(priv, "Temperature state changed %u\n", tt->state); - IWL_DEBUG_POWER(priv, "Power Index change to %u\n", + IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", tt->tt_power_mode); } mutex_unlock(&priv->mutex); @@ -397,7 +397,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) (temp > tt->tt_previous_temp) && ((temp - tt->tt_previous_temp) > IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_POWER(priv, + IWL_DEBUG_TEMP(priv, "Temperature increase %d " "degree Celsius\n", (temp - tt->tt_previous_temp)); @@ -467,13 +467,13 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) set_bit(STATUS_CT_KILL, &priv->status); tt->state = old_state; } else { - IWL_DEBUG_POWER(priv, + IWL_DEBUG_TEMP(priv, "Thermal Throttling to new state: %u\n", tt->state); if (old_state != IWL_TI_CT_KILL && tt->state == IWL_TI_CT_KILL) { if (force) { - IWL_DEBUG_POWER(priv, + IWL_DEBUG_TEMP(priv, "Enter IWL_TI_CT_KILL\n"); set_bit(STATUS_CT_KILL, &priv->status); iwl_perform_ct_kill_task(priv, true); @@ -483,7 +483,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) } } else if (old_state == IWL_TI_CT_KILL && tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n"); + IWL_DEBUG_TEMP(priv, "Exit IWL_TI_CT_KILL\n"); iwl_perform_ct_kill_task(priv, false); } } @@ -568,7 +568,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); + IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); queue_work(priv->workqueue, &priv->ct_enter); } @@ -577,7 +577,7 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); + IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); queue_work(priv->workqueue, &priv->ct_exit); } @@ -603,7 +603,7 @@ void iwl_tt_handler(struct iwl_priv *priv) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); + IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); queue_work(priv->workqueue, &priv->tt_work); } @@ -618,7 +618,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); struct iwl_tt_trans *transaction; - IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n"); + IWL_DEBUG_TEMP(priv, "Initialize Thermal Throttling\n"); memset(tt, 0, sizeof(struct iwl_tt_mgmt)); @@ -638,7 +638,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); if (priv->cfg->base_params->adv_thermal_throttle) { - IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); + IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * IWL_TI_STATE_MAX, GFP_KERNEL); tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * @@ -671,7 +671,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) priv->thermal_throttle.advanced_tt = true; } } else { - IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); + IWL_DEBUG_TEMP(priv, "Legacy Thermal Throttling\n"); priv->thermal_throttle.advanced_tt = false; } } -- cgit v1.2.3-70-g09d2 From 06bb83589c4feac9bbb8d0d27d72f9d346f770c0 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 14:26:38 -0700 Subject: iwlagn: use IWL_DEBUG_FW for firmware related debug msg Instead use generic IWL_DEBUG_INFO, use IWL_DEBUG_FW for uCode related stuffs. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index a5cb1f63563..e916157bd14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -143,7 +143,7 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name); + IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name); ret = wait_event_interruptible_timeout(priv->wait_command_queue, priv->ucode_write_complete, 5 * HZ); if (ret == -ERESTARTSYS) { @@ -508,7 +508,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, u32 val; u32 i; - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { /* read data comes through single port, auto-incr addr */ @@ -533,7 +533,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, u32 offs; int errors = 0; - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, IWLAGN_RTC_INST_LOWER_BOUND); @@ -559,7 +559,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) { if (!iwlcore_verify_inst_sparse(priv, &img->code)) { - IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); + IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); return 0; } @@ -583,7 +583,7 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, palive = &pkt->u.alive_frame; - IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " + IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " "0x%01X 0x%01X\n", palive->is_valid, palive->ver_type, palive->ver_subtype); -- cgit v1.2.3-70-g09d2 From bf300252baa383065851e2ed6af41e5f9735fe9c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 14:26:40 -0700 Subject: iwlagn: remove unused debug flag Remove both IWL_DEBUG_TXPOWER and IWL_DEBUG_NOTIF, not used. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-debug.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index fd68ce89bb5..c844b512e56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -125,12 +125,12 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) /* 0x00000F00 - 0x00000100 */ #define IWL_DL_POWER (1 << 8) #define IWL_DL_TEMP (1 << 9) -#define IWL_DL_NOTIF (1 << 10) +/* reserved (1 << 10) */ #define IWL_DL_SCAN (1 << 11) /* 0x0000F000 - 0x00001000 */ #define IWL_DL_ASSOC (1 << 12) #define IWL_DL_DROP (1 << 13) -#define IWL_DL_TXPOWER (1 << 14) +/* reserved (1 << 14) */ #define IWL_DL_COEX (1 << 15) /* 0x000F0000 - 0x00010000 */ #define IWL_DL_FW (1 << 16) @@ -172,11 +172,9 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) #define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) #define IWL_DEBUG_COEX(p, f, a...) IWL_DEBUG(p, IWL_DL_COEX, f, ## a) -#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) #define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) #define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) -#define IWL_DEBUG_NOTIF(p, f, a...) IWL_DEBUG(p, IWL_DL_NOTIF, f, ## a) #define IWL_DEBUG_ASSOC(p, f, a...) \ IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) #define IWL_DEBUG_ASSOC_LIMIT(p, f, a...) \ -- cgit v1.2.3-70-g09d2 From 8d8854d983ab7217d322269c9bd17c1f8c481ae8 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 14:26:41 -0700 Subject: iwlagn: generic temperature location in EEPROM Temperature location in EEPROM is generic to all devices Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 05ad47628b6..f9630a3c79f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -75,7 +75,7 @@ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) { u16 temperature, voltage; __le16 *temp_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); temperature = le16_to_cpu(temp_calib[0]); voltage = le16_to_cpu(temp_calib[1]); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index e916157bd14..4be7a0f7174 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -197,7 +197,7 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_cmd cmd; __le16 *offset_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD; cmd.hdr.first_group = 0; cmd.hdr.groups_num = 1; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 2d7005385be..3dcb0a05d35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -166,12 +166,12 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_5000_TX_POWER_VERSION (4) #define EEPROM_5000_EEPROM_VERSION (0x11A) -/* 5000 and up calibration */ +/* calibration */ #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) -/* 5000 temperature */ -#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) +/* temperature */ +#define EEPROM_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) /* agn links */ #define EEPROM_LINK_HOST (2*0x64) -- cgit v1.2.3-70-g09d2 From 109a0ac5d8ed35914f5ce5c6d36244c08963c6cb Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 14:26:42 -0700 Subject: iwlagn: group similar defines together No functional changes, just group similar defines together Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 3dcb0a05d35..19058a6fac4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -162,10 +162,6 @@ struct iwl_eeprom_enhanced_txpwr { s8 mimo3_max; } __packed; -/* 5000 Specific */ -#define EEPROM_5000_TX_POWER_VERSION (4) -#define EEPROM_5000_EEPROM_VERSION (0x11A) - /* calibration */ #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) @@ -203,6 +199,10 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ +/* 5000 Specific */ +#define EEPROM_5000_TX_POWER_VERSION (4) +#define EEPROM_5000_EEPROM_VERSION (0x11A) + /* 5050 Specific */ #define EEPROM_5050_TX_POWER_VERSION (4) #define EEPROM_5050_EEPROM_VERSION (0x21E) -- cgit v1.2.3-70-g09d2 From 1f8bf0396ae7e63648b210fd197b1a5ab0db51bf Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 14:26:43 -0700 Subject: iwlagn: merge duplicated code into single place Multiple places have similar code to construct calib header. Merge into single inline function. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 12 ++++-------- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 14 +++++--------- drivers/net/wireless/iwlwifi/iwl-agn.h | 8 ++++++++ 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 23eee0ca5b3..ba7ed9157c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -111,10 +111,8 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd; - cmd.hdr.first_group = 0; - cmd.hdr.groups_num = 1; - cmd.hdr.data_valid = 1; + iwl_set_calib_hdr(&cmd.hdr, + priv->_agn.phy_calib_chain_noise_gain_cmd); cmd.delta_gain_1 = data->delta_gain_code[1]; cmd.delta_gain_2 = data->delta_gain_code[2]; iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, @@ -144,10 +142,8 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) data->beacon_count = 0; memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd; - cmd.hdr.first_group = 0; - cmd.hdr.groups_num = 1; - cmd.hdr.data_valid = 1; + iwl_set_calib_hdr(&cmd.hdr, + priv->_agn.phy_calib_chain_noise_reset_cmd); ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, sizeof(cmd), &cmd); if (ret) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 4be7a0f7174..de8277e3225 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -183,10 +183,7 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) __le16 *xtal_calib = (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; - cmd.hdr.first_group = 0; - cmd.hdr.groups_num = 1; - cmd.hdr.data_valid = 1; + iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], @@ -198,14 +195,13 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) struct iwl_calib_temperature_offset_cmd cmd; __le16 *offset_calib = (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD; - cmd.hdr.first_group = 0; - cmd.hdr.groups_num = 1; - cmd.hdr.data_valid = 1; + + memset(&cmd, 0, sizeof(cmd)); + iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]); if (!(cmd.radio_sensor_offset)) cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; - cmd.reserved = 0; + IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", cmd.radio_sensor_offset); return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET], diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 94ee1416fb9..5d8b2db82a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -129,6 +129,14 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) tasklet_kill(&priv->irq_tasklet); } +static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) +{ + hdr->op_code = cmd; + hdr->first_group = 0; + hdr->groups_num = 1; + hdr->data_valid = 1; +} + int iwl_prepare_card_hw(struct iwl_priv *priv); int iwlagn_start_device(struct iwl_priv *priv); -- cgit v1.2.3-70-g09d2 From 4f0642a6665d1f4dbf8ef472dd5620e7585357b9 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 6 Jun 2011 16:28:54 -0700 Subject: iwlagn: Sanity check for 11n capability Make sure when we say 11n enable, we really support it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 512d8beb3df..7745816eaff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -113,6 +113,11 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv) if (!priv->cfg->sku) { /* not using sku overwrite */ priv->cfg->sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); + if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE && + !priv->cfg->ht_params) { + IWL_ERR(priv, "Invalid 11n configuration\n"); + return -EINVAL; + } } if (!priv->cfg->sku) { IWL_ERR(priv, "Invalid device sku\n"); -- cgit v1.2.3-70-g09d2 From b2ea345eab568062b321bcd3b8d72f14c93dbb63 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 7 Jun 2011 08:53:14 -0700 Subject: iwlagn: Sanity check for valid context Check EEPROM for multiple contexts support Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 56 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 488081fe183..0acf9291904 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1485,7 +1485,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) priv->new_scan_threshold_behaviour = !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { + if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) && + (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) { priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; } else @@ -3425,27 +3426,9 @@ out: return hw; } -static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static void iwl_init_context(struct iwl_priv *priv) { - int err = 0, i; - struct iwl_priv *priv; - struct ieee80211_hw *hw; - struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); - unsigned long flags; - u16 pci_cmd, num_mac; - u32 hw_rev; - - /************************ - * 1. Allocating HW data - ************************/ - - hw = iwl_alloc_all(cfg); - if (!hw) { - err = -ENOMEM; - goto out; - } - priv = hw->priv; - /* At this point both hw and priv are allocated. */ + int i; /* * The default context is always valid, @@ -3477,8 +3460,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; - priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; - priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = REPLY_WIPAN_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = + REPLY_WIPAN_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = + REPLY_WIPAN_RXON_ASSOC; priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; @@ -3498,6 +3483,28 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); +} + +static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = 0; + struct iwl_priv *priv; + struct ieee80211_hw *hw; + struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + unsigned long flags; + u16 pci_cmd, num_mac; + u32 hw_rev; + + /************************ + * 1. Allocating HW data + ************************/ + + hw = iwl_alloc_all(cfg); + if (!hw) { + err = -ENOMEM; + goto out; } + priv = hw->priv; + /* At this point both hw and priv are allocated. */ SET_IEEE80211_DEV(hw, &pdev->dev); @@ -3622,6 +3629,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->hw->wiphy->n_addresses++; } + /* initialize all valid contexts */ + iwl_init_context(priv); + /************************ * 5. Setup HW constants ************************/ -- cgit v1.2.3-70-g09d2 From ac752277961c0aba08ba7b33e7c93a56f711cef9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 11 Jun 2011 14:58:17 -0700 Subject: net/m68k: Include where needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arch/m68k/emu/nfeth.c: In function ‘nfeth_init’: arch/m68k/emu/nfeth.c:243: error: implicit declaration of function ‘request_irq’ arch/m68k/emu/nfeth.c:243: error: ‘IRQF_SHARED’ undeclared (first use in this function) arch/m68k/emu/nfeth.c:243: error: (Each undeclared identifier is reported only once arch/m68k/emu/nfeth.c:243: error: for each function it appears in.) arch/m68k/emu/nfeth.c: In function ‘nfeth_cleanup’: arch/m68k/emu/nfeth.c:266: error: implicit declaration of function ‘free_irq’ drivers/net/apne.c: In function ‘apne_probe’: drivers/net/apne.c:189: error: implicit declaration of function ‘free_irq’ drivers/net/apne.c: In function ‘apne_probe1’: drivers/net/apne.c:317: error: implicit declaration of function ‘request_irq’ drivers/net/apne.c:317: error: ‘IRQF_SHARED’ undeclared (first use in this function) drivers/net/apne.c:317: error: (Each undeclared identifier is reported only once drivers/net/apne.c:317: error: for each function it appears in.) Introduced by commit a6b7a407865a ("net: remove interrupt.h inclusion from netdevice.h"). Include in the individual drivers to fix the build. Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- arch/m68k/emu/nfeth.c | 1 + drivers/net/apne.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c index 8b6e201b2c2..3c55312ecb1 100644 --- a/arch/m68k/emu/nfeth.c +++ b/arch/m68k/emu/nfeth.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/apne.c b/drivers/net/apne.c index 2fe60f16810..547737340cb 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3-70-g09d2 From 69785b79ca9b1acb62098ff059f897bfe59d443f Mon Sep 17 00:00:00 2001 From: Po-Yu Chuang Date: Wed, 8 Jun 2011 23:32:48 +0000 Subject: net: add Faraday FTGMAC100 Gigabit Ethernet driver FTGMAC100 Ethernet Media Access Controller supports 10/100/1000 Mbps and MII/GMII. This driver has been working on some ARM/NDS32 SoC's including Faraday A369 and Andes AG102. Signed-off-by: Po-Yu Chuang Signed-off-by: David S. Miller --- drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/ftgmac100.c | 1365 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ftgmac100.h | 246 +++++++++ 4 files changed, 1621 insertions(+) create mode 100644 drivers/net/ftgmac100.c create mode 100644 drivers/net/ftgmac100.h (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index fa0ea6d291b..399cf4b28ae 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2560,6 +2560,15 @@ config PCH_GBE ML7223 is companion chip for Intel Atom E6xx series. ML7223 is completely compatible for Intel EG20T PCH. +config FTGMAC100 + tristate "Faraday FTGMAC100 Gigabit Ethernet support" + depends on ARM + select PHYLIB + help + This driver supports the FTGMAC100 Gigabit Ethernet controller + from Faraday. It is used on Faraday A369, Andes AG102 and some + other ARM/NDS32 SoC's. + endif # NETDEV_1000 # diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 776a478e629..800684104b1 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -148,6 +148,7 @@ obj-$(CONFIG_FORCEDETH) += forcedeth.o obj-$(CONFIG_NE_H8300) += ne-h8300.o obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o +obj-$(CONFIG_FTGMAC100) += ftgmac100.o obj-$(CONFIG_FTMAC100) += ftmac100.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c new file mode 100644 index 00000000000..54709af917e --- /dev/null +++ b/drivers/net/ftgmac100.c @@ -0,0 +1,1365 @@ +/* + * Faraday FTGMAC100 Gigabit Ethernet + * + * (C) Copyright 2009-2011 Faraday Technology + * Po-Yu Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ftgmac100.h" + +#define DRV_NAME "ftgmac100" +#define DRV_VERSION "0.7" + +#define RX_QUEUE_ENTRIES 256 /* must be power of 2 */ +#define TX_QUEUE_ENTRIES 512 /* must be power of 2 */ + +#define MAX_PKT_SIZE 1518 +#define RX_BUF_SIZE PAGE_SIZE /* must be smaller than 0x3fff */ + +/****************************************************************************** + * private data + *****************************************************************************/ +struct ftgmac100_descs { + struct ftgmac100_rxdes rxdes[RX_QUEUE_ENTRIES]; + struct ftgmac100_txdes txdes[TX_QUEUE_ENTRIES]; +}; + +struct ftgmac100 { + struct resource *res; + void __iomem *base; + int irq; + + struct ftgmac100_descs *descs; + dma_addr_t descs_dma_addr; + + unsigned int rx_pointer; + unsigned int tx_clean_pointer; + unsigned int tx_pointer; + unsigned int tx_pending; + + spinlock_t tx_lock; + + struct net_device *netdev; + struct device *dev; + struct napi_struct napi; + + struct mii_bus *mii_bus; + int phy_irq[PHY_MAX_ADDR]; + struct phy_device *phydev; + int old_speed; +}; + +static int ftgmac100_alloc_rx_page(struct ftgmac100 *priv, + struct ftgmac100_rxdes *rxdes, gfp_t gfp); + +/****************************************************************************** + * internal functions (hardware register access) + *****************************************************************************/ +#define INT_MASK_ALL_ENABLED (FTGMAC100_INT_RPKT_LOST | \ + FTGMAC100_INT_XPKT_ETH | \ + FTGMAC100_INT_XPKT_LOST | \ + FTGMAC100_INT_AHB_ERR | \ + FTGMAC100_INT_PHYSTS_CHG | \ + FTGMAC100_INT_RPKT_BUF | \ + FTGMAC100_INT_NO_RXBUF) + +static void ftgmac100_set_rx_ring_base(struct ftgmac100 *priv, dma_addr_t addr) +{ + iowrite32(addr, priv->base + FTGMAC100_OFFSET_RXR_BADR); +} + +static void ftgmac100_set_rx_buffer_size(struct ftgmac100 *priv, + unsigned int size) +{ + size = FTGMAC100_RBSR_SIZE(size); + iowrite32(size, priv->base + FTGMAC100_OFFSET_RBSR); +} + +static void ftgmac100_set_normal_prio_tx_ring_base(struct ftgmac100 *priv, + dma_addr_t addr) +{ + iowrite32(addr, priv->base + FTGMAC100_OFFSET_NPTXR_BADR); +} + +static void ftgmac100_txdma_normal_prio_start_polling(struct ftgmac100 *priv) +{ + iowrite32(1, priv->base + FTGMAC100_OFFSET_NPTXPD); +} + +static int ftgmac100_reset_hw(struct ftgmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + int i; + + /* NOTE: reset clears all registers */ + iowrite32(FTGMAC100_MACCR_SW_RST, priv->base + FTGMAC100_OFFSET_MACCR); + for (i = 0; i < 5; i++) { + unsigned int maccr; + + maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); + if (!(maccr & FTGMAC100_MACCR_SW_RST)) + return 0; + + udelay(1000); + } + + netdev_err(netdev, "software reset failed\n"); + return -EIO; +} + +static void ftgmac100_set_mac(struct ftgmac100 *priv, const unsigned char *mac) +{ + unsigned int maddr = mac[0] << 8 | mac[1]; + unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; + + iowrite32(maddr, priv->base + FTGMAC100_OFFSET_MAC_MADR); + iowrite32(laddr, priv->base + FTGMAC100_OFFSET_MAC_LADR); +} + +static void ftgmac100_init_hw(struct ftgmac100 *priv) +{ + /* setup ring buffer base registers */ + ftgmac100_set_rx_ring_base(priv, + priv->descs_dma_addr + + offsetof(struct ftgmac100_descs, rxdes)); + ftgmac100_set_normal_prio_tx_ring_base(priv, + priv->descs_dma_addr + + offsetof(struct ftgmac100_descs, txdes)); + + ftgmac100_set_rx_buffer_size(priv, RX_BUF_SIZE); + + iowrite32(FTGMAC100_APTC_RXPOLL_CNT(1), priv->base + FTGMAC100_OFFSET_APTC); + + ftgmac100_set_mac(priv, priv->netdev->dev_addr); +} + +#define MACCR_ENABLE_ALL (FTGMAC100_MACCR_TXDMA_EN | \ + FTGMAC100_MACCR_RXDMA_EN | \ + FTGMAC100_MACCR_TXMAC_EN | \ + FTGMAC100_MACCR_RXMAC_EN | \ + FTGMAC100_MACCR_FULLDUP | \ + FTGMAC100_MACCR_CRC_APD | \ + FTGMAC100_MACCR_RX_RUNT | \ + FTGMAC100_MACCR_RX_BROADPKT) + +static void ftgmac100_start_hw(struct ftgmac100 *priv, int speed) +{ + int maccr = MACCR_ENABLE_ALL; + + switch (speed) { + default: + case 10: + break; + + case 100: + maccr |= FTGMAC100_MACCR_FAST_MODE; + break; + + case 1000: + maccr |= FTGMAC100_MACCR_GIGA_MODE; + break; + } + + iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); +} + +static void ftgmac100_stop_hw(struct ftgmac100 *priv) +{ + iowrite32(0, priv->base + FTGMAC100_OFFSET_MACCR); +} + +/****************************************************************************** + * internal functions (receive descriptor) + *****************************************************************************/ +static bool ftgmac100_rxdes_first_segment(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_FRS); +} + +static bool ftgmac100_rxdes_last_segment(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_LRS); +} + +static bool ftgmac100_rxdes_packet_ready(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RXPKT_RDY); +} + +static void ftgmac100_rxdes_set_dma_own(struct ftgmac100_rxdes *rxdes) +{ + /* clear status bits */ + rxdes->rxdes0 &= cpu_to_le32(FTGMAC100_RXDES0_EDORR); +} + +static bool ftgmac100_rxdes_rx_error(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RX_ERR); +} + +static bool ftgmac100_rxdes_crc_error(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_CRC_ERR); +} + +static bool ftgmac100_rxdes_frame_too_long(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_FTL); +} + +static bool ftgmac100_rxdes_runt(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RUNT); +} + +static bool ftgmac100_rxdes_odd_nibble(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RX_ODD_NB); +} + +static unsigned int ftgmac100_rxdes_data_length(struct ftgmac100_rxdes *rxdes) +{ + return le32_to_cpu(rxdes->rxdes0) & FTGMAC100_RXDES0_VDBC; +} + +static bool ftgmac100_rxdes_multicast(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_MULTICAST); +} + +static void ftgmac100_rxdes_set_end_of_ring(struct ftgmac100_rxdes *rxdes) +{ + rxdes->rxdes0 |= cpu_to_le32(FTGMAC100_RXDES0_EDORR); +} + +static void ftgmac100_rxdes_set_dma_addr(struct ftgmac100_rxdes *rxdes, + dma_addr_t addr) +{ + rxdes->rxdes3 = cpu_to_le32(addr); +} + +static dma_addr_t ftgmac100_rxdes_get_dma_addr(struct ftgmac100_rxdes *rxdes) +{ + return le32_to_cpu(rxdes->rxdes3); +} + +static bool ftgmac100_rxdes_is_tcp(struct ftgmac100_rxdes *rxdes) +{ + return (rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)) == + cpu_to_le32(FTGMAC100_RXDES1_PROT_TCPIP); +} + +static bool ftgmac100_rxdes_is_udp(struct ftgmac100_rxdes *rxdes) +{ + return (rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)) == + cpu_to_le32(FTGMAC100_RXDES1_PROT_UDPIP); +} + +static bool ftgmac100_rxdes_tcpcs_err(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_TCP_CHKSUM_ERR); +} + +static bool ftgmac100_rxdes_udpcs_err(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_UDP_CHKSUM_ERR); +} + +static bool ftgmac100_rxdes_ipcs_err(struct ftgmac100_rxdes *rxdes) +{ + return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_IP_CHKSUM_ERR); +} + +/* + * rxdes2 is not used by hardware. We use it to keep track of page. + * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). + */ +static void ftgmac100_rxdes_set_page(struct ftgmac100_rxdes *rxdes, struct page *page) +{ + rxdes->rxdes2 = (unsigned int)page; +} + +static struct page *ftgmac100_rxdes_get_page(struct ftgmac100_rxdes *rxdes) +{ + return (struct page *)rxdes->rxdes2; +} + +/****************************************************************************** + * internal functions (receive) + *****************************************************************************/ +static int ftgmac100_next_rx_pointer(int pointer) +{ + return (pointer + 1) & (RX_QUEUE_ENTRIES - 1); +} + +static void ftgmac100_rx_pointer_advance(struct ftgmac100 *priv) +{ + priv->rx_pointer = ftgmac100_next_rx_pointer(priv->rx_pointer); +} + +static struct ftgmac100_rxdes *ftgmac100_current_rxdes(struct ftgmac100 *priv) +{ + return &priv->descs->rxdes[priv->rx_pointer]; +} + +static struct ftgmac100_rxdes * +ftgmac100_rx_locate_first_segment(struct ftgmac100 *priv) +{ + struct ftgmac100_rxdes *rxdes = ftgmac100_current_rxdes(priv); + + while (ftgmac100_rxdes_packet_ready(rxdes)) { + if (ftgmac100_rxdes_first_segment(rxdes)) + return rxdes; + + ftgmac100_rxdes_set_dma_own(rxdes); + ftgmac100_rx_pointer_advance(priv); + rxdes = ftgmac100_current_rxdes(priv); + } + + return NULL; +} + +static bool ftgmac100_rx_packet_error(struct ftgmac100 *priv, + struct ftgmac100_rxdes *rxdes) +{ + struct net_device *netdev = priv->netdev; + bool error = false; + + if (unlikely(ftgmac100_rxdes_rx_error(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx err\n"); + + netdev->stats.rx_errors++; + error = true; + } + + if (unlikely(ftgmac100_rxdes_crc_error(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx crc err\n"); + + netdev->stats.rx_crc_errors++; + error = true; + } else if (unlikely(ftgmac100_rxdes_ipcs_err(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx IP checksum err\n"); + + error = true; + } + + if (unlikely(ftgmac100_rxdes_frame_too_long(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx frame too long\n"); + + netdev->stats.rx_length_errors++; + error = true; + } else if (unlikely(ftgmac100_rxdes_runt(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx runt\n"); + + netdev->stats.rx_length_errors++; + error = true; + } else if (unlikely(ftgmac100_rxdes_odd_nibble(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx odd nibble\n"); + + netdev->stats.rx_length_errors++; + error = true; + } + + return error; +} + +static void ftgmac100_rx_drop_packet(struct ftgmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + struct ftgmac100_rxdes *rxdes = ftgmac100_current_rxdes(priv); + bool done = false; + + if (net_ratelimit()) + netdev_dbg(netdev, "drop packet %p\n", rxdes); + + do { + if (ftgmac100_rxdes_last_segment(rxdes)) + done = true; + + ftgmac100_rxdes_set_dma_own(rxdes); + ftgmac100_rx_pointer_advance(priv); + rxdes = ftgmac100_current_rxdes(priv); + } while (!done && ftgmac100_rxdes_packet_ready(rxdes)); + + netdev->stats.rx_dropped++; +} + +static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) +{ + struct net_device *netdev = priv->netdev; + struct ftgmac100_rxdes *rxdes; + struct sk_buff *skb; + bool done = false; + + rxdes = ftgmac100_rx_locate_first_segment(priv); + if (!rxdes) + return false; + + if (unlikely(ftgmac100_rx_packet_error(priv, rxdes))) { + ftgmac100_rx_drop_packet(priv); + return true; + } + + /* start processing */ + skb = netdev_alloc_skb_ip_align(netdev, 128); + if (unlikely(!skb)) { + if (net_ratelimit()) + netdev_err(netdev, "rx skb alloc failed\n"); + + ftgmac100_rx_drop_packet(priv); + return true; + } + + if (unlikely(ftgmac100_rxdes_multicast(rxdes))) + netdev->stats.multicast++; + + /* + * It seems that HW does checksum incorrectly with fragmented packets, + * so we are conservative here - if HW checksum error, let software do + * the checksum again. + */ + if ((ftgmac100_rxdes_is_tcp(rxdes) && !ftgmac100_rxdes_tcpcs_err(rxdes)) || + (ftgmac100_rxdes_is_udp(rxdes) && !ftgmac100_rxdes_udpcs_err(rxdes))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + do { + dma_addr_t map = ftgmac100_rxdes_get_dma_addr(rxdes); + struct page *page = ftgmac100_rxdes_get_page(rxdes); + unsigned int size; + + dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); + + size = ftgmac100_rxdes_data_length(rxdes); + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page, 0, size); + + skb->len += size; + skb->data_len += size; + skb->truesize += size; + + if (ftgmac100_rxdes_last_segment(rxdes)) + done = true; + + ftgmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC); + + ftgmac100_rx_pointer_advance(priv); + rxdes = ftgmac100_current_rxdes(priv); + } while (!done); + + __pskb_pull_tail(skb, min(skb->len, 64U)); + skb->protocol = eth_type_trans(skb, netdev); + + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += skb->len; + + /* push packet to protocol stack */ + napi_gro_receive(&priv->napi, skb); + + (*processed)++; + return true; +} + +/****************************************************************************** + * internal functions (transmit descriptor) + *****************************************************************************/ +static void ftgmac100_txdes_reset(struct ftgmac100_txdes *txdes) +{ + /* clear all except end of ring bit */ + txdes->txdes0 &= cpu_to_le32(FTGMAC100_TXDES0_EDOTR); + txdes->txdes1 = 0; + txdes->txdes2 = 0; + txdes->txdes3 = 0; +} + +static bool ftgmac100_txdes_owned_by_dma(struct ftgmac100_txdes *txdes) +{ + return txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN); +} + +static void ftgmac100_txdes_set_dma_own(struct ftgmac100_txdes *txdes) +{ + /* + * Make sure dma own bit will not be set before any other + * descriptor fields. + */ + wmb(); + txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN); +} + +static void ftgmac100_txdes_set_end_of_ring(struct ftgmac100_txdes *txdes) +{ + txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_EDOTR); +} + +static void ftgmac100_txdes_set_first_segment(struct ftgmac100_txdes *txdes) +{ + txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_FTS); +} + +static void ftgmac100_txdes_set_last_segment(struct ftgmac100_txdes *txdes) +{ + txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_LTS); +} + +static void ftgmac100_txdes_set_buffer_size(struct ftgmac100_txdes *txdes, + unsigned int len) +{ + txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXBUF_SIZE(len)); +} + +static void ftgmac100_txdes_set_txint(struct ftgmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_TXIC); +} + +static void ftgmac100_txdes_set_tcpcs(struct ftgmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_TCP_CHKSUM); +} + +static void ftgmac100_txdes_set_udpcs(struct ftgmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_UDP_CHKSUM); +} + +static void ftgmac100_txdes_set_ipcs(struct ftgmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_IP_CHKSUM); +} + +static void ftgmac100_txdes_set_dma_addr(struct ftgmac100_txdes *txdes, + dma_addr_t addr) +{ + txdes->txdes3 = cpu_to_le32(addr); +} + +static dma_addr_t ftgmac100_txdes_get_dma_addr(struct ftgmac100_txdes *txdes) +{ + return le32_to_cpu(txdes->txdes3); +} + +/* + * txdes2 is not used by hardware. We use it to keep track of socket buffer. + * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). + */ +static void ftgmac100_txdes_set_skb(struct ftgmac100_txdes *txdes, + struct sk_buff *skb) +{ + txdes->txdes2 = (unsigned int)skb; +} + +static struct sk_buff *ftgmac100_txdes_get_skb(struct ftgmac100_txdes *txdes) +{ + return (struct sk_buff *)txdes->txdes2; +} + +/****************************************************************************** + * internal functions (transmit) + *****************************************************************************/ +static int ftgmac100_next_tx_pointer(int pointer) +{ + return (pointer + 1) & (TX_QUEUE_ENTRIES - 1); +} + +static void ftgmac100_tx_pointer_advance(struct ftgmac100 *priv) +{ + priv->tx_pointer = ftgmac100_next_tx_pointer(priv->tx_pointer); +} + +static void ftgmac100_tx_clean_pointer_advance(struct ftgmac100 *priv) +{ + priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv->tx_clean_pointer); +} + +static struct ftgmac100_txdes *ftgmac100_current_txdes(struct ftgmac100 *priv) +{ + return &priv->descs->txdes[priv->tx_pointer]; +} + +static struct ftgmac100_txdes * +ftgmac100_current_clean_txdes(struct ftgmac100 *priv) +{ + return &priv->descs->txdes[priv->tx_clean_pointer]; +} + +static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + struct ftgmac100_txdes *txdes; + struct sk_buff *skb; + dma_addr_t map; + + if (priv->tx_pending == 0) + return false; + + txdes = ftgmac100_current_clean_txdes(priv); + + if (ftgmac100_txdes_owned_by_dma(txdes)) + return false; + + skb = ftgmac100_txdes_get_skb(txdes); + map = ftgmac100_txdes_get_dma_addr(txdes); + + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + + dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); + + dev_kfree_skb(skb); + + ftgmac100_txdes_reset(txdes); + + ftgmac100_tx_clean_pointer_advance(priv); + + spin_lock(&priv->tx_lock); + priv->tx_pending--; + spin_unlock(&priv->tx_lock); + netif_wake_queue(netdev); + + return true; +} + +static void ftgmac100_tx_complete(struct ftgmac100 *priv) +{ + while (ftgmac100_tx_complete_packet(priv)) + ; +} + +static int ftgmac100_xmit(struct ftgmac100 *priv, struct sk_buff *skb, + dma_addr_t map) +{ + struct net_device *netdev = priv->netdev; + struct ftgmac100_txdes *txdes; + unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; + + txdes = ftgmac100_current_txdes(priv); + ftgmac100_tx_pointer_advance(priv); + + /* setup TX descriptor */ + ftgmac100_txdes_set_skb(txdes, skb); + ftgmac100_txdes_set_dma_addr(txdes, map); + ftgmac100_txdes_set_buffer_size(txdes, len); + + ftgmac100_txdes_set_first_segment(txdes); + ftgmac100_txdes_set_last_segment(txdes); + ftgmac100_txdes_set_txint(txdes); + if (skb->ip_summed == CHECKSUM_PARTIAL) { + __be16 protocol = skb->protocol; + + if (protocol == cpu_to_be16(ETH_P_IP)) { + u8 ip_proto = ip_hdr(skb)->protocol; + + ftgmac100_txdes_set_ipcs(txdes); + if (ip_proto == IPPROTO_TCP) + ftgmac100_txdes_set_tcpcs(txdes); + else if (ip_proto == IPPROTO_UDP) + ftgmac100_txdes_set_udpcs(txdes); + } + } + + spin_lock(&priv->tx_lock); + priv->tx_pending++; + if (priv->tx_pending == TX_QUEUE_ENTRIES) + netif_stop_queue(netdev); + + /* start transmit */ + ftgmac100_txdes_set_dma_own(txdes); + spin_unlock(&priv->tx_lock); + + ftgmac100_txdma_normal_prio_start_polling(priv); + + return NETDEV_TX_OK; +} + +/****************************************************************************** + * internal functions (buffer) + *****************************************************************************/ +static int ftgmac100_alloc_rx_page(struct ftgmac100 *priv, + struct ftgmac100_rxdes *rxdes, gfp_t gfp) +{ + struct net_device *netdev = priv->netdev; + struct page *page; + dma_addr_t map; + + page = alloc_page(gfp); + if (!page) { + if (net_ratelimit()) + netdev_err(netdev, "failed to allocate rx page\n"); + return -ENOMEM; + } + + map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(priv->dev, map))) { + if (net_ratelimit()) + netdev_err(netdev, "failed to map rx page\n"); + __free_page(page); + return -ENOMEM; + } + + ftgmac100_rxdes_set_page(rxdes, page); + ftgmac100_rxdes_set_dma_addr(rxdes, map); + ftgmac100_rxdes_set_dma_own(rxdes); + return 0; +} + +static void ftgmac100_free_buffers(struct ftgmac100 *priv) +{ + int i; + + for (i = 0; i < RX_QUEUE_ENTRIES; i++) { + struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[i]; + struct page *page = ftgmac100_rxdes_get_page(rxdes); + dma_addr_t map = ftgmac100_rxdes_get_dma_addr(rxdes); + + if (!page) + continue; + + dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); + __free_page(page); + } + + for (i = 0; i < TX_QUEUE_ENTRIES; i++) { + struct ftgmac100_txdes *txdes = &priv->descs->txdes[i]; + struct sk_buff *skb = ftgmac100_txdes_get_skb(txdes); + dma_addr_t map = ftgmac100_txdes_get_dma_addr(txdes); + + if (!skb) + continue; + + dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); + dev_kfree_skb(skb); + } + + dma_free_coherent(priv->dev, sizeof(struct ftgmac100_descs), + priv->descs, priv->descs_dma_addr); +} + +static int ftgmac100_alloc_buffers(struct ftgmac100 *priv) +{ + int i; + + priv->descs = dma_alloc_coherent(priv->dev, + sizeof(struct ftgmac100_descs), + &priv->descs_dma_addr, GFP_KERNEL); + if (!priv->descs) + return -ENOMEM; + + memset(priv->descs, 0, sizeof(struct ftgmac100_descs)); + + /* initialize RX ring */ + ftgmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]); + + for (i = 0; i < RX_QUEUE_ENTRIES; i++) { + struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[i]; + + if (ftgmac100_alloc_rx_page(priv, rxdes, GFP_KERNEL)) + goto err; + } + + /* initialize TX ring */ + ftgmac100_txdes_set_end_of_ring(&priv->descs->txdes[TX_QUEUE_ENTRIES - 1]); + return 0; + +err: + ftgmac100_free_buffers(priv); + return -ENOMEM; +} + +/****************************************************************************** + * internal functions (mdio) + *****************************************************************************/ +static void ftgmac100_adjust_link(struct net_device *netdev) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + struct phy_device *phydev = priv->phydev; + int ier; + + if (phydev->speed == priv->old_speed) + return; + + priv->old_speed = phydev->speed; + + ier = ioread32(priv->base + FTGMAC100_OFFSET_IER); + + /* disable all interrupts */ + iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); + + netif_stop_queue(netdev); + ftgmac100_stop_hw(priv); + + netif_start_queue(netdev); + ftgmac100_init_hw(priv); + ftgmac100_start_hw(priv, phydev->speed); + + /* re-enable interrupts */ + iowrite32(ier, priv->base + FTGMAC100_OFFSET_IER); +} + +static int ftgmac100_mii_probe(struct ftgmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + struct phy_device *phydev = NULL; + int i; + + /* search for connect PHY device */ + for (i = 0; i < PHY_MAX_ADDR; i++) { + struct phy_device *tmp = priv->mii_bus->phy_map[i]; + + if (tmp) { + phydev = tmp; + break; + } + } + + /* now we are supposed to have a proper phydev, to attach to... */ + if (!phydev) { + netdev_info(netdev, "%s: no PHY found\n", netdev->name); + return -ENODEV; + } + + phydev = phy_connect(netdev, dev_name(&phydev->dev), + &ftgmac100_adjust_link, 0, + PHY_INTERFACE_MODE_GMII); + + if (IS_ERR(phydev)) { + netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name); + return PTR_ERR(phydev); + } + + priv->phydev = phydev; + return 0; +} + +/****************************************************************************** + * struct mii_bus functions + *****************************************************************************/ +static int ftgmac100_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) +{ + struct net_device *netdev = bus->priv; + struct ftgmac100 *priv = netdev_priv(netdev); + unsigned int phycr; + int i; + + phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); + + /* preserve MDC cycle threshold */ + phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; + + phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) | + FTGMAC100_PHYCR_REGAD(regnum) | + FTGMAC100_PHYCR_MIIRD; + + iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); + + for (i = 0; i < 10; i++) { + phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); + + if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) { + int data; + + data = ioread32(priv->base + FTGMAC100_OFFSET_PHYDATA); + return FTGMAC100_PHYDATA_MIIRDATA(data); + } + + udelay(100); + } + + netdev_err(netdev, "mdio read timed out\n"); + return -EIO; +} + +static int ftgmac100_mdiobus_write(struct mii_bus *bus, int phy_addr, + int regnum, u16 value) +{ + struct net_device *netdev = bus->priv; + struct ftgmac100 *priv = netdev_priv(netdev); + unsigned int phycr; + int data; + int i; + + phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); + + /* preserve MDC cycle threshold */ + phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; + + phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) | + FTGMAC100_PHYCR_REGAD(regnum) | + FTGMAC100_PHYCR_MIIWR; + + data = FTGMAC100_PHYDATA_MIIWDATA(value); + + iowrite32(data, priv->base + FTGMAC100_OFFSET_PHYDATA); + iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); + + for (i = 0; i < 10; i++) { + phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); + + if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) + return 0; + + udelay(100); + } + + netdev_err(netdev, "mdio write timed out\n"); + return -EIO; +} + +static int ftgmac100_mdiobus_reset(struct mii_bus *bus) +{ + return 0; +} + +/****************************************************************************** + * struct ethtool_ops functions + *****************************************************************************/ +static void ftgmac100_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, dev_name(&netdev->dev)); +} + +static int ftgmac100_get_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + + return phy_ethtool_gset(priv->phydev, cmd); +} + +static int ftgmac100_set_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + + return phy_ethtool_sset(priv->phydev, cmd); +} + +static const struct ethtool_ops ftgmac100_ethtool_ops = { + .set_settings = ftgmac100_set_settings, + .get_settings = ftgmac100_get_settings, + .get_drvinfo = ftgmac100_get_drvinfo, + .get_link = ethtool_op_get_link, +}; + +/****************************************************************************** + * interrupt handler + *****************************************************************************/ +static irqreturn_t ftgmac100_interrupt(int irq, void *dev_id) +{ + struct net_device *netdev = dev_id; + struct ftgmac100 *priv = netdev_priv(netdev); + + if (likely(netif_running(netdev))) { + /* Disable interrupts for polling */ + iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); + napi_schedule(&priv->napi); + } + + return IRQ_HANDLED; +} + +/****************************************************************************** + * struct napi_struct functions + *****************************************************************************/ +static int ftgmac100_poll(struct napi_struct *napi, int budget) +{ + struct ftgmac100 *priv = container_of(napi, struct ftgmac100, napi); + struct net_device *netdev = priv->netdev; + unsigned int status; + bool completed = true; + int rx = 0; + + status = ioread32(priv->base + FTGMAC100_OFFSET_ISR); + iowrite32(status, priv->base + FTGMAC100_OFFSET_ISR); + + if (status & (FTGMAC100_INT_RPKT_BUF | FTGMAC100_INT_NO_RXBUF)) { + /* + * FTGMAC100_INT_RPKT_BUF: + * RX DMA has received packets into RX buffer successfully + * + * FTGMAC100_INT_NO_RXBUF: + * RX buffer unavailable + */ + bool retry; + + do { + retry = ftgmac100_rx_packet(priv, &rx); + } while (retry && rx < budget); + + if (retry && rx == budget) + completed = false; + } + + if (status & (FTGMAC100_INT_XPKT_ETH | FTGMAC100_INT_XPKT_LOST)) { + /* + * FTGMAC100_INT_XPKT_ETH: + * packet transmitted to ethernet successfully + * + * FTGMAC100_INT_XPKT_LOST: + * packet transmitted to ethernet lost due to late + * collision or excessive collision + */ + ftgmac100_tx_complete(priv); + } + + if (status & (FTGMAC100_INT_NO_RXBUF | FTGMAC100_INT_RPKT_LOST | + FTGMAC100_INT_AHB_ERR | FTGMAC100_INT_PHYSTS_CHG)) { + if (net_ratelimit()) + netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status, + status & FTGMAC100_INT_NO_RXBUF ? "NO_RXBUF " : "", + status & FTGMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "", + status & FTGMAC100_INT_AHB_ERR ? "AHB_ERR " : "", + status & FTGMAC100_INT_PHYSTS_CHG ? "PHYSTS_CHG" : ""); + + if (status & FTGMAC100_INT_NO_RXBUF) { + /* RX buffer unavailable */ + netdev->stats.rx_over_errors++; + } + + if (status & FTGMAC100_INT_RPKT_LOST) { + /* received packet lost due to RX FIFO full */ + netdev->stats.rx_fifo_errors++; + } + } + + if (completed) { + napi_complete(napi); + + /* enable all interrupts */ + iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTGMAC100_OFFSET_IER); + } + + return rx; +} + +/****************************************************************************** + * struct net_device_ops functions + *****************************************************************************/ +static int ftgmac100_open(struct net_device *netdev) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + int err; + + err = ftgmac100_alloc_buffers(priv); + if (err) { + netdev_err(netdev, "failed to allocate buffers\n"); + goto err_alloc; + } + + err = request_irq(priv->irq, ftgmac100_interrupt, 0, netdev->name, netdev); + if (err) { + netdev_err(netdev, "failed to request irq %d\n", priv->irq); + goto err_irq; + } + + priv->rx_pointer = 0; + priv->tx_clean_pointer = 0; + priv->tx_pointer = 0; + priv->tx_pending = 0; + + err = ftgmac100_reset_hw(priv); + if (err) + goto err_hw; + + ftgmac100_init_hw(priv); + ftgmac100_start_hw(priv, 10); + + phy_start(priv->phydev); + + napi_enable(&priv->napi); + netif_start_queue(netdev); + + /* enable all interrupts */ + iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTGMAC100_OFFSET_IER); + return 0; + +err_hw: + free_irq(priv->irq, netdev); +err_irq: + ftgmac100_free_buffers(priv); +err_alloc: + return err; +} + +static int ftgmac100_stop(struct net_device *netdev) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + + /* disable all interrupts */ + iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); + + netif_stop_queue(netdev); + napi_disable(&priv->napi); + phy_stop(priv->phydev); + + ftgmac100_stop_hw(priv); + free_irq(priv->irq, netdev); + ftgmac100_free_buffers(priv); + + return 0; +} + +static int ftgmac100_hard_start_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + dma_addr_t map; + + if (unlikely(skb->len > MAX_PKT_SIZE)) { + if (net_ratelimit()) + netdev_dbg(netdev, "tx packet too big\n"); + + netdev->stats.tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(priv->dev, map))) { + /* drop packet */ + if (net_ratelimit()) + netdev_err(netdev, "map socket buffer failed\n"); + + netdev->stats.tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + return ftgmac100_xmit(priv, skb, map); +} + +/* optional */ +static int ftgmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + struct ftgmac100 *priv = netdev_priv(netdev); + + return phy_mii_ioctl(priv->phydev, ifr, cmd); +} + +static const struct net_device_ops ftgmac100_netdev_ops = { + .ndo_open = ftgmac100_open, + .ndo_stop = ftgmac100_stop, + .ndo_start_xmit = ftgmac100_hard_start_xmit, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = ftgmac100_do_ioctl, +}; + +/****************************************************************************** + * struct platform_driver functions + *****************************************************************************/ +static int ftgmac100_probe(struct platform_device *pdev) +{ + struct resource *res; + int irq; + struct net_device *netdev; + struct ftgmac100 *priv; + int err; + int i; + + if (!pdev) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + /* setup net_device */ + netdev = alloc_etherdev(sizeof(*priv)); + if (!netdev) { + err = -ENOMEM; + goto err_alloc_etherdev; + } + + SET_NETDEV_DEV(netdev, &pdev->dev); + + SET_ETHTOOL_OPS(netdev, &ftgmac100_ethtool_ops); + netdev->netdev_ops = &ftgmac100_netdev_ops; + netdev->features = NETIF_F_IP_CSUM | NETIF_F_GRO; + + platform_set_drvdata(pdev, netdev); + + /* setup private data */ + priv = netdev_priv(netdev); + priv->netdev = netdev; + priv->dev = &pdev->dev; + + spin_lock_init(&priv->tx_lock); + + /* initialize NAPI */ + netif_napi_add(netdev, &priv->napi, ftgmac100_poll, 64); + + /* map io memory */ + priv->res = request_mem_region(res->start, resource_size(res), + dev_name(&pdev->dev)); + if (!priv->res) { + dev_err(&pdev->dev, "Could not reserve memory region\n"); + err = -ENOMEM; + goto err_req_mem; + } + + priv->base = ioremap(res->start, resource_size(res)); + if (!priv->base) { + dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); + err = -EIO; + goto err_ioremap; + } + + priv->irq = irq; + + /* initialize mdio bus */ + priv->mii_bus = mdiobus_alloc(); + if (!priv->mii_bus) { + err = -EIO; + goto err_alloc_mdiobus; + } + + priv->mii_bus->name = "ftgmac100_mdio"; + snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "ftgmac100_mii"); + + priv->mii_bus->priv = netdev; + priv->mii_bus->read = ftgmac100_mdiobus_read; + priv->mii_bus->write = ftgmac100_mdiobus_write; + priv->mii_bus->reset = ftgmac100_mdiobus_reset; + priv->mii_bus->irq = priv->phy_irq; + + for (i = 0; i < PHY_MAX_ADDR; i++) + priv->mii_bus->irq[i] = PHY_POLL; + + err = mdiobus_register(priv->mii_bus); + if (err) { + dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); + goto err_register_mdiobus; + } + + err = ftgmac100_mii_probe(priv); + if (err) { + dev_err(&pdev->dev, "MII Probe failed!\n"); + goto err_mii_probe; + } + + /* register network device */ + err = register_netdev(netdev); + if (err) { + dev_err(&pdev->dev, "Failed to register netdev\n"); + goto err_register_netdev; + } + + netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base); + + if (!is_valid_ether_addr(netdev->dev_addr)) { + random_ether_addr(netdev->dev_addr); + netdev_info(netdev, "generated random MAC address %pM\n", + netdev->dev_addr); + } + + return 0; + +err_register_netdev: + phy_disconnect(priv->phydev); +err_mii_probe: + mdiobus_unregister(priv->mii_bus); +err_register_mdiobus: + mdiobus_free(priv->mii_bus); +err_alloc_mdiobus: + iounmap(priv->base); +err_ioremap: + release_resource(priv->res); +err_req_mem: + netif_napi_del(&priv->napi); + platform_set_drvdata(pdev, NULL); + free_netdev(netdev); +err_alloc_etherdev: + return err; +} + +static int __exit ftgmac100_remove(struct platform_device *pdev) +{ + struct net_device *netdev; + struct ftgmac100 *priv; + + netdev = platform_get_drvdata(pdev); + priv = netdev_priv(netdev); + + unregister_netdev(netdev); + + phy_disconnect(priv->phydev); + mdiobus_unregister(priv->mii_bus); + mdiobus_free(priv->mii_bus); + + iounmap(priv->base); + release_resource(priv->res); + + netif_napi_del(&priv->napi); + platform_set_drvdata(pdev, NULL); + free_netdev(netdev); + return 0; +} + +static struct platform_driver ftgmac100_driver = { + .probe = ftgmac100_probe, + .remove = __exit_p(ftgmac100_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +/****************************************************************************** + * initialization / finalization + *****************************************************************************/ +static int __init ftgmac100_init(void) +{ + pr_info("Loading version " DRV_VERSION " ...\n"); + return platform_driver_register(&ftgmac100_driver); +} + +static void __exit ftgmac100_exit(void) +{ + platform_driver_unregister(&ftgmac100_driver); +} + +module_init(ftgmac100_init); +module_exit(ftgmac100_exit); + +MODULE_AUTHOR("Po-Yu Chuang "); +MODULE_DESCRIPTION("FTGMAC100 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ftgmac100.h b/drivers/net/ftgmac100.h new file mode 100644 index 00000000000..13408d448b0 --- /dev/null +++ b/drivers/net/ftgmac100.h @@ -0,0 +1,246 @@ +/* + * Faraday FTGMAC100 Gigabit Ethernet + * + * (C) Copyright 2009-2011 Faraday Technology + * Po-Yu Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __FTGMAC100_H +#define __FTGMAC100_H + +#define FTGMAC100_OFFSET_ISR 0x00 +#define FTGMAC100_OFFSET_IER 0x04 +#define FTGMAC100_OFFSET_MAC_MADR 0x08 +#define FTGMAC100_OFFSET_MAC_LADR 0x0c +#define FTGMAC100_OFFSET_MAHT0 0x10 +#define FTGMAC100_OFFSET_MAHT1 0x14 +#define FTGMAC100_OFFSET_NPTXPD 0x18 +#define FTGMAC100_OFFSET_RXPD 0x1c +#define FTGMAC100_OFFSET_NPTXR_BADR 0x20 +#define FTGMAC100_OFFSET_RXR_BADR 0x24 +#define FTGMAC100_OFFSET_HPTXPD 0x28 +#define FTGMAC100_OFFSET_HPTXR_BADR 0x2c +#define FTGMAC100_OFFSET_ITC 0x30 +#define FTGMAC100_OFFSET_APTC 0x34 +#define FTGMAC100_OFFSET_DBLAC 0x38 +#define FTGMAC100_OFFSET_DMAFIFOS 0x3c +#define FTGMAC100_OFFSET_REVR 0x40 +#define FTGMAC100_OFFSET_FEAR 0x44 +#define FTGMAC100_OFFSET_TPAFCR 0x48 +#define FTGMAC100_OFFSET_RBSR 0x4c +#define FTGMAC100_OFFSET_MACCR 0x50 +#define FTGMAC100_OFFSET_MACSR 0x54 +#define FTGMAC100_OFFSET_TM 0x58 +#define FTGMAC100_OFFSET_PHYCR 0x60 +#define FTGMAC100_OFFSET_PHYDATA 0x64 +#define FTGMAC100_OFFSET_FCR 0x68 +#define FTGMAC100_OFFSET_BPR 0x6c +#define FTGMAC100_OFFSET_WOLCR 0x70 +#define FTGMAC100_OFFSET_WOLSR 0x74 +#define FTGMAC100_OFFSET_WFCRC 0x78 +#define FTGMAC100_OFFSET_WFBM1 0x80 +#define FTGMAC100_OFFSET_WFBM2 0x84 +#define FTGMAC100_OFFSET_WFBM3 0x88 +#define FTGMAC100_OFFSET_WFBM4 0x8c +#define FTGMAC100_OFFSET_NPTXR_PTR 0x90 +#define FTGMAC100_OFFSET_HPTXR_PTR 0x94 +#define FTGMAC100_OFFSET_RXR_PTR 0x98 +#define FTGMAC100_OFFSET_TX 0xa0 +#define FTGMAC100_OFFSET_TX_MCOL_SCOL 0xa4 +#define FTGMAC100_OFFSET_TX_ECOL_FAIL 0xa8 +#define FTGMAC100_OFFSET_TX_LCOL_UND 0xac +#define FTGMAC100_OFFSET_RX 0xb0 +#define FTGMAC100_OFFSET_RX_BC 0xb4 +#define FTGMAC100_OFFSET_RX_MC 0xb8 +#define FTGMAC100_OFFSET_RX_PF_AEP 0xbc +#define FTGMAC100_OFFSET_RX_RUNT 0xc0 +#define FTGMAC100_OFFSET_RX_CRCER_FTL 0xc4 +#define FTGMAC100_OFFSET_RX_COL_LOST 0xc8 + +/* + * Interrupt status register & interrupt enable register + */ +#define FTGMAC100_INT_RPKT_BUF (1 << 0) +#define FTGMAC100_INT_RPKT_FIFO (1 << 1) +#define FTGMAC100_INT_NO_RXBUF (1 << 2) +#define FTGMAC100_INT_RPKT_LOST (1 << 3) +#define FTGMAC100_INT_XPKT_ETH (1 << 4) +#define FTGMAC100_INT_XPKT_FIFO (1 << 5) +#define FTGMAC100_INT_NO_NPTXBUF (1 << 6) +#define FTGMAC100_INT_XPKT_LOST (1 << 7) +#define FTGMAC100_INT_AHB_ERR (1 << 8) +#define FTGMAC100_INT_PHYSTS_CHG (1 << 9) +#define FTGMAC100_INT_NO_HPTXBUF (1 << 10) + +/* + * Interrupt timer control register + */ +#define FTGMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0) +#define FTGMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4) +#define FTGMAC100_ITC_RXINT_TIME_SEL (1 << 7) +#define FTGMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8) +#define FTGMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12) +#define FTGMAC100_ITC_TXINT_TIME_SEL (1 << 15) + +/* + * Automatic polling timer control register + */ +#define FTGMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0) +#define FTGMAC100_APTC_RXPOLL_TIME_SEL (1 << 4) +#define FTGMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8) +#define FTGMAC100_APTC_TXPOLL_TIME_SEL (1 << 12) + +/* + * DMA burst length and arbitration control register + */ +#define FTGMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 0) +#define FTGMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 3) +#define FTGMAC100_DBLAC_RX_THR_EN (1 << 6) +#define FTGMAC100_DBLAC_RXBURST_SIZE(x) (((x) & 0x3) << 8) +#define FTGMAC100_DBLAC_TXBURST_SIZE(x) (((x) & 0x3) << 10) +#define FTGMAC100_DBLAC_RXDES_SIZE(x) (((x) & 0xf) << 12) +#define FTGMAC100_DBLAC_TXDES_SIZE(x) (((x) & 0xf) << 16) +#define FTGMAC100_DBLAC_IFG_CNT(x) (((x) & 0x7) << 20) +#define FTGMAC100_DBLAC_IFG_INC (1 << 23) + +/* + * DMA FIFO status register + */ +#define FTGMAC100_DMAFIFOS_RXDMA1_SM(dmafifos) ((dmafifos) & 0xf) +#define FTGMAC100_DMAFIFOS_RXDMA2_SM(dmafifos) (((dmafifos) >> 4) & 0xf) +#define FTGMAC100_DMAFIFOS_RXDMA3_SM(dmafifos) (((dmafifos) >> 8) & 0x7) +#define FTGMAC100_DMAFIFOS_TXDMA1_SM(dmafifos) (((dmafifos) >> 12) & 0xf) +#define FTGMAC100_DMAFIFOS_TXDMA2_SM(dmafifos) (((dmafifos) >> 16) & 0x3) +#define FTGMAC100_DMAFIFOS_TXDMA3_SM(dmafifos) (((dmafifos) >> 18) & 0xf) +#define FTGMAC100_DMAFIFOS_RXFIFO_EMPTY (1 << 26) +#define FTGMAC100_DMAFIFOS_TXFIFO_EMPTY (1 << 27) +#define FTGMAC100_DMAFIFOS_RXDMA_GRANT (1 << 28) +#define FTGMAC100_DMAFIFOS_TXDMA_GRANT (1 << 29) +#define FTGMAC100_DMAFIFOS_RXDMA_REQ (1 << 30) +#define FTGMAC100_DMAFIFOS_TXDMA_REQ (1 << 31) + +/* + * Receive buffer size register + */ +#define FTGMAC100_RBSR_SIZE(x) ((x) & 0x3fff) + +/* + * MAC control register + */ +#define FTGMAC100_MACCR_TXDMA_EN (1 << 0) +#define FTGMAC100_MACCR_RXDMA_EN (1 << 1) +#define FTGMAC100_MACCR_TXMAC_EN (1 << 2) +#define FTGMAC100_MACCR_RXMAC_EN (1 << 3) +#define FTGMAC100_MACCR_RM_VLAN (1 << 4) +#define FTGMAC100_MACCR_HPTXR_EN (1 << 5) +#define FTGMAC100_MACCR_LOOP_EN (1 << 6) +#define FTGMAC100_MACCR_ENRX_IN_HALFTX (1 << 7) +#define FTGMAC100_MACCR_FULLDUP (1 << 8) +#define FTGMAC100_MACCR_GIGA_MODE (1 << 9) +#define FTGMAC100_MACCR_CRC_APD (1 << 10) +#define FTGMAC100_MACCR_RX_RUNT (1 << 12) +#define FTGMAC100_MACCR_JUMBO_LF (1 << 13) +#define FTGMAC100_MACCR_RX_ALL (1 << 14) +#define FTGMAC100_MACCR_HT_MULTI_EN (1 << 15) +#define FTGMAC100_MACCR_RX_MULTIPKT (1 << 16) +#define FTGMAC100_MACCR_RX_BROADPKT (1 << 17) +#define FTGMAC100_MACCR_DISCARD_CRCERR (1 << 18) +#define FTGMAC100_MACCR_FAST_MODE (1 << 19) +#define FTGMAC100_MACCR_SW_RST (1 << 31) + +/* + * PHY control register + */ +#define FTGMAC100_PHYCR_MDC_CYCTHR_MASK 0x3f +#define FTGMAC100_PHYCR_MDC_CYCTHR(x) ((x) & 0x3f) +#define FTGMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16) +#define FTGMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21) +#define FTGMAC100_PHYCR_MIIRD (1 << 26) +#define FTGMAC100_PHYCR_MIIWR (1 << 27) + +/* + * PHY data register + */ +#define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff) +#define FTGMAC100_PHYDATA_MIIRDATA(phydata) (((phydata) >> 16) & 0xffff) + +/* + * Transmit descriptor, aligned to 16 bytes + */ +struct ftgmac100_txdes { + unsigned int txdes0; + unsigned int txdes1; + unsigned int txdes2; /* not used by HW */ + unsigned int txdes3; /* TXBUF_BADR */ +} __attribute__ ((aligned(16))); + +#define FTGMAC100_TXDES0_TXBUF_SIZE(x) ((x) & 0x3fff) +#define FTGMAC100_TXDES0_EDOTR (1 << 15) +#define FTGMAC100_TXDES0_CRC_ERR (1 << 19) +#define FTGMAC100_TXDES0_LTS (1 << 28) +#define FTGMAC100_TXDES0_FTS (1 << 29) +#define FTGMAC100_TXDES0_TXDMA_OWN (1 << 31) + +#define FTGMAC100_TXDES1_VLANTAG_CI(x) ((x) & 0xffff) +#define FTGMAC100_TXDES1_INS_VLANTAG (1 << 16) +#define FTGMAC100_TXDES1_TCP_CHKSUM (1 << 17) +#define FTGMAC100_TXDES1_UDP_CHKSUM (1 << 18) +#define FTGMAC100_TXDES1_IP_CHKSUM (1 << 19) +#define FTGMAC100_TXDES1_LLC (1 << 22) +#define FTGMAC100_TXDES1_TX2FIC (1 << 30) +#define FTGMAC100_TXDES1_TXIC (1 << 31) + +/* + * Receive descriptor, aligned to 16 bytes + */ +struct ftgmac100_rxdes { + unsigned int rxdes0; + unsigned int rxdes1; + unsigned int rxdes2; /* not used by HW */ + unsigned int rxdes3; /* RXBUF_BADR */ +} __attribute__ ((aligned(16))); + +#define FTGMAC100_RXDES0_VDBC 0x3fff +#define FTGMAC100_RXDES0_EDORR (1 << 15) +#define FTGMAC100_RXDES0_MULTICAST (1 << 16) +#define FTGMAC100_RXDES0_BROADCAST (1 << 17) +#define FTGMAC100_RXDES0_RX_ERR (1 << 18) +#define FTGMAC100_RXDES0_CRC_ERR (1 << 19) +#define FTGMAC100_RXDES0_FTL (1 << 20) +#define FTGMAC100_RXDES0_RUNT (1 << 21) +#define FTGMAC100_RXDES0_RX_ODD_NB (1 << 22) +#define FTGMAC100_RXDES0_FIFO_FULL (1 << 23) +#define FTGMAC100_RXDES0_PAUSE_OPCODE (1 << 24) +#define FTGMAC100_RXDES0_PAUSE_FRAME (1 << 25) +#define FTGMAC100_RXDES0_LRS (1 << 28) +#define FTGMAC100_RXDES0_FRS (1 << 29) +#define FTGMAC100_RXDES0_RXPKT_RDY (1 << 31) + +#define FTGMAC100_RXDES1_VLANTAG_CI 0xffff +#define FTGMAC100_RXDES1_PROT_MASK (0x3 << 20) +#define FTGMAC100_RXDES1_PROT_NONIP (0x0 << 20) +#define FTGMAC100_RXDES1_PROT_IP (0x1 << 20) +#define FTGMAC100_RXDES1_PROT_TCPIP (0x2 << 20) +#define FTGMAC100_RXDES1_PROT_UDPIP (0x3 << 20) +#define FTGMAC100_RXDES1_LLC (1 << 22) +#define FTGMAC100_RXDES1_DF (1 << 23) +#define FTGMAC100_RXDES1_VLANTAG_AVAIL (1 << 24) +#define FTGMAC100_RXDES1_TCP_CHKSUM_ERR (1 << 25) +#define FTGMAC100_RXDES1_UDP_CHKSUM_ERR (1 << 26) +#define FTGMAC100_RXDES1_IP_CHKSUM_ERR (1 << 27) + +#endif /* __FTGMAC100_H */ -- cgit v1.2.3-70-g09d2 From 40d15cd06e87722b1cc27d56c8274617580f2c56 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 10 Jun 2011 00:50:32 +0000 Subject: net: DM9000: Add support for byte EEPROM access Given many versions of ethtool's reluctance to do anything other than byte accesses to the EEPROM interface, it is easier to update the driver to support byte accesses so that all the ethtool versions that have been observed in Debian can write the EEPROM. Signed-off-by: Ben Dooks Signed-off-by: Mark Brown Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/dm9000.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 863e9c459e6..8ef31dc4704 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -535,21 +535,35 @@ static int dm9000_set_eeprom(struct net_device *dev, board_info_t *dm = to_dm9000_board(dev); int offset = ee->offset; int len = ee->len; - int i; + int done; /* EEPROM access is aligned to two bytes */ - if ((len & 1) != 0 || (offset & 1) != 0) - return -EINVAL; - if (dm->flags & DM9000_PLATF_NO_EEPROM) return -ENOENT; if (ee->magic != DM_EEPROM_MAGIC) return -EINVAL; - for (i = 0; i < len; i += 2) - dm9000_write_eeprom(dm, (offset + i) / 2, data + i); + while (len > 0) { + if (len & 1 || offset & 1) { + int which = offset & 1; + u8 tmp[2]; + + dm9000_read_eeprom(dm, offset / 2, tmp); + tmp[which] = *data; + dm9000_write_eeprom(dm, offset / 2, tmp); + + done = 1; + } else { + dm9000_write_eeprom(dm, offset / 2, data); + done = 2; + } + + data += done; + offset += done; + len -= done; + } return 0; } -- cgit v1.2.3-70-g09d2 From 10a8d94a95742bb15b4e617ee9884bb4381362be Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 10 Jun 2011 00:56:17 +0000 Subject: virtio_net: introduce VIRTIO_NET_HDR_F_DATA_VALID There's no need for the guest to validate the checksum if it have been validated by host nics. So this patch introduces a new flag - VIRTIO_NET_HDR_F_DATA_VALID which is used to bypass the checksum examing in guest. The backend (tap/macvtap) may set this flag when met skbs with CHECKSUM_UNNECESSARY to save cpu utilization. No feature negotiation is needed as old driver just ignore this flag. Iperf shows 12%-30% performance improvement for UDP traffic. For TCP, when gro is on no difference as it produces skb with partial checksum. But when gro is disabled, 20% or even higher improvement could be measured by netperf. Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 2 ++ drivers/net/tun.c | 2 ++ drivers/net/virtio_net.c | 2 ++ include/linux/virtio_net.h | 1 + net/packet/af_packet.c | 2 ++ 5 files changed, 9 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 6696e56e632..ecee0fe65a9 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -508,6 +508,8 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; vnet_hdr->csum_start = skb_checksum_start_offset(skb); vnet_hdr->csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + vnet_hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID; } /* else everything is zero */ return 0; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ef68e13c042..4dab85eecb6 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -788,6 +788,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; gso.csum_start = skb_checksum_start_offset(skb); gso.csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; } /* else everything is zero */ if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index f6853247a62..be3686a298d 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -274,6 +274,8 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len) hdr->hdr.csum_start, hdr->hdr.csum_offset)) goto frame_err; + } else if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) { + skb->ip_summed = CHECKSUM_UNNECESSARY; } skb->protocol = eth_type_trans(skb, dev); diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 136040bba3e..970d5a2a904 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -63,6 +63,7 @@ struct virtio_net_config { * specify GSO or CSUM features, you can simply ignore the header. */ struct virtio_net_hdr { #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 // Use csum_start, csum_offset +#define VIRTIO_NET_HDR_F_DATA_VALID 2 // Csum is valid __u8 flags; #define VIRTIO_NET_HDR_GSO_NONE 0 // Not a GSO frame #define VIRTIO_NET_HDR_GSO_TCPV4 1 // GSO frame, IPv4 TCP (TSO) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 67f6749a0a4..b54ec41adea 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1685,6 +1685,8 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; vnet_hdr.csum_start = skb_checksum_start_offset(skb); vnet_hdr.csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; } /* else everything is zero */ err = memcpy_toiovec(msg->msg_iov, (void *)&vnet_hdr, -- cgit v1.2.3-70-g09d2 From eb8a50d9a6118a310c0b01d47091a2a5d994b549 Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Sat, 11 Jun 2011 15:58:46 -0700 Subject: be2net: Enable NETIF_F_TSO6 for VLAN traffic for BE NETIF_F_TSO6 for VLAN packets was not enabled for BE adapters. Enabling it. Signed-off-by: Padmanabh Ratnakar Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 9ba197b0978..6ddaa34121e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2925,12 +2925,9 @@ static void be_netdev_init(struct net_device *netdev) netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | + netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - if (lancer_chip(adapter)) - netdev->vlan_features |= NETIF_F_TSO6; - netdev->flags |= IFF_MULTICAST; /* Default settings for Rx and Tx flow control */ -- cgit v1.2.3-70-g09d2 From 539d3ee6376eba05ebd947c81d097e31a3ee42a8 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 10 Jun 2011 03:36:43 +0000 Subject: net: fix MIPS fallout from "net: remove interrupt.h inclusion from netdevice.h" Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- drivers/net/bcm63xx_enet.c | 1 + drivers/net/cpmac.c | 1 + drivers/net/mipsnet.c | 1 + drivers/net/octeon/octeon_mgmt.c | 1 + 4 files changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index f1573d492e9..4753bb9731f 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -18,6 +18,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include +#include #include #include #include diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index fec939f8f65..086ce0418b2 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -18,6 +18,7 @@ #include #include +#include #include #include diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index 869f0ea43a5..004e64ab1f9 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c index b264f0f4560..429e08c84e9 100644 --- a/drivers/net/octeon/octeon_mgmt.c +++ b/drivers/net/octeon/octeon_mgmt.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From 830a9c75514b477994fd3847f72654d3dbdfa5ca Mon Sep 17 00:00:00 2001 From: Jiri Bohac Date: Fri, 10 Jun 2011 10:27:20 +0000 Subject: bonding: clean up bond_del_vlan() 1) the setting of NETIF_F_VLAN_CHALLENGED in bond_del_vlan() is useless since commit b2a103e6 because bond_fix_features() now sets NETIF_F_VLAN_CHALLENGED whenever the last slave is being removed. 2) the code never triggers anyway as vlan_list is never empty since ad1afb00. Signed-off-by: Jiri Bohac Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index bb1af9c1629..07e866d5a87 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -329,16 +329,6 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) kfree(vlan); - if (list_empty(&bond->vlan_list) && - (bond->slave_cnt == 0)) { - /* Last VLAN removed and no slaves, so - * restore block on adding VLANs. This will - * be removed once new slaves that are not - * VLAN challenged will be added. - */ - bond->dev->features |= NETIF_F_VLAN_CHALLENGED; - } - res = 0; goto out; } -- cgit v1.2.3-70-g09d2 From 18a03b9772da749efb8d92bd9893bfe3bd442425 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:18:59 +0000 Subject: fec: enable transmit and receive time stamping. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch has been tested on the Freescale M5234BCC, which includes the National Semiconductor DP83640 with IEEE 1588 support. Cc: Greg Ungerer Cc: "Uwe Kleine-König" Cc: Shawn Guo Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/fec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 885d8baff7d..965fe90e1c2 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -326,6 +326,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) spin_unlock_irqrestore(&fep->hw_lock, flags); + skb_tx_timestamp(skb); + return NETDEV_TX_OK; } @@ -650,7 +652,8 @@ fec_enet_rx(struct net_device *ndev) skb_put(skb, pkt_len - 4); /* Make room */ skb_copy_to_linear_data(skb, data, pkt_len - 4); skb->protocol = eth_type_trans(skb, ndev); - netif_rx(skb); + if (!skb_defer_rx_timestamp(skb)) + netif_rx(skb); } bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, data, -- cgit v1.2.3-70-g09d2 From fb290cdd43463e6be339bfb021aa9a00cdb50ea2 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:00 +0000 Subject: davinci_emac: pass ioctls through to phy device. The DaVinci EMAC driver does not implement any ioctls, but still it can pass them through to the phy device. This makes it possible for a phy to offer PHC capabilities. Cc: Anant Gole Cc: Kevin Hilman Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/davinci_emac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index dcc4a170b0f..5c2baa4f785 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1489,14 +1489,14 @@ static void emac_adjust_link(struct net_device *ndev) */ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) { - dev_warn(&ndev->dev, "DaVinci EMAC: ioctl not supported\n"); + struct emac_priv *priv = netdev_priv(ndev); if (!(netif_running(ndev))) return -EINVAL; /* TODO: Add phy read and write and private statistics get feature */ - return -EOPNOTSUPP; + return phy_mii_ioctl(priv->phydev, ifrq, cmd); } static int match_first_device(struct device *dev, void *data) -- cgit v1.2.3-70-g09d2 From 1ca9495f851d6d41a118ae064002d51afdfd415b Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:01 +0000 Subject: davinci_emac: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping for the DaVinci EMAC driver. Tested together with the dp83640 PHY. Cc: Anant Gole Cc: Kevin Hilman Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/davinci_emac.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 5c2baa4f785..f5688ff58a4 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1090,6 +1090,7 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) dev_err(emac_dev, "DaVinci EMAC: desc submit failed"); goto fail_tx; } + skb_tx_timestamp(skb); return NETDEV_TX_OK; -- cgit v1.2.3-70-g09d2 From 2669069aacc914821b45fe14a49e7fe0ba5d10bd Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:02 +0000 Subject: tg3: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping for the TIGON3 driver. Compile tested only. Cc: Matt Carlson Cc: Michael Chan Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c8a145d72f1..aa1d1defc82 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6092,6 +6092,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Packets are ready, update Tx producer idx local and on card. */ tw32_tx_mbox(tnapi->prodmbox, entry); + skb_tx_timestamp(skb); + tnapi->tx_prod = entry; if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) { netif_tx_stop_queue(txq); -- cgit v1.2.3-70-g09d2 From ff9b3078b918480a471b065c36133a144a531038 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:03 +0000 Subject: dnet: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping in the "Dave ethernet interface." Compile tested only. Cc: Ilya Yanok Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/dnet.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index b2269104667..c1063d1540c 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -588,6 +588,8 @@ static netdev_tx_t dnet_start_xmit(struct sk_buff *skb, struct net_device *dev) dnet_writel(bp, irq_enable, INTR_ENB); } + skb_tx_timestamp(skb); + /* free the buffer */ dev_kfree_skb(skb); -- cgit v1.2.3-70-g09d2 From 68f51394073b30ef8648f8516d5a7d40c68b1f8a Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:04 +0000 Subject: ethoc: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping for the OpenCores 10/100 MAC driver. Compile tested only. Cc: Thierry Reding Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 9162c705c4f..0e8cc75bb5f 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -875,6 +875,7 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev) } spin_unlock_irq(&priv->lock); + skb_tx_timestamp(skb); out: dev_kfree_skb(skb); return NETDEV_TX_OK; -- cgit v1.2.3-70-g09d2 From 7c4bb9fcaed7148eb25c0cf0997f01971fba21e9 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:05 +0000 Subject: r6040: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping for the RDC R6040 Fast Ethernet MAC. Compile tested only. Cc: Florian Fainelli Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/r6040.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 200a363c3bf..5ee5f8f932f 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -846,6 +846,8 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb, spin_unlock_irqrestore(&lp->lock, flags); + skb_tx_timestamp(skb); + return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From 3e82ce120c6f5036c3c739903e67218fd47cbc4c Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:06 +0000 Subject: stmmac: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping for the STMicroelectronics Ethernet driver. Compile tested only. Cc: Giuseppe Cavallaro Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index e25e44a45c2..5b85f4ca200 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1081,6 +1081,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) priv->hw->dma->enable_dma_transmission(priv->ioaddr); + skb_tx_timestamp(skb); + return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From ec1d7c9a5e9c136e08a9b1df3109ad5d38d8179c Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 12 Jun 2011 02:19:07 +0000 Subject: smsc9420: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping for the smsc9420. Compile tested only. Cc: Steve Glendinning Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/smsc9420.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 5e5e64da5cb..5555102bb96 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -1035,6 +1035,8 @@ static netdev_tx_t smsc9420_hard_start_xmit(struct sk_buff *skb, smsc9420_reg_write(pd, TX_POLL_DEMAND, 1); smsc9420_pci_flush_write(pd); + skb_tx_timestamp(skb); + return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From bf0239a98a7378c6a1a6b01701ec5e27591f52ce Mon Sep 17 00:00:00 2001 From: "Peter Pan(潘卫平)" Date: Mon, 13 Jun 2011 04:30:10 +0000 Subject: bonding:delete a dereference before check Dan Carpenter found that there was a dereference before a check, added in 56d00c677de0(bonding:delete lacp_fast from ad_bond_info). Signed-off-by: Weiping Pan Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6122725fc7c..77da2e84962 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -1900,7 +1900,6 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) int bond_3ad_bind_slave(struct slave *slave) { struct bonding *bond = bond_get_bond_by_slave(slave); - int lacp_fast = bond->params.lacp_fast; struct port *port; struct aggregator *aggregator; @@ -1916,7 +1915,7 @@ int bond_3ad_bind_slave(struct slave *slave) // port initialization port = &(SLAVE_AD_INFO(slave).port); - ad_initialize_port(port, lacp_fast); + ad_initialize_port(port, bond->params.lacp_fast); port->slave = slave; port->actor_port_number = SLAVE_AD_INFO(slave).id; -- cgit v1.2.3-70-g09d2 From b7c7deeb4c77538577f0b6a724f10ce8693eb648 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 13 Jun 2011 05:48:30 +0000 Subject: vmxnet3: remove unused variable While doing some backporting I noticed that vmxnet3 had a variable that was set but never used. Get rid of it, and stop the compiler from griping Signed-off-by: Neil Horman CC: "VMware, Inc." CC: "David S. Miller" Signed-off-by: Bhavesh Davda Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index cea1b3c2953..33097ec1c51 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -405,10 +405,8 @@ vmxnet3_tq_cleanup(struct vmxnet3_tx_queue *tq, while (tq->tx_ring.next2comp != tq->tx_ring.next2fill) { struct vmxnet3_tx_buf_info *tbi; - union Vmxnet3_GenericDesc *gdesc; tbi = tq->buf_info + tq->tx_ring.next2comp; - gdesc = tq->tx_ring.base + tq->tx_ring.next2comp; vmxnet3_unmap_tx_buf(tbi, adapter->pdev); if (tbi->skb) { -- cgit v1.2.3-70-g09d2 From 59e5137357559ec60b2e72bdc3d5a7e22c47212b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 14 Jun 2011 01:32:38 +0000 Subject: cnic: Move indexing function pointers to struct kcq_info The hardware indexing scheme for the FCoE kcq will change in the upcoming firmware. This patch will cope with the change easily. Signed-off-by: Michael Chan Signed-off-by: Vladislav Zolotarov Signed-off-by: David S. Miller --- drivers/net/cnic.c | 84 ++++++++++++++++++++++++++++-------------------------- drivers/net/cnic.h | 5 ++-- 2 files changed, 46 insertions(+), 43 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 363c7f36890..07f1b13c8dc 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -900,24 +900,56 @@ static int cnic_alloc_context(struct cnic_dev *dev) return 0; } -static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info) +static u16 cnic_bnx2_next_idx(u16 idx) +{ + return idx + 1; +} + +static u16 cnic_bnx2_hw_idx(u16 idx) +{ + return idx; +} + +static u16 cnic_bnx2x_next_idx(u16 idx) { - int err, i, is_bnx2 = 0; + idx++; + if ((idx & MAX_KCQE_CNT) == MAX_KCQE_CNT) + idx++; + + return idx; +} + +static u16 cnic_bnx2x_hw_idx(u16 idx) +{ + if ((idx & MAX_KCQE_CNT) == MAX_KCQE_CNT) + idx++; + return idx; +} + +static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info, + bool use_pg_tbl) +{ + int err, i, use_page_tbl = 0; struct kcqe **kcq; - if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) - is_bnx2 = 1; + if (use_pg_tbl) + use_page_tbl = 1; - err = cnic_alloc_dma(dev, &info->dma, KCQ_PAGE_CNT, is_bnx2); + err = cnic_alloc_dma(dev, &info->dma, KCQ_PAGE_CNT, use_page_tbl); if (err) return err; kcq = (struct kcqe **) info->dma.pg_arr; info->kcq = kcq; - if (is_bnx2) + info->next_idx = cnic_bnx2_next_idx; + info->hw_idx = cnic_bnx2_hw_idx; + if (use_pg_tbl) return 0; + info->next_idx = cnic_bnx2x_next_idx; + info->hw_idx = cnic_bnx2x_hw_idx; + for (i = 0; i < KCQ_PAGE_CNT; i++) { struct bnx2x_bd_chain_next *next = (struct bnx2x_bd_chain_next *) &kcq[i][MAX_KCQE_CNT]; @@ -1060,7 +1092,7 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev) goto error; cp->kwq = (struct kwqe **) cp->kwq_info.pg_arr; - ret = cnic_alloc_kcq(dev, &cp->kcq1); + ret = cnic_alloc_kcq(dev, &cp->kcq1, true); if (ret) goto error; @@ -1196,12 +1228,12 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) j++; } - ret = cnic_alloc_kcq(dev, &cp->kcq1); + ret = cnic_alloc_kcq(dev, &cp->kcq1, false); if (ret) goto error; if (BNX2X_CHIP_IS_E2(cp->chip_id)) { - ret = cnic_alloc_kcq(dev, &cp->kcq2); + ret = cnic_alloc_kcq(dev, &cp->kcq2, false); if (ret) goto error; } @@ -2652,32 +2684,6 @@ end: cnic_spq_completion(dev, DRV_CTL_RET_L5_SPQ_CREDIT_CMD, comp); } -static u16 cnic_bnx2_next_idx(u16 idx) -{ - return idx + 1; -} - -static u16 cnic_bnx2_hw_idx(u16 idx) -{ - return idx; -} - -static u16 cnic_bnx2x_next_idx(u16 idx) -{ - idx++; - if ((idx & MAX_KCQE_CNT) == MAX_KCQE_CNT) - idx++; - - return idx; -} - -static u16 cnic_bnx2x_hw_idx(u16 idx) -{ - if ((idx & MAX_KCQE_CNT) == MAX_KCQE_CNT) - idx++; - return idx; -} - static int cnic_get_kcqes(struct cnic_dev *dev, struct kcq_info *info) { struct cnic_local *cp = dev->cnic_priv; @@ -2688,12 +2694,12 @@ static int cnic_get_kcqes(struct cnic_dev *dev, struct kcq_info *info) i = ri = last = info->sw_prod_idx; ri &= MAX_KCQ_IDX; hw_prod = *info->hw_prod_idx_ptr; - hw_prod = cp->hw_idx(hw_prod); + hw_prod = info->hw_idx(hw_prod); while ((i != hw_prod) && (kcqe_cnt < MAX_COMPLETED_KCQE)) { kcqe = &info->kcq[KCQ_PG(ri)][KCQ_IDX(ri)]; cp->completed_kcq[kcqe_cnt++] = kcqe; - i = cp->next_idx(i); + i = info->next_idx(i); ri = i & MAX_KCQ_IDX; if (likely(!(kcqe->kcqe_op_flag & KCQE_FLAGS_NEXT))) { last_cnt = kcqe_cnt; @@ -5227,8 +5233,6 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev) cp->enable_int = cnic_enable_bnx2_int; cp->disable_int_sync = cnic_disable_bnx2_int_sync; cp->close_conn = cnic_close_bnx2_conn; - cp->next_idx = cnic_bnx2_next_idx; - cp->hw_idx = cnic_bnx2_hw_idx; return cdev; cnic_err: @@ -5294,8 +5298,6 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) else cp->ack_int = cnic_ack_bnx2x_msix; cp->close_conn = cnic_close_bnx2x_conn; - cp->next_idx = cnic_bnx2x_next_idx; - cp->hw_idx = cnic_bnx2x_hw_idx; return cdev; } diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 3367a6d3a77..eb11821108a 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -185,6 +185,9 @@ struct kcq_info { u16 sw_prod_idx; u16 *status_idx_ptr; u32 io_addr; + + u16 (*next_idx)(u16); + u16 (*hw_idx)(u16); }; struct iro { @@ -332,8 +335,6 @@ struct cnic_local { void (*disable_int_sync)(struct cnic_dev *); void (*ack_int)(struct cnic_dev *); void (*close_conn)(struct cnic_sock *, u32 opcode); - u16 (*next_idx)(u16); - u16 (*hw_idx)(u16); }; struct bnx2x_bd_chain_next { -- cgit v1.2.3-70-g09d2 From 8eef2af1824da37b428ad34e7ff3490b327b39c1 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:32:47 +0000 Subject: bnx2x: do not allocate FCoE ring if disabled Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 831c6ec98ee..122cc295d7b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2621,7 +2621,12 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) #ifdef BCM_CNIC } #endif - set_sb_shortcuts(bp, index); + + /* FCoE Queue uses Default SB and doesn't ACK the SB, thus no need to + * set shortcuts for it. + */ + if (!IS_FCOE_IDX(index)) + set_sb_shortcuts(bp, index); /* Tx */ if (!skip_tx_queue(bp, index)) { @@ -2698,9 +2703,13 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) if (bnx2x_alloc_fp_mem_at(bp, 0)) return -ENOMEM; #ifdef BCM_CNIC - /* FCoE */ - if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX)) - return -ENOMEM; + if (!NO_FCOE(bp)) + /* FCoE */ + if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX)) + /* we will fail load process instead of mark + * NO_FCOE_FLAG + */ + return -ENOMEM; #endif /* RSS */ for_each_nondefault_eth_queue(bp, i) -- cgit v1.2.3-70-g09d2 From 4b7ed8978dc79de45e9fbc202f4328388311f81f Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:32:53 +0000 Subject: bnx2x: remove references to intr_sem It's not needed any more since device always operates in interrupt-driven mode Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 2 -- drivers/net/bnx2x/bnx2x_cmn.c | 23 +++++------------------ drivers/net/bnx2x/bnx2x_main.c | 36 ------------------------------------ 3 files changed, 5 insertions(+), 56 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 480e02df86e..4b85489dc8e 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -925,8 +925,6 @@ struct bnx2x { struct iro *iro_arr; #define IRO (bp->iro_arr) - atomic_t intr_sem; - bnx2x_recovery_state_t recovery_state; int is_leader; struct msix_entry *msix_table; diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 122cc295d7b..14e7eb15e51 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -739,12 +739,6 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) struct bnx2x_fastpath *fp = fp_cookie; struct bnx2x *bp = fp->bp; - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return IRQ_HANDLED; - } - DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB " "[fp %d fw_sd %d igusb %d]\n", fp->index, fp->fw_sb_id, fp->igu_sb_id); @@ -1289,18 +1283,11 @@ static void bnx2x_napi_disable(struct bnx2x *bp) void bnx2x_netif_start(struct bnx2x *bp) { - int intr_sem; - - intr_sem = atomic_dec_and_test(&bp->intr_sem); - smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ - - if (intr_sem) { - if (netif_running(bp->dev)) { - bnx2x_napi_enable(bp); - bnx2x_int_enable(bp); - if (bp->state == BNX2X_STATE_OPEN) - netif_tx_wake_all_queues(bp->dev); - } + if (netif_running(bp->dev)) { + bnx2x_napi_enable(bp); + bnx2x_int_enable(bp); + if (bp->state == BNX2X_STATE_OPEN) + netif_tx_wake_all_queues(bp->dev); } } diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2e89b6cf37a..637ff5ac244 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1285,10 +1285,6 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; int i, offset; - /* disable interrupt handling */ - atomic_inc(&bp->intr_sem); - smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ - if (disable_hw) /* prevent the HW from sending interrupts */ bnx2x_int_disable(bp); @@ -1411,12 +1407,6 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) } DP(NETIF_MSG_INTR, "got an interrupt status 0x%x\n", status); - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return IRQ_HANDLED; - } - #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) return IRQ_HANDLED; @@ -3771,12 +3761,6 @@ static void bnx2x_sp_task(struct work_struct *work) struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work); u16 status; - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return; - } - status = bnx2x_update_dsb_idx(bp); /* if (status == 0) */ /* BNX2X_ERR("spurious slowpath interrupt!\n"); */ @@ -3820,12 +3804,6 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) struct net_device *dev = dev_instance; struct bnx2x *bp = netdev_priv(dev); - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return IRQ_HANDLED; - } - bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); @@ -3859,9 +3837,6 @@ static void bnx2x_timer(unsigned long data) if (!netif_running(bp->dev)) return; - if (atomic_read(&bp->intr_sem) != 0) - goto timer_restart; - if (poll) { struct bnx2x_fastpath *fp = &bp->fp[0]; @@ -3896,7 +3871,6 @@ static void bnx2x_timer(unsigned long data) if (bp->state == BNX2X_STATE_OPEN) bnx2x_stats_handle(bp, STATS_EVENT_UPDATE); -timer_restart: mod_timer(&bp->timer, jiffies + bp->current_interval); } @@ -4470,9 +4444,6 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) bnx2x_init_ind_table(bp); bnx2x_stats_init(bp); - /* At this point, we are ready for interrupts */ - atomic_set(&bp->intr_sem, 0); - /* flush all before enabling interrupts */ mb(); mmiowb(); @@ -8648,10 +8619,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) int timer_interval; int rc; - /* Disable interrupt handling until HW is initialized */ - atomic_set(&bp->intr_sem, 1); - smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ - mutex_init(&bp->port.phy_mutex); mutex_init(&bp->fw_mb_mutex); spin_lock_init(&bp->stats_lock); @@ -10169,9 +10136,6 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, if (ops == NULL) return -EINVAL; - if (atomic_read(&bp->intr_sem) != 0) - return -EBUSY; - bp->cnic_kwq = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!bp->cnic_kwq) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 93ef5c02a436000d6b90ff59c9d25563000eee7f Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:33:02 +0000 Subject: bnx2x: put start bd csum in separate function Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 14e7eb15e51..3a2a50c36b4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2136,6 +2136,24 @@ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, sizeof(struct udphdr) - skb->data; } +static inline void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_start_bd *tx_start_bd, u32 xmit_type) +{ + + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; + + if (xmit_type & XMIT_CSUM_V4) + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IP_CSUM; + else + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IPV6; + + if (!(xmit_type & XMIT_CSUM_TCP)) + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IS_UDP; + +} + /** * bnx2x_set_pbd_csum - update PBD with checksum and return header length * @@ -2307,20 +2325,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - if (xmit_type & XMIT_CSUM) { - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; - - if (xmit_type & XMIT_CSUM_V4) - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IP_CSUM; - else - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IPV6; - - if (!(xmit_type & XMIT_CSUM_TCP)) - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IS_UDP; - } + if (xmit_type & XMIT_CSUM) + bnx2x_set_sbd_csum(bp, skb, tx_start_bd, xmit_type); if (CHIP_IS_E2(bp)) { pbd_e2 = &fp->tx_desc_ring[bd_prod].parse_bd_e2; -- cgit v1.2.3-70-g09d2 From ca92429f5f52a76eb6e161622d813b8224ce0565 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:33:08 +0000 Subject: bnx2x: avoid release of unrequested irqs Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 3a2a50c36b4..9fee7f0a2d9 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1097,30 +1097,43 @@ void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value) } } -static void bnx2x_free_msix_irqs(struct bnx2x *bp) +/** + * bnx2x_free_msix_irqs - free previously requested MSI-X IRQ vectors + * + * @bp: driver handle + * @nvecs: number of vectors to be released + */ +static void bnx2x_free_msix_irqs(struct bnx2x *bp, int nvecs) { - int i, offset = 1; + int i, offset = 0; - free_irq(bp->msix_table[0].vector, bp->dev); + if (nvecs == offset) + return; + free_irq(bp->msix_table[offset].vector, bp->dev); DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", - bp->msix_table[0].vector); - + bp->msix_table[offset].vector); + offset++; #ifdef BCM_CNIC + if (nvecs == offset) + return; offset++; #endif + for_each_eth_queue(bp, i) { - DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " - "state %x\n", i, bp->msix_table[i + offset].vector, - bnx2x_fp(bp, i, state)); + if (nvecs == offset) + return; + DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d " + "irq\n", i, bp->msix_table[offset].vector); - free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]); + free_irq(bp->msix_table[offset++].vector, &bp->fp[i]); } } void bnx2x_free_irq(struct bnx2x *bp) { if (bp->flags & USING_MSIX_FLAG) - bnx2x_free_msix_irqs(bp); + bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) + + CNIC_CONTEXT_USE + 1); else if (bp->flags & USING_MSI_FLAG) free_irq(bp->pdev->irq, bp->dev); else @@ -1193,9 +1206,10 @@ int bnx2x_enable_msix(struct bnx2x *bp) static int bnx2x_req_msix_irqs(struct bnx2x *bp) { - int i, rc, offset = 1; + int i, rc, offset = 0; - rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0, + rc = request_irq(bp->msix_table[offset++].vector, + bnx2x_msix_sp_int, 0, bp->dev->name, bp->dev); if (rc) { BNX2X_ERR("request sp irq failed\n"); @@ -1213,8 +1227,9 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) rc = request_irq(bp->msix_table[offset].vector, bnx2x_msix_fp_int, 0, fp->name, fp); if (rc) { - BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc); - bnx2x_free_msix_irqs(bp); + BNX2X_ERR("request fp #%d irq (%d) failed rc %d\n", i, + bp->msix_table[offset].vector, rc); + bnx2x_free_msix_irqs(bp, offset); return -EBUSY; } -- cgit v1.2.3-70-g09d2 From 30ae438b120bc63caa2328733c7c7119d5d29842 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:33:13 +0000 Subject: bnx2x: disable fairness if ETS is enabled Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_dcb.h | 2 ++ drivers/net/bnx2x/bnx2x_main.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h index bed369d67e0..5bedd85e94d 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.h +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -60,6 +60,8 @@ struct bnx2x_dcbx_port_params { #define BNX2X_DCBX_OVERWRITE_SETTINGS_DISABLE 0 #define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE 1 #define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID (BNX2X_DCBX_CONFIG_INV_VALUE) +#define BNX2X_IS_ETS_ENABLED(bp) ((bp)->dcb_state == BNX2X_DCB_STATE_ON &&\ + (bp)->dcbx_port_params.ets.enabled) struct bnx2x_config_lldp_params { u32 overwrite_settings; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 637ff5ac244..bc516bbcd9f 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1892,8 +1892,12 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) bp->vn_weight_sum += vn_min_rate; } - /* ... only if all min rates are zeros - disable fairness */ - if (all_zero) { + /* if ETS or all min rates are zeros - disable fairness */ + if (BNX2X_IS_ETS_ENABLED(bp)) { + bp->cmng.flags.cmng_enables &= + ~CMNG_FLAGS_PER_PORT_FAIRNESS_VN; + DP(NETIF_MSG_IFUP, "Fairness will be disabled due to ETS\n"); + } else if (all_zero) { bp->cmng.flags.cmng_enables &= ~CMNG_FLAGS_PER_PORT_FAIRNESS_VN; DP(NETIF_MSG_IFUP, "All MIN values are zeroes" -- cgit v1.2.3-70-g09d2 From 361c391e2339eb8d479feec9042ec6e822593350 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:33:19 +0000 Subject: bnx2x: do not call link update without HW notification Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index bc516bbcd9f..2b4b376a69f 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2847,9 +2847,15 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) /* save nig interrupt mask */ nig_mask = REG_RD(bp, nig_int_mask_addr); - REG_WR(bp, nig_int_mask_addr, 0); - bnx2x_link_attn(bp); + /* If nig_mask is not set, no need to call the update + * function. + */ + if (nig_mask) { + REG_WR(bp, nig_int_mask_addr, 0); + + bnx2x_link_attn(bp); + } /* handle unicore attn? */ } -- cgit v1.2.3-70-g09d2 From 7a25cc7315e4d846cebbecd31bc4d79e7d2d6db3 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:33:25 +0000 Subject: bnx2x: dump FW memory when appropriate msglvl is raised Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.h | 2 ++ drivers/net/bnx2x/bnx2x_ethtool.c | 6 +++++- drivers/net/bnx2x/bnx2x_main.c | 23 ++++++++++++++++++----- drivers/net/bnx2x/bnx2x_reg.h | 1 + 4 files changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 19f8638ed51..ded8cf1e93f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -363,6 +363,8 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); */ void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value); +void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl); + /* dev_close main block */ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 2957353f7c2..9526a320eaf 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -704,8 +704,12 @@ static void bnx2x_set_msglevel(struct net_device *dev, u32 level) { struct bnx2x *bp = netdev_priv(dev); - if (capable(CAP_NET_ADMIN)) + if (capable(CAP_NET_ADMIN)) { + /* dump MCP trace */ + if (level & BNX2X_MSG_MCP) + bnx2x_fw_dump_lvl(bp, KERN_INFO); bp->msg_enable = level; + } } static int bnx2x_nway_reset(struct net_device *dev) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2b4b376a69f..3c06b140039 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -833,9 +833,9 @@ static int bnx2x_mc_assert(struct bnx2x *bp) return rc; } -static void bnx2x_fw_dump(struct bnx2x *bp) +void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl) { - u32 addr; + u32 addr, val; u32 mark, offset; __be32 data[9]; int word; @@ -844,6 +844,14 @@ static void bnx2x_fw_dump(struct bnx2x *bp) BNX2X_ERR("NO MCP - can not dump\n"); return; } + netdev_printk(lvl, bp->dev, "bc %d.%d.%d\n", + (bp->common.bc_ver & 0xff0000) >> 16, + (bp->common.bc_ver & 0xff00) >> 8, + (bp->common.bc_ver & 0xff)); + + val = REG_RD(bp, MCP_REG_MCPR_CPU_PROGRAM_COUNTER); + if (val == REG_RD(bp, MCP_REG_MCPR_CPU_PROGRAM_COUNTER)) + printk("%s" "MCP PC at 0x%x\n", lvl, val); if (BP_PATH(bp) == 0) trace_shmem_base = bp->common.shmem_base; @@ -853,9 +861,9 @@ static void bnx2x_fw_dump(struct bnx2x *bp) mark = REG_RD(bp, addr); mark = (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH) + ((mark + 0x3) & ~0x3) - 0x08000000; - pr_err("begin fw dump (mark 0x%x)\n", mark); + printk("%s" "begin fw dump (mark 0x%x)\n", lvl, mark); - pr_err(""); + printk("%s", lvl); for (offset = mark; offset <= trace_shmem_base; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, offset + 4*word)); @@ -868,7 +876,12 @@ static void bnx2x_fw_dump(struct bnx2x *bp) data[8] = 0x0; pr_cont("%s", (char *)data); } - pr_err("end of fw dump\n"); + printk("%s" "end of fw dump\n", lvl); +} + +static inline void bnx2x_fw_dump(struct bnx2x *bp) +{ + bnx2x_fw_dump_lvl(bp, KERN_ERR); } void bnx2x_panic_dump(struct bnx2x *bp) diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 949e8bd7318..18ac2ab08f3 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -933,6 +933,7 @@ * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */ #define IGU_REG_WRITE_DONE_PENDING 0x130480 #define MCP_A_REG_MCPR_SCRATCH 0x3a0000 +#define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c #define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 #define MCP_REG_MCPR_NVM_ADDR 0x8640c #define MCP_REG_MCPR_NVM_CFG4 0x8642c -- cgit v1.2.3-70-g09d2 From a9fccec79e359b9162ab0cebe2c7ce30ee4172c3 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:33:30 +0000 Subject: bnx2x: use bnx2x_reload_if_running Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.h | 3 +++ drivers/net/bnx2x/bnx2x_ethtool.c | 8 +------- 3 files changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 9fee7f0a2d9..ed1d695b177 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2810,7 +2810,7 @@ alloc_err: } -static int bnx2x_reload_if_running(struct net_device *dev) +int bnx2x_reload_if_running(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index ded8cf1e93f..57d9354da61 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -377,6 +377,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); /* select_queue callback */ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); +/* reload helper */ +int bnx2x_reload_if_running(struct net_device *dev); + int bnx2x_change_mac_addr(struct net_device *dev, void *p); /* NAPI poll Rx part */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 9526a320eaf..ddb99a9a803 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1238,7 +1238,6 @@ static int bnx2x_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct bnx2x *bp = netdev_priv(dev); - int rc = 0; if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); @@ -1255,12 +1254,7 @@ static int bnx2x_set_ringparam(struct net_device *dev, bp->rx_ring_size = ering->rx_pending; bp->tx_ring_size = ering->tx_pending; - if (netif_running(dev)) { - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - rc = bnx2x_nic_load(bp, LOAD_NORMAL); - } - - return rc; + return bnx2x_reload_if_running(dev); } static void bnx2x_get_pauseparam(struct net_device *dev, -- cgit v1.2.3-70-g09d2 From 9ee3d37b05c2fc5c6c01e09dd3bcc4500babf76a Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:33:34 +0000 Subject: bnx2x: removed unused variables Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 3 --- drivers/net/bnx2x/bnx2x_main.c | 15 ++++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 4b85489dc8e..3cf0768c890 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -928,8 +928,6 @@ struct bnx2x { bnx2x_recovery_state_t recovery_state; int is_leader; struct msix_entry *msix_table; -#define INT_MODE_INTx 1 -#define INT_MODE_MSI 2 int tx_ring_size; @@ -1092,7 +1090,6 @@ struct bnx2x { int multi_mode; int num_queues; int disable_tpa; - int int_mode; u32 *rx_indir_table; struct tstorm_eth_mac_filter_config mac_filters; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 3c06b140039..d7cab0dc57f 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -99,6 +99,8 @@ static int disable_tpa; module_param(disable_tpa, int, 0); MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); +#define INT_MODE_INTx 1 +#define INT_MODE_MSI 2 static int int_mode; module_param(int_mode, int, 0); MODULE_PARM_DESC(int_mode, " Force interrupt mode other then MSI-X " @@ -6606,11 +6608,10 @@ static int bnx2x_setup_fw_client(struct bnx2x *bp, * * In case of MSI-X it will also try to enable MSI-X. */ -static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) +static void __devinit bnx2x_set_int_mode(struct bnx2x *bp) { - int rc = 0; - switch (bp->int_mode) { + switch (int_mode) { case INT_MODE_MSI: bnx2x_enable_msi(bp); /* falling through... */ @@ -6629,8 +6630,7 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) * so try to enable MSI-X with the requested number of fp's * and fallback to MSI or legacy INTx with one fp */ - rc = bnx2x_enable_msix(bp); - if (rc) { + if (bnx2x_enable_msix(bp)) { /* failed to enable MSI-X */ if (bp->multi_mode) DP(NETIF_MSG_IFUP, @@ -6641,14 +6641,12 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) 1 + NONE_ETH_CONTEXT_USE); bp->num_queues = 1 + NONE_ETH_CONTEXT_USE; + /* Try to enable MSI */ if (!(bp->flags & DISABLE_MSI_FLAG)) bnx2x_enable_msi(bp); } - break; } - - return rc; } /* must be called prioir to any HW initializations */ @@ -8673,7 +8671,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) "must load devices in order!\n"); bp->multi_mode = multi_mode; - bp->int_mode = int_mode; /* Set TPA flags */ if (disable_tpa) { -- cgit v1.2.3-70-g09d2 From 042181f5aa8833a8918e1a91cfaf292146ffc62c Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 14 Jun 2011 01:33:39 +0000 Subject: bnx2x: Created bnx2x_sp Moved the HSI dependent slow path code to a separate file. Currently it contains the implementation of MACs, Rx mode, multicast addresses, indirection table, fast path queue and function configuration code. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/Makefile | 2 +- drivers/net/bnx2x/bnx2x.h | 6 +- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.h | 10 +- drivers/net/bnx2x/bnx2x_ethtool.c | 1 + drivers/net/bnx2x/bnx2x_main.c | 824 +------------------------------------- drivers/net/bnx2x/bnx2x_sp.c | 819 +++++++++++++++++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_sp.h | 43 ++ 8 files changed, 874 insertions(+), 833 deletions(-) create mode 100644 drivers/net/bnx2x/bnx2x_sp.c create mode 100644 drivers/net/bnx2x/bnx2x_sp.h (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile index bb83a296127..48fbdd48f88 100644 --- a/drivers/net/bnx2x/Makefile +++ b/drivers/net/bnx2x/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_BNX2X) += bnx2x.o -bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o +bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o bnx2x_sp.o diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 3cf0768c890..6d4d6d4e53c 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1482,10 +1482,11 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); /* Clears multicast and unicast list configuration in the chip. */ -void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp); -void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp); void bnx2x_invalidate_uc_list(struct bnx2x *bp); +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); + void bnx2x_update_coalesce(struct bnx2x *bp); int bnx2x_get_cur_phy_idx(struct bnx2x *bp); @@ -1825,6 +1826,5 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); -void bnx2x_push_indir_table(struct bnx2x *bp); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index ed1d695b177..c72e1df0472 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -24,8 +24,8 @@ #include #include #include "bnx2x_cmn.h" - #include "bnx2x_init.h" +#include "bnx2x_sp.h" static int bnx2x_setup_irqs(struct bnx2x *bp); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 57d9354da61..5a97f92b340 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -292,13 +292,6 @@ int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set); */ void bnx2x_set_rx_mode(struct net_device *dev); -/** - * bnx2x_set_storm_rx_mode - configure MAC filtering rules in a FW. - * - * @bp: driver handle - */ -void bnx2x_set_storm_rx_mode(struct bnx2x *bp); - /* Parity errors related */ void bnx2x_inc_load_cnt(struct bnx2x *bp); u32 bnx2x_dec_load_cnt(struct bnx2x *bp); @@ -1117,6 +1110,9 @@ static inline void storm_memset_cmng(struct bnx2x *bp, void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); +void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, + u8 sb_index, u8 disable, u16 usec); + /** * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration. * diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ddb99a9a803..7a133052660 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -25,6 +25,7 @@ #include "bnx2x_cmn.h" #include "bnx2x_dump.h" #include "bnx2x_init.h" +#include "bnx2x_sp.h" /* Note: in the format strings below %s is replaced by the queue-name which is * either its index or 'fcoe' for the fcoe queue. Make sure the format string diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index d7cab0dc57f..84f419fcde2 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -56,6 +56,7 @@ #include "bnx2x_init_ops.h" #include "bnx2x_cmn.h" #include "bnx2x_dcb.h" +#include "bnx2x_sp.h" #include #include "bnx2x_fw_file_hdr.h" @@ -162,186 +163,11 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); * General service functions ****************************************************************************/ -static inline void __storm_memset_dma_mapping(struct bnx2x *bp, - u32 addr, dma_addr_t mapping) -{ - REG_WR(bp, addr, U64_LO(mapping)); - REG_WR(bp, addr + 4, U64_HI(mapping)); -} - -static inline void __storm_memset_fill(struct bnx2x *bp, - u32 addr, size_t size, u32 val) -{ - int i; - for (i = 0; i < size/4; i++) - REG_WR(bp, addr + (i * 4), val); -} - -static inline void storm_memset_ustats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) -{ - size_t size = sizeof(struct ustorm_per_client_stats); - - u32 addr = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); - - __storm_memset_fill(bp, addr, size, 0); -} - -static inline void storm_memset_tstats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) -{ - size_t size = sizeof(struct tstorm_per_client_stats); - - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); - - __storm_memset_fill(bp, addr, size, 0); -} - -static inline void storm_memset_xstats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) -{ - size_t size = sizeof(struct xstorm_per_client_stats); - - u32 addr = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); - - __storm_memset_fill(bp, addr, size, 0); -} - - -static inline void storm_memset_spq_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = XSEM_REG_FAST_MEMORY + - XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - static inline void storm_memset_ov(struct bnx2x *bp, u16 ov, u16 abs_fid) { REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(abs_fid), ov); } -static inline void storm_memset_func_cfg(struct bnx2x *bp, - struct tstorm_eth_function_common_config *tcfg, - u16 abs_fid) -{ - size_t size = sizeof(struct tstorm_eth_function_common_config); - - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)tcfg); -} - -static inline void storm_memset_xstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_tstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_ustats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_cstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_xstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_tstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_ustats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_cstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_CSTRORM_INTMEM + - CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, - u16 pf_id) -{ - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); -} - -static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, - u8 enable) -{ - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), - enable); -} static inline void storm_memset_eq_data(struct bnx2x *bp, struct event_ring_data *eq_data, @@ -2239,143 +2065,6 @@ static u8 stat_counter_valid(struct bnx2x *bp, struct bnx2x_fastpath *fp) return true; } -/* must be called under rtnl_lock */ -static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) -{ - u32 mask = (1 << cl_id); - - /* initial seeting is BNX2X_ACCEPT_NONE */ - u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; - u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; - u8 unmatched_unicast = 0; - - if (filters & BNX2X_ACCEPT_UNMATCHED_UCAST) - unmatched_unicast = 1; - - if (filters & BNX2X_PROMISCUOUS_MODE) { - /* promiscious - accept all, drop none */ - drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; - accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; - if (IS_MF_SI(bp)) { - /* - * SI mode defines to accept in promiscuos mode - * only unmatched packets - */ - unmatched_unicast = 1; - accp_all_ucast = 0; - } - } - if (filters & BNX2X_ACCEPT_UNICAST) { - /* accept matched ucast */ - drop_all_ucast = 0; - } - if (filters & BNX2X_ACCEPT_MULTICAST) - /* accept matched mcast */ - drop_all_mcast = 0; - - if (filters & BNX2X_ACCEPT_ALL_UNICAST) { - /* accept all mcast */ - drop_all_ucast = 0; - accp_all_ucast = 1; - } - if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { - /* accept all mcast */ - drop_all_mcast = 0; - accp_all_mcast = 1; - } - if (filters & BNX2X_ACCEPT_BROADCAST) { - /* accept (all) bcast */ - drop_all_bcast = 0; - accp_all_bcast = 1; - } - - bp->mac_filters.ucast_drop_all = drop_all_ucast ? - bp->mac_filters.ucast_drop_all | mask : - bp->mac_filters.ucast_drop_all & ~mask; - - bp->mac_filters.mcast_drop_all = drop_all_mcast ? - bp->mac_filters.mcast_drop_all | mask : - bp->mac_filters.mcast_drop_all & ~mask; - - bp->mac_filters.bcast_drop_all = drop_all_bcast ? - bp->mac_filters.bcast_drop_all | mask : - bp->mac_filters.bcast_drop_all & ~mask; - - bp->mac_filters.ucast_accept_all = accp_all_ucast ? - bp->mac_filters.ucast_accept_all | mask : - bp->mac_filters.ucast_accept_all & ~mask; - - bp->mac_filters.mcast_accept_all = accp_all_mcast ? - bp->mac_filters.mcast_accept_all | mask : - bp->mac_filters.mcast_accept_all & ~mask; - - bp->mac_filters.bcast_accept_all = accp_all_bcast ? - bp->mac_filters.bcast_accept_all | mask : - bp->mac_filters.bcast_accept_all & ~mask; - - bp->mac_filters.unmatched_unicast = unmatched_unicast ? - bp->mac_filters.unmatched_unicast | mask : - bp->mac_filters.unmatched_unicast & ~mask; -} - -static void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) -{ - struct tstorm_eth_function_common_config tcfg = {0}; - u16 rss_flgs; - - /* tpa */ - if (p->func_flgs & FUNC_FLG_TPA) - tcfg.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - - /* set rss flags */ - rss_flgs = (p->rss->mode << - TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); - - if (p->rss->cap & RSS_IPV4_CAP) - rss_flgs |= RSS_IPV4_CAP_MASK; - if (p->rss->cap & RSS_IPV4_TCP_CAP) - rss_flgs |= RSS_IPV4_TCP_CAP_MASK; - if (p->rss->cap & RSS_IPV6_CAP) - rss_flgs |= RSS_IPV6_CAP_MASK; - if (p->rss->cap & RSS_IPV6_TCP_CAP) - rss_flgs |= RSS_IPV6_TCP_CAP_MASK; - - tcfg.config_flags |= rss_flgs; - tcfg.rss_result_mask = p->rss->result_mask; - - storm_memset_func_cfg(bp, &tcfg, p->func_id); - - /* Enable the function in the FW */ - storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); - storm_memset_func_en(bp, p->func_id, 1); - - /* statistics */ - if (p->func_flgs & FUNC_FLG_STATS) { - struct stats_indication_flags stats_flags = {0}; - stats_flags.collect_eth = 1; - - storm_memset_xstats_flags(bp, &stats_flags, p->func_id); - storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); - - storm_memset_tstats_flags(bp, &stats_flags, p->func_id); - storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); - - storm_memset_ustats_flags(bp, &stats_flags, p->func_id); - storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); - - storm_memset_cstats_flags(bp, &stats_flags, p->func_id); - storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); - } - - /* spq */ - if (p->func_flgs & FUNC_FLG_SPQ) { - storm_memset_spq_addr(bp, p->spq_map, p->func_id); - REG_WR(bp, XSEM_REG_FAST_MEMORY + - XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); - } -} - static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, struct bnx2x_fastpath *fp) { @@ -4068,7 +3757,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); } -static void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, +void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, u8 sb_index, u8 disable, u16 usec) { int port = BP_PORT(bp); @@ -4213,20 +3902,6 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp) min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1); } -void bnx2x_push_indir_table(struct bnx2x *bp) -{ - int func = BP_FUNC(bp); - int i; - - if (bp->multi_mode == ETH_RSS_MODE_DISABLED) - return; - - for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) - REG_WR8(bp, BAR_TSTRORM_INTMEM + - TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, - bp->fp->cl_id + bp->rx_indir_table[i]); -} - static void bnx2x_init_ind_table(struct bnx2x *bp) { int i; @@ -4237,104 +3912,6 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) bnx2x_push_indir_table(bp); } -void bnx2x_set_storm_rx_mode(struct bnx2x *bp) -{ - int mode = bp->rx_mode; - int port = BP_PORT(bp); - u16 cl_id; - u32 def_q_filters = 0; - - /* All but management unicast packets should pass to the host as well */ - u32 llh_mask = - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; - - switch (mode) { - case BNX2X_RX_MODE_NONE: /* no Rx */ - def_q_filters = BNX2X_ACCEPT_NONE; -#ifdef BCM_CNIC - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); - } -#endif - break; - - case BNX2X_RX_MODE_NORMAL: - def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_MULTICAST; -#ifdef BCM_CNIC - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST | - BNX2X_ACCEPT_MULTICAST); - } -#endif - break; - - case BNX2X_RX_MODE_ALLMULTI: - def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_ALL_MULTICAST; -#ifdef BCM_CNIC - /* - * Prevent duplication of multicast packets by configuring FCoE - * L2 Client to receive only matched unicast frames. - */ - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST); - } -#endif - break; - - case BNX2X_RX_MODE_PROMISC: - def_q_filters |= BNX2X_PROMISCUOUS_MODE; -#ifdef BCM_CNIC - /* - * Prevent packets duplication by configuring DROP_ALL for FCoE - * L2 Client. - */ - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); - } -#endif - /* pass management unicast packets as well */ - llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; - break; - - default: - BNX2X_ERR("BAD rx mode (%d)\n", mode); - break; - } - - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters); - - REG_WR(bp, - (port ? NIG_REG_LLH1_BRB1_DRV_MASK : - NIG_REG_LLH0_BRB1_DRV_MASK), llh_mask); - - DP(NETIF_MSG_IFUP, "rx mode %d\n" - "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" - "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n" - "unmatched_ucast 0x%x\n", mode, - bp->mac_filters.ucast_drop_all, - bp->mac_filters.mcast_drop_all, - bp->mac_filters.bcast_drop_all, - bp->mac_filters.ucast_accept_all, - bp->mac_filters.mcast_accept_all, - bp->mac_filters.bcast_accept_all, - bp->mac_filters.unmatched_unicast - ); - - storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); -} - static void bnx2x_init_internal_common(struct bnx2x *bp) { int i; @@ -5976,9 +5553,6 @@ alloc_mem_err: /* * Init service functions */ -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags); - int bnx2x_func_start(struct bnx2x *bp) { bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 0, 0, 1); @@ -5997,75 +5571,7 @@ static int bnx2x_func_stop(struct bnx2x *bp) 0, &(bp->state), WAIT_RAMROD_COMMON); } -/** - * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips - * - * @bp: driver handle - * @set: set or clear an entry (1 or 0) - * @mac: pointer to a buffer containing a MAC - * @cl_bit_vec: bit vector of clients to register a MAC for - * @cam_offset: offset in a CAM to use - * @is_bcast: is the set MAC a broadcast address (for E1 only) - */ -static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 is_bcast) -{ - struct mac_configuration_cmd *config = - (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); - int ramrod_flags = WAIT_RAMROD_COMMON; - - bp->set_mac_pending = 1; - - config->hdr.length = 1; - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - /* Mark the single MAC configuration ramrod as opposed to a - * UC/MC list configuration). - */ - config->hdr.echo = 1; - - /* primary MAC */ - config->config_table[0].msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].vlan_id = 0; - config->config_table[0].pf_id = BP_FUNC(bp); - if (set) - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_SET); - else - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); - - if (is_bcast) - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_BROADCAST, 1); - - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", - (set ? "setting" : "clearing"), - config->config_table[0].msb_mac_addr, - config->config_table[0].middle_mac_addr, - config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); - - mb(); - - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); - - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); -} - -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, int *state_p, int flags) { /* can take a while if any port is running */ @@ -6205,164 +5711,6 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set) } } -static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp) -{ - return CHIP_REV_IS_SLOW(bp) ? - (BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) : - (BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp))); -} - -/* set mc list, do not wait as wait implies sleep and - * set_rx_mode can be invoked from non-sleepable context. - * - * Instead we use the same ramrod data buffer each time we need - * to configure a list of addresses, and use the fact that the - * list of MACs is changed in an incremental way and that the - * function is called under the netif_addr_lock. A temporary - * inconsistent CAM configuration (possible in case of a very fast - * sequence of add/del/add on the host side) will shortly be - * restored by the handler of the last ramrod. - */ -static int bnx2x_set_e1_mc_list(struct bnx2x *bp) -{ - int i = 0, old; - struct net_device *dev = bp->dev; - u8 offset = bnx2x_e1_cam_mc_offset(bp); - struct netdev_hw_addr *ha; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); - - if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) - return -EINVAL; - - netdev_for_each_mc_addr(ha, dev) { - /* copy mac */ - config_cmd->config_table[i].msb_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); - config_cmd->config_table[i].middle_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); - config_cmd->config_table[i].lsb_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); - - config_cmd->config_table[i].vlan_id = 0; - config_cmd->config_table[i].pf_id = BP_FUNC(bp); - config_cmd->config_table[i].clients_bit_vector = - cpu_to_le32(1 << BP_L_ID(bp)); - - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_SET); - - DP(NETIF_MSG_IFUP, - "setting MCAST[%d] (%04x:%04x:%04x)\n", i, - config_cmd->config_table[i].msb_mac_addr, - config_cmd->config_table[i].middle_mac_addr, - config_cmd->config_table[i].lsb_mac_addr); - i++; - } - old = config_cmd->hdr.length; - if (old > i) { - for (; i < old; i++) { - if (CAM_IS_INVALID(config_cmd-> - config_table[i])) { - /* already invalidated */ - break; - } - /* invalidate */ - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); - } - } - - wmb(); - - config_cmd->hdr.length = i; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* Mark that this ramrod doesn't use bp->set_mac_pending for - * synchronization. - */ - config_cmd->hdr.echo = 0; - - mb(); - - return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); -} - -void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp) -{ - int i; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); - int ramrod_flags = WAIT_RAMROD_COMMON; - u8 offset = bnx2x_e1_cam_mc_offset(bp); - - for (i = 0; i < BNX2X_MAX_MULTICAST; i++) - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); - - wmb(); - - config_cmd->hdr.length = BNX2X_MAX_MULTICAST; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* We'll wait for a completion this time... */ - config_cmd->hdr.echo = 1; - - bp->set_mac_pending = 1; - - mb(); - - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); - - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, - ramrod_flags); - -} - -/* Accept one or more multicasts */ -static int bnx2x_set_e1h_mc_list(struct bnx2x *bp) -{ - struct net_device *dev = bp->dev; - struct netdev_hw_addr *ha; - u32 mc_filter[MC_HASH_SIZE]; - u32 crc, bit, regidx; - int i; - - memset(mc_filter, 0, 4 * MC_HASH_SIZE); - - netdev_for_each_mc_addr(ha, dev) { - DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", - bnx2x_mc_addr(ha)); - - crc = crc32c_le(0, bnx2x_mc_addr(ha), - ETH_ALEN); - bit = (crc >> 24) & 0xff; - regidx = bit >> 5; - bit &= 0x1f; - mc_filter[regidx] |= (1 << bit); - } - - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), - mc_filter[i]); - - return 0; -} - -void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp) -{ - int i; - - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); -} - #ifdef BCM_CNIC /** * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s). @@ -6434,172 +5782,6 @@ int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set) } #endif -static void bnx2x_fill_cl_init_data(struct bnx2x *bp, - struct bnx2x_client_init_params *params, - u8 activate, - struct client_init_ramrod_data *data) -{ - /* Clear the buffer */ - memset(data, 0, sizeof(*data)); - - /* general */ - data->general.client_id = params->rxq_params.cl_id; - data->general.statistics_counter_id = params->rxq_params.stat_id; - data->general.statistics_en_flg = - (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; - data->general.is_fcoe_flg = - (params->ramrod_params.flags & CLIENT_IS_FCOE) ? 1 : 0; - data->general.activate_flg = activate; - data->general.sp_client_id = params->rxq_params.spcl_id; - - /* Rx data */ - data->rx.tpa_en_flg = - (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; - data->rx.vmqueue_mode_en_flg = 0; - data->rx.cache_line_alignment_log_size = - params->rxq_params.cache_line_log; - data->rx.enable_dynamic_hc = - (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; - data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; - data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; - data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; - - /* We don't set drop flags */ - data->rx.drop_ip_cs_err_flg = 0; - data->rx.drop_tcp_cs_err_flg = 0; - data->rx.drop_ttl0_flg = 0; - data->rx.drop_udp_cs_err_flg = 0; - - data->rx.inner_vlan_removal_enable_flg = - (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; - data->rx.outer_vlan_removal_enable_flg = - (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; - data->rx.status_block_id = params->rxq_params.fw_sb_id; - data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; - data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); - data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); - data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); - data->rx.bd_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); - data->rx.bd_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); - data->rx.sge_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.sge_map)); - data->rx.sge_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.sge_map)); - data->rx.cqe_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); - data->rx.cqe_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); - data->rx.is_leading_rss = - (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; - data->rx.is_approx_mcast = data->rx.is_leading_rss; - - /* Tx data */ - data->tx.enforce_security_flg = 0; /* VF specific */ - data->tx.tx_status_block_id = params->txq_params.fw_sb_id; - data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; - data->tx.mtu = 0; /* VF specific */ - data->tx.tx_bd_page_base.lo = - cpu_to_le32(U64_LO(params->txq_params.dscr_map)); - data->tx.tx_bd_page_base.hi = - cpu_to_le32(U64_HI(params->txq_params.dscr_map)); - - /* flow control data */ - data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); - data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); - data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); - data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); - data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); - data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); - data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); - - data->fc.safc_group_num = params->txq_params.cos; - data->fc.safc_group_en_flg = - (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; - data->fc.traffic_type = - (params->ramrod_params.flags & CLIENT_IS_FCOE) ? - LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; -} - -static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) -{ - /* ustorm cxt validation */ - cxt->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); - /* xcontext validation */ - cxt->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); -} - -static int bnx2x_setup_fw_client(struct bnx2x *bp, - struct bnx2x_client_init_params *params, - u8 activate, - struct client_init_ramrod_data *data, - dma_addr_t data_mapping) -{ - u16 hc_usec; - int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; - int ramrod_flags = 0, rc; - - /* HC and context validation values */ - hc_usec = params->txq_params.hc_rate ? - 1000000 / params->txq_params.hc_rate : 0; - bnx2x_update_coalesce_sb_index(bp, - params->txq_params.fw_sb_id, - params->txq_params.sb_cq_index, - !(params->txq_params.flags & QUEUE_FLG_HC), - hc_usec); - - *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; - - hc_usec = params->rxq_params.hc_rate ? - 1000000 / params->rxq_params.hc_rate : 0; - bnx2x_update_coalesce_sb_index(bp, - params->rxq_params.fw_sb_id, - params->rxq_params.sb_cq_index, - !(params->rxq_params.flags & QUEUE_FLG_HC), - hc_usec); - - bnx2x_set_ctx_validation(params->rxq_params.cxt, - params->rxq_params.cid); - - /* zero stats */ - if (params->txq_params.flags & QUEUE_FLG_STATS) - storm_memset_xstats_zero(bp, BP_PORT(bp), - params->txq_params.stat_id); - - if (params->rxq_params.flags & QUEUE_FLG_STATS) { - storm_memset_ustats_zero(bp, BP_PORT(bp), - params->rxq_params.stat_id); - storm_memset_tstats_zero(bp, BP_PORT(bp), - params->rxq_params.stat_id); - } - - /* Fill the ramrod data */ - bnx2x_fill_cl_init_data(bp, params, activate, data); - - /* SETUP ramrod. - * - * bnx2x_sp_post() takes a spin_lock thus no other explict memory - * barrier except from mmiowb() is needed to impose a - * proper ordering of memory operations. - */ - mmiowb(); - - - bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, - U64_HI(data_mapping), U64_LO(data_mapping), 0); - - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, - params->ramrod_params.index, - params->ramrod_params.pstate, - ramrod_flags); - return rc; -} /** * bnx2x_set_int_mode - configure interrupt mode diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c new file mode 100644 index 00000000000..7c876a06b77 --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -0,0 +1,819 @@ +#include +#include +#include +#include +#include +#include +#include "bnx2x.h" +#include "bnx2x_cmn.h" +#include "bnx2x_sp.h" + + +/** + * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips + * + * @bp: driver handle + * @set: set or clear an entry (1 or 0) + * @mac: pointer to a buffer containing a MAC + * @cl_bit_vec: bit vector of clients to register a MAC for + * @cam_offset: offset in a CAM to use + * @is_bcast: is the set MAC a broadcast address (for E1 only) + */ +void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast) +{ + struct mac_configuration_cmd *config = + (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; + + config->hdr.length = 1; + config->hdr.offset = cam_offset; + config->hdr.client_id = 0xff; + /* Mark the single MAC configuration ramrod as opposed to a + * UC/MC list configuration). + */ + config->hdr.echo = 1; + + /* primary MAC */ + config->config_table[0].msb_mac_addr = + swab16(*(u16 *)&mac[0]); + config->config_table[0].middle_mac_addr = + swab16(*(u16 *)&mac[2]); + config->config_table[0].lsb_mac_addr = + swab16(*(u16 *)&mac[4]); + config->config_table[0].clients_bit_vector = + cpu_to_le32(cl_bit_vec); + config->config_table[0].vlan_id = 0; + config->config_table[0].pf_id = BP_FUNC(bp); + if (set) + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + else + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + if (is_bcast) + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_BROADCAST, 1); + + DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", + (set ? "setting" : "clearing"), + config->config_table[0].msb_mac_addr, + config->config_table[0].middle_mac_addr, + config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); + + mb(); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(bnx2x_sp_mapping(bp, mac_config)), + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); +} + + +static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp) +{ + return CHIP_REV_IS_SLOW(bp) ? + (BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) : + (BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp))); +} + +/* set mc list, do not wait as wait implies sleep and + * set_rx_mode can be invoked from non-sleepable context. + * + * Instead we use the same ramrod data buffer each time we need + * to configure a list of addresses, and use the fact that the + * list of MACs is changed in an incremental way and that the + * function is called under the netif_addr_lock. A temporary + * inconsistent CAM configuration (possible in case of a very fast + * sequence of add/del/add on the host side) will shortly be + * restored by the handler of the last ramrod. + */ +int bnx2x_set_e1_mc_list(struct bnx2x *bp) +{ + int i = 0, old; + struct net_device *dev = bp->dev; + u8 offset = bnx2x_e1_cam_mc_offset(bp); + struct netdev_hw_addr *ha; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + + if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) + return -EINVAL; + + netdev_for_each_mc_addr(ha, dev) { + /* copy mac */ + config_cmd->config_table[i].msb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); + config_cmd->config_table[i].middle_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); + config_cmd->config_table[i].lsb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); + + config_cmd->config_table[i].vlan_id = 0; + config_cmd->config_table[i].pf_id = BP_FUNC(bp); + config_cmd->config_table[i].clients_bit_vector = + cpu_to_le32(1 << BP_L_ID(bp)); + + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + + DP(NETIF_MSG_IFUP, + "setting MCAST[%d] (%04x:%04x:%04x)\n", i, + config_cmd->config_table[i].msb_mac_addr, + config_cmd->config_table[i].middle_mac_addr, + config_cmd->config_table[i].lsb_mac_addr); + i++; + } + old = config_cmd->hdr.length; + if (old > i) { + for (; i < old; i++) { + if (CAM_IS_INVALID(config_cmd-> + config_table[i])) { + /* already invalidated */ + break; + } + /* invalidate */ + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + } + } + + wmb(); + + config_cmd->hdr.length = i; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + /* Mark that this ramrod doesn't use bp->set_mac_pending for + * synchronization. + */ + config_cmd->hdr.echo = 0; + + mb(); + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); +} + +void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp) +{ + int i; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + u8 offset = bnx2x_e1_cam_mc_offset(bp); + + for (i = 0; i < BNX2X_MAX_MULTICAST; i++) + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + wmb(); + + config_cmd->hdr.length = BNX2X_MAX_MULTICAST; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + /* We'll wait for a completion this time... */ + config_cmd->hdr.echo = 1; + + bp->set_mac_pending = 1; + + mb(); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, + ramrod_flags); + +} + +/* Accept one or more multicasts */ +int bnx2x_set_e1h_mc_list(struct bnx2x *bp) +{ + struct net_device *dev = bp->dev; + struct netdev_hw_addr *ha; + u32 mc_filter[MC_HASH_SIZE]; + u32 crc, bit, regidx; + int i; + + memset(mc_filter, 0, 4 * MC_HASH_SIZE); + + netdev_for_each_mc_addr(ha, dev) { + DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", + bnx2x_mc_addr(ha)); + + crc = crc32c_le(0, bnx2x_mc_addr(ha), + ETH_ALEN); + bit = (crc >> 24) & 0xff; + regidx = bit >> 5; + bit &= 0x1f; + mc_filter[regidx] |= (1 << bit); + } + + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), + mc_filter[i]); + + return 0; +} + +void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp) +{ + int i; + + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); +} + +/* must be called under rtnl_lock */ +void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) +{ + u32 mask = (1 << cl_id); + + /* initial seeting is BNX2X_ACCEPT_NONE */ + u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; + u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; + u8 unmatched_unicast = 0; + + if (filters & BNX2X_ACCEPT_UNMATCHED_UCAST) + unmatched_unicast = 1; + + if (filters & BNX2X_PROMISCUOUS_MODE) { + /* promiscious - accept all, drop none */ + drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; + accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; + if (IS_MF_SI(bp)) { + /* + * SI mode defines to accept in promiscuos mode + * only unmatched packets + */ + unmatched_unicast = 1; + accp_all_ucast = 0; + } + } + if (filters & BNX2X_ACCEPT_UNICAST) { + /* accept matched ucast */ + drop_all_ucast = 0; + } + if (filters & BNX2X_ACCEPT_MULTICAST) + /* accept matched mcast */ + drop_all_mcast = 0; + + if (filters & BNX2X_ACCEPT_ALL_UNICAST) { + /* accept all mcast */ + drop_all_ucast = 0; + accp_all_ucast = 1; + } + if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { + /* accept all mcast */ + drop_all_mcast = 0; + accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_BROADCAST) { + /* accept (all) bcast */ + drop_all_bcast = 0; + accp_all_bcast = 1; + } + + bp->mac_filters.ucast_drop_all = drop_all_ucast ? + bp->mac_filters.ucast_drop_all | mask : + bp->mac_filters.ucast_drop_all & ~mask; + + bp->mac_filters.mcast_drop_all = drop_all_mcast ? + bp->mac_filters.mcast_drop_all | mask : + bp->mac_filters.mcast_drop_all & ~mask; + + bp->mac_filters.bcast_drop_all = drop_all_bcast ? + bp->mac_filters.bcast_drop_all | mask : + bp->mac_filters.bcast_drop_all & ~mask; + + bp->mac_filters.ucast_accept_all = accp_all_ucast ? + bp->mac_filters.ucast_accept_all | mask : + bp->mac_filters.ucast_accept_all & ~mask; + + bp->mac_filters.mcast_accept_all = accp_all_mcast ? + bp->mac_filters.mcast_accept_all | mask : + bp->mac_filters.mcast_accept_all & ~mask; + + bp->mac_filters.bcast_accept_all = accp_all_bcast ? + bp->mac_filters.bcast_accept_all | mask : + bp->mac_filters.bcast_accept_all & ~mask; + + bp->mac_filters.unmatched_unicast = unmatched_unicast ? + bp->mac_filters.unmatched_unicast | mask : + bp->mac_filters.unmatched_unicast & ~mask; +} + +void bnx2x_set_storm_rx_mode(struct bnx2x *bp) +{ + int mode = bp->rx_mode; + int port = BP_PORT(bp); + u16 cl_id; + u32 def_q_filters = 0; + + /* All but management unicast packets should pass to the host as well */ + u32 llh_mask = + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; + + switch (mode) { + case BNX2X_RX_MODE_NONE: /* no Rx */ + def_q_filters = BNX2X_ACCEPT_NONE; +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); + } +#endif + break; + + case BNX2X_RX_MODE_NORMAL: + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_MULTICAST; +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_MULTICAST); + } +#endif + break; + + case BNX2X_RX_MODE_ALLMULTI: + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST; +#ifdef BCM_CNIC + /* + * Prevent duplication of multicast packets by configuring FCoE + * L2 Client to receive only matched unicast frames. + */ + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST); + } +#endif + break; + + case BNX2X_RX_MODE_PROMISC: + def_q_filters |= BNX2X_PROMISCUOUS_MODE; +#ifdef BCM_CNIC + /* + * Prevent packets duplication by configuring DROP_ALL for FCoE + * L2 Client. + */ + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); + } +#endif + /* pass management unicast packets as well */ + llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; + break; + + default: + BNX2X_ERR("BAD rx mode (%d)\n", mode); + break; + } + + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters); + + REG_WR(bp, + (port ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK), llh_mask); + + DP(NETIF_MSG_IFUP, "rx mode %d\n" + "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" + "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n" + "unmatched_ucast 0x%x\n", mode, + bp->mac_filters.ucast_drop_all, + bp->mac_filters.mcast_drop_all, + bp->mac_filters.bcast_drop_all, + bp->mac_filters.ucast_accept_all, + bp->mac_filters.mcast_accept_all, + bp->mac_filters.bcast_accept_all, + bp->mac_filters.unmatched_unicast + ); + + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); +} + +/* RSS configuration */ +static inline void __storm_memset_dma_mapping(struct bnx2x *bp, + u32 addr, dma_addr_t mapping) +{ + REG_WR(bp, addr, U64_LO(mapping)); + REG_WR(bp, addr + 4, U64_HI(mapping)); +} + +static inline void __storm_fill(struct bnx2x *bp, + u32 addr, size_t size, u32 val) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), val); +} + +static inline void storm_memset_ustats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct ustorm_per_client_stats); + + u32 addr = BAR_USTRORM_INTMEM + + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_fill(bp, addr, size, 0); +} + +static inline void storm_memset_tstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct tstorm_per_client_stats); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_fill(bp, addr, size, 0); +} + +static inline void storm_memset_xstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct xstorm_per_client_stats); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_fill(bp, addr, size, 0); +} + + +static inline void storm_memset_spq_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_xstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_tstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_ustats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_cstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_xstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_tstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ustats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_USTRORM_INTMEM + + USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_cstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, + u16 pf_id) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); +} + +static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, + u8 enable) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), + enable); +} + +static inline void storm_memset_func_cfg(struct bnx2x *bp, + struct tstorm_eth_function_common_config *tcfg, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_function_common_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)tcfg); +} + +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) +{ + struct tstorm_eth_function_common_config tcfg = {0}; + u16 rss_flgs; + + /* tpa */ + if (p->func_flgs & FUNC_FLG_TPA) + tcfg.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; + + /* set rss flags */ + rss_flgs = (p->rss->mode << + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); + + if (p->rss->cap & RSS_IPV4_CAP) + rss_flgs |= RSS_IPV4_CAP_MASK; + if (p->rss->cap & RSS_IPV4_TCP_CAP) + rss_flgs |= RSS_IPV4_TCP_CAP_MASK; + if (p->rss->cap & RSS_IPV6_CAP) + rss_flgs |= RSS_IPV6_CAP_MASK; + if (p->rss->cap & RSS_IPV6_TCP_CAP) + rss_flgs |= RSS_IPV6_TCP_CAP_MASK; + + tcfg.config_flags |= rss_flgs; + tcfg.rss_result_mask = p->rss->result_mask; + + storm_memset_func_cfg(bp, &tcfg, p->func_id); + + /* Enable the function in the FW */ + storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); + storm_memset_func_en(bp, p->func_id, 1); + + /* statistics */ + if (p->func_flgs & FUNC_FLG_STATS) { + struct stats_indication_flags stats_flags = {0}; + stats_flags.collect_eth = 1; + + storm_memset_xstats_flags(bp, &stats_flags, p->func_id); + storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_tstats_flags(bp, &stats_flags, p->func_id); + storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_ustats_flags(bp, &stats_flags, p->func_id); + storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_cstats_flags(bp, &stats_flags, p->func_id); + storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); + } + + /* spq */ + if (p->func_flgs & FUNC_FLG_SPQ) { + storm_memset_spq_addr(bp, p->spq_map, p->func_id); + REG_WR(bp, XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); + } +} + +static void bnx2x_fill_cl_init_data(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data) +{ + /* Clear the buffer */ + memset(data, 0, sizeof(*data)); + + /* general */ + data->general.client_id = params->rxq_params.cl_id; + data->general.statistics_counter_id = params->rxq_params.stat_id; + data->general.statistics_en_flg = + (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; + data->general.is_fcoe_flg = + (params->ramrod_params.flags & CLIENT_IS_FCOE) ? 1 : 0; + data->general.activate_flg = activate; + data->general.sp_client_id = params->rxq_params.spcl_id; + + /* Rx data */ + data->rx.tpa_en_flg = + (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; + data->rx.vmqueue_mode_en_flg = 0; + data->rx.cache_line_alignment_log_size = + params->rxq_params.cache_line_log; + data->rx.enable_dynamic_hc = + (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; + data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; + data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; + data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; + + /* We don't set drop flags */ + data->rx.drop_ip_cs_err_flg = 0; + data->rx.drop_tcp_cs_err_flg = 0; + data->rx.drop_ttl0_flg = 0; + data->rx.drop_udp_cs_err_flg = 0; + + data->rx.inner_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; + data->rx.outer_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; + data->rx.status_block_id = params->rxq_params.fw_sb_id; + data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; + data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); + data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); + data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); + data->rx.bd_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); + data->rx.bd_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); + data->rx.sge_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.sge_map)); + data->rx.sge_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.sge_map)); + data->rx.cqe_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); + data->rx.cqe_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); + data->rx.is_leading_rss = + (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; + data->rx.is_approx_mcast = data->rx.is_leading_rss; + + /* Tx data */ + data->tx.enforce_security_flg = 0; /* VF specific */ + data->tx.tx_status_block_id = params->txq_params.fw_sb_id; + data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; + data->tx.mtu = 0; /* VF specific */ + data->tx.tx_bd_page_base.lo = + cpu_to_le32(U64_LO(params->txq_params.dscr_map)); + data->tx.tx_bd_page_base.hi = + cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + + /* flow control data */ + data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); + data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); + data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); + data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); + data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); + data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); + data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); + + data->fc.safc_group_num = params->txq_params.cos; + data->fc.safc_group_en_flg = + (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; + data->fc.traffic_type = + (params->ramrod_params.flags & CLIENT_IS_FCOE) ? + LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; +} + + +int bnx2x_setup_fw_client(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data, + dma_addr_t data_mapping) +{ + u16 hc_usec; + int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; + int ramrod_flags = 0, rc; + + /* HC and context validation values */ + hc_usec = params->txq_params.hc_rate ? + 1000000 / params->txq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->txq_params.fw_sb_id, + params->txq_params.sb_cq_index, + !(params->txq_params.flags & QUEUE_FLG_HC), + hc_usec); + + *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; + + hc_usec = params->rxq_params.hc_rate ? + 1000000 / params->rxq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->rxq_params.fw_sb_id, + params->rxq_params.sb_cq_index, + !(params->rxq_params.flags & QUEUE_FLG_HC), + hc_usec); + + bnx2x_set_ctx_validation(params->rxq_params.cxt, + params->rxq_params.cid); + + /* zero stats */ + if (params->txq_params.flags & QUEUE_FLG_STATS) + storm_memset_xstats_zero(bp, BP_PORT(bp), + params->txq_params.stat_id); + + if (params->rxq_params.flags & QUEUE_FLG_STATS) { + storm_memset_ustats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + storm_memset_tstats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + } + + /* Fill the ramrod data */ + bnx2x_fill_cl_init_data(bp, params, activate, data); + + /* SETUP ramrod. + * + * bnx2x_sp_post() takes a spin_lock thus no other explict memory + * barrier except from mmiowb() is needed to impose a + * proper ordering of memory operations. + */ + mmiowb(); + + + bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, + U64_HI(data_mapping), U64_LO(data_mapping), 0); + + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, + params->ramrod_params.index, + params->ramrod_params.pstate, + ramrod_flags); + return rc; +} + +void bnx2x_push_indir_table(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + int i; + + if (bp->multi_mode == ETH_RSS_MODE_DISABLED) + return; + + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) + REG_WR8(bp, BAR_TSTRORM_INTMEM + + TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, + bp->fp->cl_id + bp->rx_indir_table[i]); +} diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h new file mode 100644 index 00000000000..f9b755e4a10 --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_sp.h @@ -0,0 +1,43 @@ +#ifndef BNX2X_SP +#define BNX2X_SP + +#include "bnx2x_reg.h" + +/* MAC configuration */ +void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast); + +/* Multicast */ +void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp); +void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp); +int bnx2x_set_e1_mc_list(struct bnx2x *bp); +int bnx2x_set_e1h_mc_list(struct bnx2x *bp); + +/* Rx mode */ +void bnx2x_set_storm_rx_mode(struct bnx2x *bp); +void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters); + +/* RSS configuration */ +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p); +void bnx2x_push_indir_table(struct bnx2x *bp); + +/* Queue configuration */ +static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) +{ + /* ustorm cxt validation */ + cxt->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, + ETH_CONNECTION_TYPE); + /* xcontext validation */ + cxt->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, + ETH_CONNECTION_TYPE); +} + +int bnx2x_setup_fw_client(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data, + dma_addr_t data_mapping); +#endif /* BNX2X_SP */ -- cgit v1.2.3-70-g09d2 From 619c5cb6885b936c44ae1422ef805b69c6291485 Mon Sep 17 00:00:00 2001 From: Vlad Zolotarov Date: Tue, 14 Jun 2011 14:33:44 +0300 Subject: New 7.0 FW: bnx2x, cnic, bnx2i, bnx2fc New FW/HSI (7.0): - Added support to 578xx chips - Improved HSI - much less driver's direct access to the FW internal memory needed. New implementation of the HSI handling layer in the bnx2x (bnx2x_sp.c): - Introduced chip dependent objects that have chip independent interfaces for configuration of MACs, multicast addresses, Rx mode, indirection table, fast path queues and function initialization/cleanup. - Objects functionality is based on the private function pointers, which allows not only a per-chip but also PF/VF differentiation while still preserving the same interface towards the driver. - Objects interface is not influenced by the HSI changes which do not require providing new parameters keeping the code outside the bnx2x_sp.c invariant with regard to such HSI chnages. Changes in a CNIC, bnx2fc and bnx2i modules due to the new HSI. Signed-off-by: Vladislav Zolotarov Signed-off-by: Michael Chan Signed-off-by: Bhanu Prakash Gollapudi Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 870 +++-- drivers/net/bnx2x/bnx2x_cmn.c | 870 +++-- drivers/net/bnx2x/bnx2x_cmn.h | 549 ++- drivers/net/bnx2x/bnx2x_dcb.c | 179 +- drivers/net/bnx2x/bnx2x_dcb.h | 3 - drivers/net/bnx2x/bnx2x_dump.h | 913 +++-- drivers/net/bnx2x/bnx2x_ethtool.c | 392 +- drivers/net/bnx2x/bnx2x_fw_defs.h | 519 +-- drivers/net/bnx2x/bnx2x_hsi.h | 5495 +++++++++++++++++---------- drivers/net/bnx2x/bnx2x_init.h | 316 +- drivers/net/bnx2x/bnx2x_init_ops.h | 194 +- drivers/net/bnx2x/bnx2x_link.c | 106 +- drivers/net/bnx2x/bnx2x_link.h | 21 +- drivers/net/bnx2x/bnx2x_main.c | 3729 +++++++++++------- drivers/net/bnx2x/bnx2x_reg.h | 194 +- drivers/net/bnx2x/bnx2x_sp.c | 5748 +++++++++++++++++++++++++--- drivers/net/bnx2x/bnx2x_sp.h | 1278 ++++++- drivers/net/bnx2x/bnx2x_stats.c | 868 +++-- drivers/net/bnx2x/bnx2x_stats.h | 228 +- drivers/net/cnic.c | 164 +- drivers/net/cnic.h | 35 +- drivers/net/cnic_defs.h | 6488 ++++++++++++++++++-------------- drivers/net/cnic_if.h | 8 +- drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h | 1162 +++--- drivers/scsi/bnx2fc/bnx2fc.h | 10 +- drivers/scsi/bnx2fc/bnx2fc_constants.h | 139 +- drivers/scsi/bnx2fc/bnx2fc_els.c | 7 +- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 4 +- drivers/scsi/bnx2fc/bnx2fc_hwi.c | 442 ++- drivers/scsi/bnx2fc/bnx2fc_io.c | 23 +- drivers/scsi/bnx2fc/bnx2fc_tgt.c | 24 +- drivers/scsi/bnx2i/57xx_iscsi_hsi.h | 12 +- 32 files changed, 20778 insertions(+), 10212 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 6d4d6d4e53c..b4b3abe9e7c 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -47,11 +47,12 @@ #endif #include -#include + #include "bnx2x_reg.h" #include "bnx2x_fw_defs.h" #include "bnx2x_hsi.h" #include "bnx2x_link.h" +#include "bnx2x_sp.h" #include "bnx2x_dcb.h" #include "bnx2x_stats.h" @@ -80,6 +81,12 @@ do { \ ##__args); \ } while (0) +#define DP_CONT(__mask, __fmt, __args...) \ +do { \ + if (bp->msg_enable & (__mask)) \ + pr_cont(__fmt, ##__args); \ +} while (0) + /* errors debug print */ #define BNX2X_DBG_ERR(__fmt, __args...) \ do { \ @@ -111,7 +118,9 @@ do { \ dev_info(&bp->pdev->dev, __fmt, ##__args); \ } while (0) -void bnx2x_panic_dump(struct bnx2x *bp); +#define BNX2X_MAC_FMT "%pM" +#define BNX2X_MAC_PRN_LIST(mac) (mac) + #ifdef BNX2X_STOP_ON_ERROR #define bnx2x_panic() do { \ @@ -233,11 +242,11 @@ void bnx2x_panic_dump(struct bnx2x *bp); * */ /* iSCSI L2 */ -#define BNX2X_ISCSI_ETH_CL_ID 17 +#define BNX2X_ISCSI_ETH_CL_ID_IDX 1 #define BNX2X_ISCSI_ETH_CID 17 /* FCoE L2 */ -#define BNX2X_FCOE_ETH_CL_ID 18 +#define BNX2X_FCOE_ETH_CL_ID_IDX 2 #define BNX2X_FCOE_ETH_CID 18 /** Additional rings budgeting */ @@ -283,44 +292,73 @@ union db_prod { /* MC hsi */ -#define BCM_PAGE_SHIFT 12 -#define BCM_PAGE_SIZE (1 << BCM_PAGE_SHIFT) -#define BCM_PAGE_MASK (~(BCM_PAGE_SIZE - 1)) +#define BCM_PAGE_SHIFT 12 +#define BCM_PAGE_SIZE (1 << BCM_PAGE_SHIFT) +#define BCM_PAGE_MASK (~(BCM_PAGE_SIZE - 1)) #define BCM_PAGE_ALIGN(addr) (((addr) + BCM_PAGE_SIZE - 1) & BCM_PAGE_MASK) -#define PAGES_PER_SGE_SHIFT 0 -#define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT) -#define SGE_PAGE_SIZE PAGE_SIZE -#define SGE_PAGE_SHIFT PAGE_SHIFT -#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))(addr)) +#define PAGES_PER_SGE_SHIFT 0 +#define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT) +#define SGE_PAGE_SIZE PAGE_SIZE +#define SGE_PAGE_SHIFT PAGE_SHIFT +#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))(addr)) /* SGE ring related macros */ -#define NUM_RX_SGE_PAGES 2 +#define NUM_RX_SGE_PAGES 2 #define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge)) -#define MAX_RX_SGE_CNT (RX_SGE_CNT - 2) +#define MAX_RX_SGE_CNT (RX_SGE_CNT - 2) /* RX_SGE_CNT is promised to be a power of 2 */ -#define RX_SGE_MASK (RX_SGE_CNT - 1) -#define NUM_RX_SGE (RX_SGE_CNT * NUM_RX_SGE_PAGES) -#define MAX_RX_SGE (NUM_RX_SGE - 1) +#define RX_SGE_MASK (RX_SGE_CNT - 1) +#define NUM_RX_SGE (RX_SGE_CNT * NUM_RX_SGE_PAGES) +#define MAX_RX_SGE (NUM_RX_SGE - 1) #define NEXT_SGE_IDX(x) ((((x) & RX_SGE_MASK) == \ (MAX_RX_SGE_CNT - 1)) ? (x) + 3 : (x) + 1) -#define RX_SGE(x) ((x) & MAX_RX_SGE) +#define RX_SGE(x) ((x) & MAX_RX_SGE) + +/* Manipulate a bit vector defined as an array of u64 */ -/* SGE producer mask related macros */ /* Number of bits in one sge_mask array element */ -#define RX_SGE_MASK_ELEM_SZ 64 -#define RX_SGE_MASK_ELEM_SHIFT 6 -#define RX_SGE_MASK_ELEM_MASK ((u64)RX_SGE_MASK_ELEM_SZ - 1) +#define BIT_VEC64_ELEM_SZ 64 +#define BIT_VEC64_ELEM_SHIFT 6 +#define BIT_VEC64_ELEM_MASK ((u64)BIT_VEC64_ELEM_SZ - 1) + + +#define __BIT_VEC64_SET_BIT(el, bit) \ + do { \ + el = ((el) | ((u64)0x1 << (bit))); \ + } while (0) + +#define __BIT_VEC64_CLEAR_BIT(el, bit) \ + do { \ + el = ((el) & (~((u64)0x1 << (bit)))); \ + } while (0) + + +#define BIT_VEC64_SET_BIT(vec64, idx) \ + __BIT_VEC64_SET_BIT((vec64)[(idx) >> BIT_VEC64_ELEM_SHIFT], \ + (idx) & BIT_VEC64_ELEM_MASK) + +#define BIT_VEC64_CLEAR_BIT(vec64, idx) \ + __BIT_VEC64_CLEAR_BIT((vec64)[(idx) >> BIT_VEC64_ELEM_SHIFT], \ + (idx) & BIT_VEC64_ELEM_MASK) + +#define BIT_VEC64_TEST_BIT(vec64, idx) \ + (((vec64)[(idx) >> BIT_VEC64_ELEM_SHIFT] >> \ + ((idx) & BIT_VEC64_ELEM_MASK)) & 0x1) /* Creates a bitmask of all ones in less significant bits. idx - index of the most significant bit in the created mask */ -#define RX_SGE_ONES_MASK(idx) \ - (((u64)0x1 << (((idx) & RX_SGE_MASK_ELEM_MASK) + 1)) - 1) -#define RX_SGE_MASK_ELEM_ONE_MASK ((u64)(~0)) +#define BIT_VEC64_ONES_MASK(idx) \ + (((u64)0x1 << (((idx) & BIT_VEC64_ELEM_MASK) + 1)) - 1) +#define BIT_VEC64_ELEM_ONE_MASK ((u64)(~0)) + +/*******************************************************/ + + /* Number of u64 elements in SGE mask array */ #define RX_SGE_MASK_LEN ((NUM_RX_SGE_PAGES * RX_SGE_CNT) / \ - RX_SGE_MASK_ELEM_SZ) + BIT_VEC64_ELEM_SZ) #define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1) #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) @@ -331,7 +369,30 @@ union host_hc_status_block { struct host_hc_status_block_e2 *e2_sb; }; +struct bnx2x_agg_info { + /* + * First aggregation buffer is an skb, the following - are pages. + * We will preallocate the skbs for each aggregation when + * we open the interface and will replace the BD at the consumer + * with this one when we receive the TPA_START CQE in order to + * keep the Rx BD ring consistent. + */ + struct sw_rx_bd first_buf; + u8 tpa_state; +#define BNX2X_TPA_START 1 +#define BNX2X_TPA_STOP 2 +#define BNX2X_TPA_ERROR 3 + u8 placement_offset; + u16 parsing_flags; + u16 vlan_tag; + u16 len_on_bd; +}; + +#define Q_STATS_OFFSET32(stat_name) \ + (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) + struct bnx2x_fastpath { + struct bnx2x *bp; /* parent */ #define BNX2X_NAPI_WEIGHT 128 struct napi_struct napi; @@ -366,23 +427,13 @@ struct bnx2x_fastpath { u64 sge_mask[RX_SGE_MASK_LEN]; - int state; -#define BNX2X_FP_STATE_CLOSED 0 -#define BNX2X_FP_STATE_IRQ 0x80000 -#define BNX2X_FP_STATE_OPENING 0x90000 -#define BNX2X_FP_STATE_OPEN 0xa0000 -#define BNX2X_FP_STATE_HALTING 0xb0000 -#define BNX2X_FP_STATE_HALTED 0xc0000 -#define BNX2X_FP_STATE_TERMINATING 0xd0000 -#define BNX2X_FP_STATE_TERMINATED 0xe0000 + u32 cid; u8 index; /* number in fp array */ u8 cl_id; /* eth client id */ u8 cl_qzone_id; u8 fw_sb_id; /* status block number in FW */ u8 igu_sb_id; /* status block number in HW */ - u32 cid; - union db_prod tx_db; u16 tx_pkt_prod; @@ -401,24 +452,20 @@ struct bnx2x_fastpath { /* The last maximal completed SGE */ u16 last_max_sge; __le16 *rx_cons_sb; - unsigned long tx_pkt, rx_pkt, rx_calls; /* TPA related */ - struct sw_rx_bd tpa_pool[ETH_MAX_AGGREGATION_QUEUES_E1H]; - u8 tpa_state[ETH_MAX_AGGREGATION_QUEUES_E1H]; -#define BNX2X_TPA_START 1 -#define BNX2X_TPA_STOP 2 + struct bnx2x_agg_info tpa_info[ETH_MAX_AGGREGATION_QUEUES_E1H_E2]; u8 disable_tpa; #ifdef BNX2X_STOP_ON_ERROR u64 tpa_queue_used; #endif - struct tstorm_per_client_stats old_tclient; - struct ustorm_per_client_stats old_uclient; - struct xstorm_per_client_stats old_xclient; + struct tstorm_per_queue_stats old_tclient; + struct ustorm_per_queue_stats old_uclient; + struct xstorm_per_queue_stats old_xclient; struct bnx2x_eth_q_stats eth_q_stats; /* The size is calculated using the following: @@ -427,7 +474,13 @@ struct bnx2x_fastpath { 4 (for the digits and to make it DWORD aligned) */ #define FP_NAME_SIZE (sizeof(((struct net_device *)0)->name) + 8) char name[FP_NAME_SIZE]; - struct bnx2x *bp; /* parent */ + + /* MACs object */ + struct bnx2x_vlan_mac_obj mac_obj; + + /* Queue State object */ + struct bnx2x_queue_sp_obj q_obj; + }; #define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) @@ -435,11 +488,13 @@ struct bnx2x_fastpath { /* Use 2500 as a mini-jumbo MTU for FCoE */ #define BNX2X_FCOE_MINI_JUMBO_MTU 2500 -#ifdef BCM_CNIC -/* FCoE L2 `fastpath' is right after the eth entries */ +/* FCoE L2 `fastpath' entry is right after the eth entries */ #define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp) #define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX]) #define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var) + + +#ifdef BCM_CNIC #define IS_FCOE_FP(fp) (fp->index == FCOE_IDX) #define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX) #else @@ -449,77 +504,68 @@ struct bnx2x_fastpath { /* MC hsi */ -#define MAX_FETCH_BD 13 /* HW max BDs per packet */ -#define RX_COPY_THRESH 92 +#define MAX_FETCH_BD 13 /* HW max BDs per packet */ +#define RX_COPY_THRESH 92 -#define NUM_TX_RINGS 16 +#define NUM_TX_RINGS 16 #define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_tx_bd_types)) -#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) -#define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS) -#define MAX_TX_BD (NUM_TX_BD - 1) -#define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2) -#define INIT_JUMBO_TX_RING_SIZE MAX_TX_AVAIL -#define INIT_TX_RING_SIZE MAX_TX_AVAIL +#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) +#define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS) +#define MAX_TX_BD (NUM_TX_BD - 1) +#define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2) #define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \ (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1) -#define TX_BD(x) ((x) & MAX_TX_BD) -#define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT) +#define TX_BD(x) ((x) & MAX_TX_BD) +#define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT) /* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */ -#define NUM_RX_RINGS 8 +#define NUM_RX_RINGS 8 #define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd)) -#define MAX_RX_DESC_CNT (RX_DESC_CNT - 2) -#define RX_DESC_MASK (RX_DESC_CNT - 1) -#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS) -#define MAX_RX_BD (NUM_RX_BD - 1) -#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) -#define MIN_RX_SIZE_TPA 72 -#define MIN_RX_SIZE_NONTPA 10 -#define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL -#define INIT_RX_RING_SIZE MAX_RX_AVAIL +#define MAX_RX_DESC_CNT (RX_DESC_CNT - 2) +#define RX_DESC_MASK (RX_DESC_CNT - 1) +#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS) +#define MAX_RX_BD (NUM_RX_BD - 1) +#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) +#define MIN_RX_AVAIL 128 + +#define MIN_RX_SIZE_TPA_HW (CHIP_IS_E1(bp) ? \ + ETH_MIN_RX_CQES_WITH_TPA_E1 : \ + ETH_MIN_RX_CQES_WITH_TPA_E1H_E2) +#define MIN_RX_SIZE_NONTPA_HW ETH_MIN_RX_CQES_WITHOUT_TPA +#define MIN_RX_SIZE_TPA (max_t(u32, MIN_RX_SIZE_TPA_HW, MIN_RX_AVAIL)) +#define MIN_RX_SIZE_NONTPA (max_t(u32, MIN_RX_SIZE_NONTPA_HW,\ + MIN_RX_AVAIL)) + #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1) -#define RX_BD(x) ((x) & MAX_RX_BD) +#define RX_BD(x) ((x) & MAX_RX_BD) -/* As long as CQE is 4 times bigger than BD entry we have to allocate - 4 times more pages for CQ ring in order to keep it balanced with - BD ring */ -#define NUM_RCQ_RINGS (NUM_RX_RINGS * 4) +/* + * As long as CQE is X times bigger than BD entry we have to allocate X times + * more pages for CQ ring in order to keep it balanced with BD ring + */ +#define CQE_BD_REL (sizeof(union eth_rx_cqe) / sizeof(struct eth_rx_bd)) +#define NUM_RCQ_RINGS (NUM_RX_RINGS * CQE_BD_REL) #define RCQ_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe)) -#define MAX_RCQ_DESC_CNT (RCQ_DESC_CNT - 1) -#define NUM_RCQ_BD (RCQ_DESC_CNT * NUM_RCQ_RINGS) -#define MAX_RCQ_BD (NUM_RCQ_BD - 1) -#define MAX_RCQ_AVAIL (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2) +#define MAX_RCQ_DESC_CNT (RCQ_DESC_CNT - 1) +#define NUM_RCQ_BD (RCQ_DESC_CNT * NUM_RCQ_RINGS) +#define MAX_RCQ_BD (NUM_RCQ_BD - 1) +#define MAX_RCQ_AVAIL (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2) #define NEXT_RCQ_IDX(x) ((((x) & MAX_RCQ_DESC_CNT) == \ (MAX_RCQ_DESC_CNT - 1)) ? (x) + 2 : (x) + 1) -#define RCQ_BD(x) ((x) & MAX_RCQ_BD) +#define RCQ_BD(x) ((x) & MAX_RCQ_BD) /* This is needed for determining of last_max */ -#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b)) - -#define __SGE_MASK_SET_BIT(el, bit) \ - do { \ - el = ((el) | ((u64)0x1 << (bit))); \ - } while (0) - -#define __SGE_MASK_CLEAR_BIT(el, bit) \ - do { \ - el = ((el) & (~((u64)0x1 << (bit)))); \ - } while (0) - -#define SGE_MASK_SET_BIT(fp, idx) \ - __SGE_MASK_SET_BIT(fp->sge_mask[(idx) >> RX_SGE_MASK_ELEM_SHIFT], \ - ((idx) & RX_SGE_MASK_ELEM_MASK)) +#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b)) +#define SUB_S32(a, b) (s32)((s32)(a) - (s32)(b)) -#define SGE_MASK_CLEAR_BIT(fp, idx) \ - __SGE_MASK_CLEAR_BIT(fp->sge_mask[(idx) >> RX_SGE_MASK_ELEM_SHIFT], \ - ((idx) & RX_SGE_MASK_ELEM_MASK)) +#define BNX2X_SWCID_SHIFT 17 +#define BNX2X_SWCID_MASK ((0x1 << BNX2X_SWCID_SHIFT) - 1) /* used on a CID received from the HW */ -#define SW_CID(x) (le32_to_cpu(x) & \ - (COMMON_RAMROD_ETH_RX_CQE_CID >> 7)) +#define SW_CID(x) (le32_to_cpu(x) & BNX2X_SWCID_MASK) #define CQE_CMD(x) (le32_to_cpu(x) >> \ COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT) @@ -529,6 +575,9 @@ struct bnx2x_fastpath { #define BNX2X_DB_MIN_SHIFT 3 /* 8 bytes */ #define BNX2X_DB_SHIFT 7 /* 128 bytes*/ +#if (BNX2X_DB_SHIFT < BNX2X_DB_MIN_SHIFT) +#error "Min DB doorbell stride is 8" +#endif #define DPM_TRIGER_TYPE 0x40 #define DOORBELL(bp, cid, val) \ do { \ @@ -557,13 +606,11 @@ struct bnx2x_fastpath { /* stuff added to make the code fit 80Col */ - -#define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE) - -#define TPA_TYPE_START ETH_FAST_PATH_RX_CQE_START_FLG -#define TPA_TYPE_END ETH_FAST_PATH_RX_CQE_END_FLG -#define TPA_TYPE(cqe_fp_flags) ((cqe_fp_flags) & \ - (TPA_TYPE_START | TPA_TYPE_END)) +#define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE) +#define CQE_TYPE_START(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_START_AGG) +#define CQE_TYPE_STOP(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_STOP_AGG) +#define CQE_TYPE_SLOW(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_RAMROD) +#define CQE_TYPE_FAST(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_FASTPATH) #define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG @@ -590,12 +637,30 @@ struct bnx2x_fastpath { #define BNX2X_RX_SUM_FIX(cqe) \ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags) -#define U_SB_ETH_RX_CQ_INDEX 1 -#define U_SB_ETH_RX_BD_INDEX 2 -#define C_SB_ETH_TX_CQ_INDEX 5 + +#define FP_USB_FUNC_OFF \ + offsetof(struct cstorm_status_block_u, func) +#define FP_CSB_FUNC_OFF \ + offsetof(struct cstorm_status_block_c, func) + +#define HC_INDEX_TOE_RX_CQ_CONS 0 /* Formerly Ustorm TOE CQ index */ + /* (HC_INDEX_U_TOE_RX_CQ_CONS) */ +#define HC_INDEX_ETH_RX_CQ_CONS 1 /* Formerly Ustorm ETH CQ index */ + /* (HC_INDEX_U_ETH_RX_CQ_CONS) */ +#define HC_INDEX_ETH_RX_BD_CONS 2 /* Formerly Ustorm ETH BD index */ + /* (HC_INDEX_U_ETH_RX_BD_CONS) */ + +#define HC_INDEX_TOE_TX_CQ_CONS 4 /* Formerly Cstorm TOE CQ index */ + /* (HC_INDEX_C_TOE_TX_CQ_CONS) */ +#define HC_INDEX_ETH_TX_CQ_CONS 5 /* Formerly Cstorm ETH CQ index */ + /* (HC_INDEX_C_ETH_TX_CQ_CONS) */ + +#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_ETH_RX_CQ_CONS +#define U_SB_ETH_RX_BD_INDEX HC_INDEX_ETH_RX_BD_CONS +#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_ETH_TX_CQ_CONS #define BNX2X_RX_SB_INDEX \ - (&fp->sb_index_values[U_SB_ETH_RX_CQ_INDEX]) + (&fp->sb_index_values[HC_INDEX_ETH_RX_CQ_CONS]) #define BNX2X_TX_SB_INDEX \ (&fp->sb_index_values[C_SB_ETH_TX_CQ_INDEX]) @@ -615,29 +680,53 @@ struct bnx2x_common { #define CHIP_NUM_57711 0x164f #define CHIP_NUM_57711E 0x1650 #define CHIP_NUM_57712 0x1662 -#define CHIP_NUM_57712E 0x1663 +#define CHIP_NUM_57712_MF 0x1663 +#define CHIP_NUM_57713 0x1651 +#define CHIP_NUM_57713E 0x1652 +#define CHIP_NUM_57800 0x168a +#define CHIP_NUM_57800_MF 0x16a5 +#define CHIP_NUM_57810 0x168e +#define CHIP_NUM_57810_MF 0x16ae +#define CHIP_NUM_57840 0x168d +#define CHIP_NUM_57840_MF 0x16ab #define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710) #define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711) #define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E) #define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712) -#define CHIP_IS_57712E(bp) (CHIP_NUM(bp) == CHIP_NUM_57712E) +#define CHIP_IS_57712_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57712_MF) +#define CHIP_IS_57800(bp) (CHIP_NUM(bp) == CHIP_NUM_57800) +#define CHIP_IS_57800_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57800_MF) +#define CHIP_IS_57810(bp) (CHIP_NUM(bp) == CHIP_NUM_57810) +#define CHIP_IS_57810_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57810_MF) +#define CHIP_IS_57840(bp) (CHIP_NUM(bp) == CHIP_NUM_57840) +#define CHIP_IS_57840_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57840_MF) #define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ CHIP_IS_57711E(bp)) #define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ - CHIP_IS_57712E(bp)) + CHIP_IS_57712_MF(bp)) +#define CHIP_IS_E3(bp) (CHIP_IS_57800(bp) || \ + CHIP_IS_57800_MF(bp) || \ + CHIP_IS_57810(bp) || \ + CHIP_IS_57810_MF(bp) || \ + CHIP_IS_57840(bp) || \ + CHIP_IS_57840_MF(bp)) #define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp))) -#define IS_E1H_OFFSET (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) - -#define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000) -#define CHIP_REV_Ax 0x00000000 +#define USES_WARPCORE(bp) (CHIP_IS_E3(bp)) +#define IS_E1H_OFFSET (!CHIP_IS_E1(bp)) + +#define CHIP_REV_SHIFT 12 +#define CHIP_REV_MASK (0xF << CHIP_REV_SHIFT) +#define CHIP_REV_VAL(bp) (bp->common.chip_id & CHIP_REV_MASK) +#define CHIP_REV_Ax (0x0 << CHIP_REV_SHIFT) +#define CHIP_REV_Bx (0x1 << CHIP_REV_SHIFT) /* assume maximum 5 revisions */ -#define CHIP_REV_IS_SLOW(bp) (CHIP_REV(bp) > 0x00005000) +#define CHIP_REV_IS_SLOW(bp) (CHIP_REV_VAL(bp) > 0x00005000) /* Emul versions are A=>0xe, B=>0xc, C=>0xa, D=>8, E=>6 */ #define CHIP_REV_IS_EMUL(bp) ((CHIP_REV_IS_SLOW(bp)) && \ - !(CHIP_REV(bp) & 0x00001000)) + !(CHIP_REV_VAL(bp) & 0x00001000)) /* FPGA versions are A=>0xf, B=>0xd, C=>0xb, D=>9, E=>7 */ #define CHIP_REV_IS_FPGA(bp) ((CHIP_REV_IS_SLOW(bp)) && \ - (CHIP_REV(bp) & 0x00001000)) + (CHIP_REV_VAL(bp) & 0x00001000)) #define CHIP_TIME(bp) ((CHIP_REV_IS_EMUL(bp)) ? 2000 : \ ((CHIP_REV_IS_FPGA(bp)) ? 200 : 1)) @@ -645,6 +734,16 @@ struct bnx2x_common { #define CHIP_METAL(bp) (bp->common.chip_id & 0x00000ff0) #define CHIP_BOND_ID(bp) (bp->common.chip_id & 0x0000000f) #define CHIP_PARITY_ENABLED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) +#define CHIP_REV_SIM(bp) (((CHIP_REV_MASK - CHIP_REV_VAL(bp)) >>\ + (CHIP_REV_SHIFT + 1)) \ + << CHIP_REV_SHIFT) +#define CHIP_REV(bp) (CHIP_REV_IS_SLOW(bp) ? \ + CHIP_REV_SIM(bp) :\ + CHIP_REV_VAL(bp)) +#define CHIP_IS_E3B0(bp) (CHIP_IS_E3(bp) && \ + (CHIP_REV(bp) == CHIP_REV_Bx)) +#define CHIP_IS_E3A0(bp) (CHIP_IS_E3(bp) && \ + (CHIP_REV(bp) == CHIP_REV_Ax)) int flash_size; #define NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */ @@ -666,7 +765,7 @@ struct bnx2x_common { #define INT_BLOCK_MODE_NORMAL 0 #define INT_BLOCK_MODE_BW_COMP 2 #define CHIP_INT_MODE_IS_NBC(bp) \ - (CHIP_IS_E2(bp) && \ + (!CHIP_IS_E1x(bp) && \ !((bp)->common.int_block & INT_BLOCK_MODE_BW_COMP)) #define CHIP_INT_MODE_IS_BC(bp) (!CHIP_INT_MODE_IS_NBC(bp)) @@ -712,19 +811,15 @@ struct bnx2x_port { /* end of port */ -/* e1h Classification CAM line allocations */ -enum { - CAM_ETH_LINE = 0, - CAM_ISCSI_ETH_LINE, - CAM_FIP_ETH_LINE, - CAM_FIP_MCAST_LINE, - CAM_MAX_PF_LINE = CAM_FIP_MCAST_LINE -}; -/* number of MACs per function in NIG memory - used for SI mode */ -#define NIG_LLH_FUNC_MEM_SIZE 16 -/* number of entries in NIG_REG_LLHX_FUNC_MEM */ -#define NIG_LLH_FUNC_MEM_MAX_OFFSET 8 +#define STATS_OFFSET32(stat_name) \ + (offsetof(struct bnx2x_eth_stats, stat_name) / 4) +/* slow path */ + +/* slow path work-queue */ +extern struct workqueue_struct *bnx2x_wq; + +#define BNX2X_MAX_NUM_OF_VFS 64 #define BNX2X_VF_ID_INVALID 0xFF /* @@ -749,8 +844,10 @@ enum { * L2 queue is supported. the cid for the FCoE L2 queue is always X. */ -#define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */ -#define FP_SB_MAX_E2 16 /* fast-path interrupt contexts E2 */ +/* fast-path interrupt contexts E1x */ +#define FP_SB_MAX_E1x 16 +/* fast-path interrupt contexts E2 */ +#define FP_SB_MAX_E2 HC_SB_MAX_SB_E2 /* * cid_cnt paramter below refers to the value returned by @@ -761,13 +858,13 @@ enum { * The number of FP context allocated by the driver == max number of regular * L2 queues + 1 for the FCoE L2 queue */ -#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) +#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - FCOE_CONTEXT_USE) /* * The number of FP-SB allocated by the driver == max number of regular L2 * queues + 1 for the CNIC which also consumes an FP-SB */ -#define FP_SB_COUNT(cid_cnt) ((cid_cnt) - FCOE_CONTEXT_USE) +#define FP_SB_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) #define NUM_IGU_SB_REQUIRED(cid_cnt) \ (FP_SB_COUNT(cid_cnt) - NONE_ETH_CONTEXT_USE) @@ -788,38 +885,61 @@ union cdu_context { #define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) #endif -#define QM_ILT_PAGE_SZ_HW 3 -#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 32K */ +#define QM_ILT_PAGE_SZ_HW 0 +#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 4K */ #define QM_CID_ROUND 1024 #ifdef BCM_CNIC /* TM (timers) host DB constants */ -#define TM_ILT_PAGE_SZ_HW 2 -#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 16K */ +#define TM_ILT_PAGE_SZ_HW 0 +#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 4K */ /* #define TM_CONN_NUM (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */ #define TM_CONN_NUM 1024 #define TM_ILT_SZ (8 * TM_CONN_NUM) #define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ) /* SRC (Searcher) host DB constants */ -#define SRC_ILT_PAGE_SZ_HW 3 -#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 32K */ +#define SRC_ILT_PAGE_SZ_HW 0 +#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 4K */ #define SRC_HASH_BITS 10 #define SRC_CONN_NUM (1 << SRC_HASH_BITS) /* 1024 */ #define SRC_ILT_SZ (sizeof(struct src_ent) * SRC_CONN_NUM) #define SRC_T2_SZ SRC_ILT_SZ #define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ) + #endif -#define MAX_DMAE_C 8 +#define MAX_DMAE_C 8 /* DMA memory not used in fastpath */ struct bnx2x_slowpath { - struct eth_stats_query fw_stats; - struct mac_configuration_cmd mac_config; - struct mac_configuration_cmd mcast_config; - struct mac_configuration_cmd uc_mac_config; - struct client_init_ramrod_data client_init_data; + union { + struct mac_configuration_cmd e1x; + struct eth_classify_rules_ramrod_data e2; + } mac_rdata; + + + union { + struct tstorm_eth_mac_filter_config e1x; + struct eth_filter_rules_ramrod_data e2; + } rx_mode_rdata; + + union { + struct mac_configuration_cmd e1; + struct eth_multicast_rules_ramrod_data e2; + } mcast_rdata; + + struct eth_rss_update_ramrod_data rss_rdata; + + /* Queue State related ramrods are always sent under rtnl_lock */ + union { + struct client_init_ramrod_data init_data; + struct client_update_ramrod_data update_data; + } q_rdata; + + union { + struct function_start_data func_start; + } func_rdata; /* used by dmae command executer */ struct dmae_command dmae[MAX_DMAE_C]; @@ -846,7 +966,7 @@ struct bnx2x_slowpath { #define MAX_DYNAMIC_ATTN_GRPS 8 struct attn_route { - u32 sig[5]; + u32 sig[5]; }; struct iro { @@ -872,7 +992,7 @@ typedef enum { BNX2X_RECOVERY_WAIT, } bnx2x_recovery_state_t; -/** +/* * Event queue (EQ or event ring) MC hsi * NUM_EQ_PAGES and EQ_DESC_CNT_PAGE must be power of 2 */ @@ -910,6 +1030,24 @@ enum { BNX2X_LINK_REPORT_TX_FC_ON, }; +enum { + BNX2X_PORT_QUERY_IDX, + BNX2X_PF_QUERY_IDX, + BNX2X_FIRST_QUEUE_QUERY_IDX, +}; + +struct bnx2x_fw_stats_req { + struct stats_query_header hdr; + struct stats_query_entry query[STATS_QUERY_CMD_COUNT]; +}; + +struct bnx2x_fw_stats_data { + struct stats_counter storm_counters; + struct per_port_stats port; + struct per_pf_stats pf; + struct per_queue_stats queue_stats[1]; +}; + struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure @@ -919,10 +1057,23 @@ struct bnx2x { void __iomem *doorbells; u16 db_size; + u8 pf_num; /* absolute PF number */ + u8 pfid; /* per-path PF number */ + int base_fw_ndsb; /**/ +#define BP_PATH(bp) (CHIP_IS_E1x(bp) ? 0 : (bp->pf_num & 1)) +#define BP_PORT(bp) (bp->pfid & 1) +#define BP_FUNC(bp) (bp->pfid) +#define BP_ABS_FUNC(bp) (bp->pf_num) +#define BP_E1HVN(bp) (bp->pfid >> 1) +#define BP_VN(bp) (BP_E1HVN(bp)) /*remove when approved*/ +#define BP_L_ID(bp) (BP_E1HVN(bp) << 2) +#define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\ + BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1)) + struct net_device *dev; struct pci_dev *pdev; - struct iro *iro_arr; + const struct iro *iro_arr; #define IRO (bp->iro_arr) bnx2x_recovery_state_t recovery_state; @@ -940,7 +1091,8 @@ struct bnx2x { /* Max supported alignment is 256 (8 shift) */ #define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \ L1_CACHE_SHIFT : 8) -#define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT) + /* FW use 2 Cache lines Alignment for start packet and size */ +#define BNX2X_FW_RX_ALIGN (2 << BNX2X_RX_ALIGN_SHIFT) #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) struct host_sp_status_block *def_status_blk; @@ -970,10 +1122,12 @@ struct bnx2x { __le16 *eq_cons_sb; atomic_t eq_spq_left; /* COMMON_XXX ramrods credit */ - /* Flags for marking that there is a STAT_QUERY or - SET_MAC ramrod pending */ - int stats_pending; - int set_mac_pending; + + + /* Counter for marking that there is a STAT_QUERY ramrod pending */ + u16 stats_pending; + /* Counter for completed statistics ramrods */ + u16 stats_comp; /* End of fields used in the performance code paths */ @@ -981,47 +1135,27 @@ struct bnx2x { int msg_enable; u32 flags; -#define PCIX_FLAG 1 -#define PCI_32BIT_FLAG 2 -#define ONE_PORT_FLAG 4 -#define NO_WOL_FLAG 8 -#define USING_DAC_FLAG 0x10 -#define USING_MSIX_FLAG 0x20 -#define USING_MSI_FLAG 0x40 - -#define TPA_ENABLE_FLAG 0x80 -#define NO_MCP_FLAG 0x100 -#define DISABLE_MSI_FLAG 0x200 +#define PCIX_FLAG (1 << 0) +#define PCI_32BIT_FLAG (1 << 1) +#define ONE_PORT_FLAG (1 << 2) +#define NO_WOL_FLAG (1 << 3) +#define USING_DAC_FLAG (1 << 4) +#define USING_MSIX_FLAG (1 << 5) +#define USING_MSI_FLAG (1 << 6) +#define DISABLE_MSI_FLAG (1 << 7) +#define TPA_ENABLE_FLAG (1 << 8) +#define NO_MCP_FLAG (1 << 9) + #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) -#define MF_FUNC_DIS 0x1000 -#define FCOE_MACS_SET 0x2000 -#define NO_FCOE_FLAG 0x4000 -#define NO_ISCSI_OOO_FLAG 0x8000 -#define NO_ISCSI_FLAG 0x10000 +#define MF_FUNC_DIS (1 << 11) +#define OWN_CNIC_IRQ (1 << 12) +#define NO_ISCSI_OOO_FLAG (1 << 13) +#define NO_ISCSI_FLAG (1 << 14) +#define NO_FCOE_FLAG (1 << 15) -#define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) #define NO_ISCSI(bp) ((bp)->flags & NO_ISCSI_FLAG) #define NO_ISCSI_OOO(bp) ((bp)->flags & NO_ISCSI_OOO_FLAG) - - int pf_num; /* absolute PF number */ - int pfid; /* per-path PF number */ - int base_fw_ndsb; -#define BP_PATH(bp) (!CHIP_IS_E2(bp) ? \ - 0 : (bp->pf_num & 1)) -#define BP_PORT(bp) (bp->pfid & 1) -#define BP_FUNC(bp) (bp->pfid) -#define BP_ABS_FUNC(bp) (bp->pf_num) -#define BP_E1HVN(bp) (bp->pfid >> 1) -#define BP_VN(bp) (CHIP_MODE_IS_4_PORT(bp) ? \ - 0 : BP_E1HVN(bp)) -#define BP_L_ID(bp) (BP_E1HVN(bp) << 2) -#define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\ - BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1)) - -#ifdef BCM_CNIC -#define BCM_CNIC_CID_START 16 -#define BCM_ISCSI_ETH_CL_ID 17 -#endif +#define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) int pm_cap; int pcie_cap; @@ -1048,9 +1182,9 @@ struct bnx2x { struct cmng_struct_per_port cmng; u32 vn_weight_sum; - u32 mf_config[E1HVN_MAX]; u32 mf2_config[E2_FUNC_MAX]; + u32 path_has_ovlan; /* E3 */ u16 mf_ov; u8 mf_mode; #define IS_MF(bp) (bp->mf_mode != 0) @@ -1075,32 +1209,20 @@ struct bnx2x { u32 lin_cnt; - int state; + u16 state; #define BNX2X_STATE_CLOSED 0 #define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000 #define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000 #define BNX2X_STATE_OPEN 0x3000 #define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000 #define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000 -#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000 -#define BNX2X_STATE_FUNC_STARTED 0x7000 + #define BNX2X_STATE_DIAG 0xe000 #define BNX2X_STATE_ERROR 0xf000 int multi_mode; int num_queues; int disable_tpa; - u32 *rx_indir_table; - - struct tstorm_eth_mac_filter_config mac_filters; -#define BNX2X_ACCEPT_NONE 0x0000 -#define BNX2X_ACCEPT_UNICAST 0x0001 -#define BNX2X_ACCEPT_MULTICAST 0x0002 -#define BNX2X_ACCEPT_ALL_UNICAST 0x0004 -#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 -#define BNX2X_ACCEPT_BROADCAST 0x0010 -#define BNX2X_ACCEPT_UNMATCHED_UCAST 0x0020 -#define BNX2X_PROMISCUOUS_MODE 0x10000 u32 rx_mode; #define BNX2X_RX_MODE_NONE 0 @@ -1108,7 +1230,6 @@ struct bnx2x { #define BNX2X_RX_MODE_ALLMULTI 2 #define BNX2X_RX_MODE_PROMISC 3 #define BNX2X_MAX_MULTICAST 64 -#define BNX2X_MAX_EMUL_MULTI 16 u8 igu_dsb_id; u8 igu_base_sb; @@ -1117,11 +1238,38 @@ struct bnx2x { struct bnx2x_slowpath *slowpath; dma_addr_t slowpath_mapping; + + /* Total number of FW statistics requests */ + u8 fw_stats_num; + + /* + * This is a memory buffer that will contain both statistics + * ramrod request and data. + */ + void *fw_stats; + dma_addr_t fw_stats_mapping; + + /* + * FW statistics request shortcut (points at the + * beginning of fw_stats buffer). + */ + struct bnx2x_fw_stats_req *fw_stats_req; + dma_addr_t fw_stats_req_mapping; + int fw_stats_req_sz; + + /* + * FW statistics data shortcut (points at the begining of + * fw_stats buffer + fw_stats_req_sz). + */ + struct bnx2x_fw_stats_data *fw_stats_data; + dma_addr_t fw_stats_data_mapping; + int fw_stats_data_sz; + struct hw_context context; struct bnx2x_ilt *ilt; #define BP_ILT(bp) ((bp)->ilt) -#define ILT_MAX_LINES 128 +#define ILT_MAX_LINES 256 int l2_cid_count; #define L2_ILT_LINES(bp) (DIV_ROUND_UP((bp)->l2_cid_count, \ @@ -1143,16 +1291,18 @@ struct bnx2x { struct cnic_eth_dev cnic_eth_dev; union host_hc_status_block cnic_sb; dma_addr_t cnic_sb_mapping; -#define CNIC_SB_ID(bp) ((bp)->base_fw_ndsb + BP_L_ID(bp)) -#define CNIC_IGU_SB_ID(bp) ((bp)->igu_base_sb) struct eth_spe *cnic_kwq; struct eth_spe *cnic_kwq_prod; struct eth_spe *cnic_kwq_cons; struct eth_spe *cnic_kwq_last; u16 cnic_kwq_pending; u16 cnic_spq_pending; - struct mutex cnic_mutex; u8 fip_mac[ETH_ALEN]; + struct mutex cnic_mutex; + struct bnx2x_vlan_mac_obj iscsi_l2_mac_obj; + + /* Start index of the "special" (CNIC related) L2 cleints */ + u8 cnic_base_cl_id; #endif int dmae_ready; @@ -1189,6 +1339,8 @@ struct bnx2x { u16 *init_ops_offsets; /* Data blob - has 32 bit granularity */ u32 *init_data; + u32 init_mode_flags; +#define INIT_MODE_FLAGS(bp) (bp->init_mode_flags) /* Zipped PRAM blobs - raw data */ const u8 *tsem_int_table_data; const u8 *tsem_pram_data; @@ -1210,8 +1362,10 @@ struct bnx2x { #define INIT_CSEM_INT_TABLE_DATA(bp) (bp->csem_int_table_data) #define INIT_CSEM_PRAM_DATA(bp) (bp->csem_pram_data) +#define PHY_FW_VER_LEN 20 char fw_ver[32]; const struct firmware *firmware; + /* LLDP params */ struct bnx2x_config_lldp_params lldp_config_params; @@ -1230,13 +1384,30 @@ struct bnx2x { bool dcbx_mode_uset; struct bnx2x_config_dcbx_params dcbx_config_params; - struct bnx2x_dcbx_port_params dcbx_port_params; int dcb_version; - /* DCBX Negotiation results */ + /* CAM credit pools */ + struct bnx2x_credit_pool_obj macs_pool; + + /* RX_MODE object */ + struct bnx2x_rx_mode_obj rx_mode_obj; + + /* MCAST object */ + struct bnx2x_mcast_obj mcast_obj; + + /* RSS configuration object */ + struct bnx2x_rss_config_obj rss_conf_obj; + + /* Function State controlling object */ + struct bnx2x_func_sp_obj func_obj; + + unsigned long sp_state; + + /* DCBX Negotation results */ struct dcbx_features dcbx_local_feat; u32 dcbx_error; + #ifdef BCM_DCBNL struct dcbx_features dcbx_remote_feat; u32 dcbx_remote_flags; @@ -1244,42 +1415,11 @@ struct bnx2x { u32 pending_max; }; -/** - * Init queue/func interface - */ -/* queue init flags */ -#define QUEUE_FLG_TPA 0x0001 -#define QUEUE_FLG_CACHE_ALIGN 0x0002 -#define QUEUE_FLG_STATS 0x0004 -#define QUEUE_FLG_OV 0x0008 -#define QUEUE_FLG_VLAN 0x0010 -#define QUEUE_FLG_COS 0x0020 -#define QUEUE_FLG_HC 0x0040 -#define QUEUE_FLG_DHC 0x0080 -#define QUEUE_FLG_OOO 0x0100 - -#define QUEUE_DROP_IP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR -#define QUEUE_DROP_TCP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR -#define QUEUE_DROP_TTL0 TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 -#define QUEUE_DROP_UDP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR - - - -/* rss capabilities */ -#define RSS_IPV4_CAP 0x0001 -#define RSS_IPV4_TCP_CAP 0x0002 -#define RSS_IPV6_CAP 0x0004 -#define RSS_IPV6_TCP_CAP 0x0008 - +/* Tx queues may be less or equal to Rx queues */ +extern int num_queues; #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NONE_ETH_CONTEXT_USE) -/* ethtool statistics are displayed for all regular ethernet queues and the - * fcoe L2 queue if not disabled - */ -#define BNX2X_NUM_STAT_QUEUES(bp) (NO_FCOE(bp) ? BNX2X_NUM_ETH_QUEUES(bp) : \ - (BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE)) - #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) #define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE) @@ -1297,107 +1437,15 @@ struct bnx2x { TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY /* func init flags */ -#define FUNC_FLG_STATS 0x0001 -#define FUNC_FLG_TPA 0x0002 -#define FUNC_FLG_SPQ 0x0004 -#define FUNC_FLG_LEADING 0x0008 /* PF only */ - -struct rxq_pause_params { - u16 bd_th_lo; - u16 bd_th_hi; - u16 rcq_th_lo; - u16 rcq_th_hi; - u16 sge_th_lo; /* valid iff QUEUE_FLG_TPA */ - u16 sge_th_hi; /* valid iff QUEUE_FLG_TPA */ - u16 pri_map; -}; - -struct bnx2x_rxq_init_params { - /* cxt*/ - struct eth_context *cxt; - - /* dma */ - dma_addr_t dscr_map; - dma_addr_t sge_map; - dma_addr_t rcq_map; - dma_addr_t rcq_np_map; - - u16 flags; - u16 drop_flags; - u16 mtu; - u16 buf_sz; - u16 fw_sb_id; - u16 cl_id; - u16 spcl_id; - u16 cl_qzone_id; - - /* valid iff QUEUE_FLG_STATS */ - u16 stat_id; - - /* valid iff QUEUE_FLG_TPA */ - u16 tpa_agg_sz; - u16 sge_buf_sz; - u16 max_sges_pkt; - - /* valid iff QUEUE_FLG_CACHE_ALIGN */ - u8 cache_line_log; - - u8 sb_cq_index; - u32 cid; - - /* desired interrupts per sec. valid iff QUEUE_FLG_HC */ - u32 hc_rate; -}; - -struct bnx2x_txq_init_params { - /* cxt*/ - struct eth_context *cxt; +#define FUNC_FLG_RSS 0x0001 +#define FUNC_FLG_STATS 0x0002 +/* removed FUNC_FLG_UNMATCHED 0x0004 */ +#define FUNC_FLG_TPA 0x0008 +#define FUNC_FLG_SPQ 0x0010 +#define FUNC_FLG_LEADING 0x0020 /* PF only */ - /* dma */ - dma_addr_t dscr_map; - - u16 flags; - u16 fw_sb_id; - u8 sb_cq_index; - u8 cos; /* valid iff QUEUE_FLG_COS */ - u16 stat_id; /* valid iff QUEUE_FLG_STATS */ - u16 traffic_type; - u32 cid; - u16 hc_rate; /* desired interrupts per sec.*/ - /* valid iff QUEUE_FLG_HC */ - -}; - -struct bnx2x_client_ramrod_params { - int *pstate; - int state; - u16 index; - u16 cl_id; - u32 cid; - u8 poll; -#define CLIENT_IS_FCOE 0x01 -#define CLIENT_IS_LEADING_RSS 0x02 - u8 flags; -}; - -struct bnx2x_client_init_params { - struct rxq_pause_params pause; - struct bnx2x_rxq_init_params rxq_params; - struct bnx2x_txq_init_params txq_params; - struct bnx2x_client_ramrod_params ramrod_params; -}; - -struct bnx2x_rss_params { - int mode; - u16 cap; - u16 result_mask; -}; struct bnx2x_func_init_params { - - /* rss */ - struct bnx2x_rss_params *rss; /* valid iff FUNC_FLG_RSS */ - /* dma */ dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */ dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */ @@ -1409,17 +1457,10 @@ struct bnx2x_func_init_params { }; #define for_each_eth_queue(bp, var) \ - for (var = 0; var < BNX2X_NUM_ETH_QUEUES(bp); var++) + for (var = 0; var < BNX2X_NUM_ETH_QUEUES(bp); var++) #define for_each_nondefault_eth_queue(bp, var) \ - for (var = 1; var < BNX2X_NUM_ETH_QUEUES(bp); var++) - -#define for_each_napi_queue(bp, var) \ - for (var = 0; \ - var < BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE; var++) \ - if (skip_queue(bp, var)) \ - continue; \ - else + for (var = 1; var < BNX2X_NUM_ETH_QUEUES(bp); var++) #define for_each_queue(bp, var) \ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ @@ -1457,11 +1498,66 @@ struct bnx2x_func_init_params { #define skip_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) -#define WAIT_RAMROD_POLL 0x01 -#define WAIT_RAMROD_COMMON 0x02 + + +/** + * bnx2x_set_mac_one - configure a single MAC address + * + * @bp: driver handle + * @mac: MAC to configure + * @obj: MAC object handle + * @set: if 'true' add a new MAC, otherwise - delete + * @mac_type: the type of the MAC to configure (e.g. ETH, UC list) + * @ramrod_flags: RAMROD_XXX flags (e.g. RAMROD_CONT, RAMROD_COMP_WAIT) + * + * Configures one MAC according to provided parameters or continues the + * execution of previously scheduled commands if RAMROD_CONT is set in + * ramrod_flags. + * + * Returns zero if operation has successfully completed, a positive value if the + * operation has been successfully scheduled and a negative - if a requested + * operations has failed. + */ +int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac, + struct bnx2x_vlan_mac_obj *obj, bool set, + int mac_type, unsigned long *ramrod_flags); +/** + * Deletes all MACs configured for the specific MAC object. + * + * @param bp Function driver instance + * @param mac_obj MAC object to cleanup + * + * @return zero if all MACs were cleaned + */ + +/** + * bnx2x_del_all_macs - delete all MACs configured for the specific MAC object + * + * @bp: driver handle + * @mac_obj: MAC object handle + * @mac_type: type of the MACs to clear (BNX2X_XXX_MAC) + * @wait_for_comp: if 'true' block until completion + * + * Deletes all MACs of the specific type (e.g. ETH, UC list). + * + * Returns zero if operation has successfully completed, a positive value if the + * operation has been successfully scheduled and a negative - if a requested + * operations has failed. + */ +int bnx2x_del_all_macs(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *mac_obj, + int mac_type, bool wait_for_comp); + +/* Init Function API */ +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p); +int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); +int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); +int bnx2x_set_mult_gpio(struct bnx2x *bp, u8 pins, u32 mode); +int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); void bnx2x_read_mf_cfg(struct bnx2x *bp); + /* dmae */ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, @@ -1472,21 +1568,10 @@ u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, bool with_comp, u8 comp_type); -int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); -int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); -int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); void bnx2x_calc_fc_adv(struct bnx2x *bp); int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common); - -/* Clears multicast and unicast list configuration in the chip. */ -void bnx2x_invalidate_uc_list(struct bnx2x *bp); - -int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags); - + u32 data_hi, u32 data_lo, int cmd_type); void bnx2x_update_coalesce(struct bnx2x *bp); int bnx2x_get_cur_phy_idx(struct bnx2x *bp); @@ -1644,7 +1729,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, /* must be used on a CID before placing it on a HW ring */ #define HW_CID(bp, x) ((BP_PORT(bp) << 23) | \ - (BP_E1HVN(bp) << 17) | (x)) + (BP_E1HVN(bp) << BNX2X_SWCID_SHIFT) | \ + (x)) #define SP_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_spe)) #define MAX_SP_DESC_CNT (SP_DESC_CNT - 1) @@ -1771,6 +1857,30 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT)) #define MULTI_MASK 0x7f + +#define DEF_USB_FUNC_OFF offsetof(struct cstorm_def_status_block_u, func) +#define DEF_CSB_FUNC_OFF offsetof(struct cstorm_def_status_block_c, func) +#define DEF_XSB_FUNC_OFF offsetof(struct xstorm_def_status_block, func) +#define DEF_TSB_FUNC_OFF offsetof(struct tstorm_def_status_block, func) + +#define DEF_USB_IGU_INDEX_OFF \ + offsetof(struct cstorm_def_status_block_u, igu_index) +#define DEF_CSB_IGU_INDEX_OFF \ + offsetof(struct cstorm_def_status_block_c, igu_index) +#define DEF_XSB_IGU_INDEX_OFF \ + offsetof(struct xstorm_def_status_block, igu_index) +#define DEF_TSB_IGU_INDEX_OFF \ + offsetof(struct tstorm_def_status_block, igu_index) + +#define DEF_USB_SEGMENT_OFF \ + offsetof(struct cstorm_def_status_block_u, segment) +#define DEF_CSB_SEGMENT_OFF \ + offsetof(struct cstorm_def_status_block_c, segment) +#define DEF_XSB_SEGMENT_OFF \ + offsetof(struct xstorm_def_status_block, segment) +#define DEF_TSB_SEGMENT_OFF \ + offsetof(struct tstorm_def_status_block, segment) + #define BNX2X_SP_DSB_INDEX \ (&bp->def_status_blk->sp_sb.\ index_values[HC_SP_INDEX_ETH_DEF_CONS]) @@ -1782,7 +1892,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, } while (0) #define GET_FLAG(value, mask) \ - (((value) &= (mask)) >> (mask##_SHIFT)) + (((value) & (mask)) >> (mask##_SHIFT)) #define GET_FIELD(value, fname) \ (((value) & (fname##_MASK)) >> (fname##_SHIFT)) @@ -1817,14 +1927,12 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define HC_SEG_ACCESS_ATTN 4 #define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/ -#ifdef BNX2X_MAIN -#define BNX2X_EXTERN -#else -#define BNX2X_EXTERN extern -#endif - -BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ - -extern void bnx2x_set_ethtool_ops(struct net_device *netdev); +static const u32 dmae_reg_go_c[] = { + DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, + DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, + DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11, + DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15 +}; +void bnx2x_set_ethtool_ops(struct net_device *netdev); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index c72e1df0472..ebd8b1cdd58 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -27,7 +27,7 @@ #include "bnx2x_init.h" #include "bnx2x_sp.h" -static int bnx2x_setup_irqs(struct bnx2x *bp); + /** * bnx2x_bz_fp - zero content of the fastpath structure. @@ -72,6 +72,8 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) to_fp->napi = orig_napi; } +int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ + /* free skb in the packet ring at pos idx * return idx of last bd freed */ @@ -88,8 +90,8 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* prefetch skb end pointer to speedup dev_kfree_skb() */ prefetch(&skb->end); - DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n", - idx, tx_buf, skb); + DP(BNX2X_MSG_FP, "fp[%d]: pkt_idx %d buff @(%p)->skb %p\n", + fp->index, idx, tx_buf, skb); /* unmap first bd */ DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); @@ -97,6 +99,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE); + nbd = le16_to_cpu(tx_start_bd->nbd) - 1; #ifdef BNX2X_STOP_ON_ERROR if ((nbd - 1) > (MAX_SKB_FRAGS + 2)) { @@ -175,6 +178,9 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) * memory barrier, there is a small possibility that * start_xmit() will miss it and cause the queue to be stopped * forever. + * On the other hand we need an rmb() here to ensure the proper + * ordering of bit testing in the following + * netif_tx_queue_stopped(txq) call. */ smp_mb(); @@ -226,7 +232,7 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, /* First mark all used pages */ for (i = 0; i < sge_len; i++) - SGE_MASK_CLEAR_BIT(fp, + BIT_VEC64_CLEAR_BIT(fp->sge_mask, RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[i]))); DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n", @@ -238,8 +244,8 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); last_max = RX_SGE(fp->last_max_sge); - last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT; - first_elem = RX_SGE(fp->rx_sge_prod) >> RX_SGE_MASK_ELEM_SHIFT; + last_elem = last_max >> BIT_VEC64_ELEM_SHIFT; + first_elem = RX_SGE(fp->rx_sge_prod) >> BIT_VEC64_ELEM_SHIFT; /* If ring is not full */ if (last_elem + 1 != first_elem) @@ -250,8 +256,8 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, if (likely(fp->sge_mask[i])) break; - fp->sge_mask[i] = RX_SGE_MASK_ELEM_ONE_MASK; - delta += RX_SGE_MASK_ELEM_SZ; + fp->sge_mask[i] = BIT_VEC64_ELEM_ONE_MASK; + delta += BIT_VEC64_ELEM_SZ; } if (delta > 0) { @@ -266,33 +272,56 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, } static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, - struct sk_buff *skb, u16 cons, u16 prod) + struct sk_buff *skb, u16 cons, u16 prod, + struct eth_fast_path_rx_cqe *cqe) { struct bnx2x *bp = fp->bp; struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; dma_addr_t mapping; + struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; + struct sw_rx_bd *first_buf = &tpa_info->first_buf; - /* move empty skb from pool to prod and map it */ - prod_rx_buf->skb = fp->tpa_pool[queue].skb; - mapping = dma_map_single(&bp->pdev->dev, fp->tpa_pool[queue].skb->data, - fp->rx_buf_size, DMA_FROM_DEVICE); - dma_unmap_addr_set(prod_rx_buf, mapping, mapping); - - /* move partial skb from cons to pool (don't unmap yet) */ - fp->tpa_pool[queue] = *cons_rx_buf; - - /* mark bin state as start - print error if current state != stop */ - if (fp->tpa_state[queue] != BNX2X_TPA_STOP) + /* print error if current state != stop */ + if (tpa_info->tpa_state != BNX2X_TPA_STOP) BNX2X_ERR("start of bin not in stop [%d]\n", queue); - fp->tpa_state[queue] = BNX2X_TPA_START; + /* Try to map an empty skb from the aggregation info */ + mapping = dma_map_single(&bp->pdev->dev, + first_buf->skb->data, + fp->rx_buf_size, DMA_FROM_DEVICE); + /* + * ...if it fails - move the skb from the consumer to the producer + * and set the current aggregation state as ERROR to drop it + * when TPA_STOP arrives. + */ + + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + /* Move the BD from the consumer to the producer */ + bnx2x_reuse_rx_skb(fp, cons, prod); + tpa_info->tpa_state = BNX2X_TPA_ERROR; + return; + } + /* move empty skb from pool to prod */ + prod_rx_buf->skb = first_buf->skb; + dma_unmap_addr_set(prod_rx_buf, mapping, mapping); /* point prod_bd to new skb */ prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + /* move partial skb from cons to pool (don't unmap yet) */ + *first_buf = *cons_rx_buf; + + /* mark bin state as START */ + tpa_info->parsing_flags = + le16_to_cpu(cqe->pars_flags.flags); + tpa_info->vlan_tag = le16_to_cpu(cqe->vlan_tag); + tpa_info->tpa_state = BNX2X_TPA_START; + tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd); + tpa_info->placement_offset = cqe->placement_offset; + #ifdef BNX2X_STOP_ON_ERROR fp->tpa_queue_used |= (1 << queue); #ifdef _ASM_GENERIC_INT_L64_H @@ -323,10 +352,17 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags, u16 len_on_bd) { - /* TPA arrgregation won't have an IP options and TCP options - * other than timestamp. + /* + * TPA arrgregation won't have either IP options or TCP options + * other than timestamp or IPv6 extension headers. */ - u16 hdrs_len = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr); + u16 hdrs_len = ETH_HLEN + sizeof(struct tcphdr); + + if (GET_FLAG(parsing_flags, PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == + PRS_FLAG_OVERETH_IPV6) + hdrs_len += sizeof(struct ipv6hdr); + else /* IPv4 */ + hdrs_len += sizeof(struct iphdr); /* Check if there was a TCP timestamp, if there is it's will @@ -341,30 +377,30 @@ static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags, } static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, - struct sk_buff *skb, - struct eth_fast_path_rx_cqe *fp_cqe, - u16 cqe_idx, u16 parsing_flags) + u16 queue, struct sk_buff *skb, + struct eth_end_agg_rx_cqe *cqe, + u16 cqe_idx) { struct sw_rx_page *rx_pg, old_rx_pg; - u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); u32 i, frag_len, frag_size, pages; int err; int j; + struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; + u16 len_on_bd = tpa_info->len_on_bd; - frag_size = le16_to_cpu(fp_cqe->pkt_len) - len_on_bd; + frag_size = le16_to_cpu(cqe->pkt_len) - len_on_bd; pages = SGE_PAGE_ALIGN(frag_size) >> SGE_PAGE_SHIFT; /* This is needed in order to enable forwarding support */ if (frag_size) - skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp, parsing_flags, - len_on_bd); + skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp, + tpa_info->parsing_flags, len_on_bd); #ifdef BNX2X_STOP_ON_ERROR if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n", pages, cqe_idx); - BNX2X_ERR("fp_cqe->pkt_len = %d fp_cqe->len_on_bd = %d\n", - fp_cqe->pkt_len, len_on_bd); + BNX2X_ERR("cqe->pkt_len = %d\n", cqe->pkt_len); bnx2x_panic(); return -EINVAL; } @@ -372,8 +408,7 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Run through the SGL and compose the fragmented skb */ for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) { - u16 sge_idx = - RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[j])); + u16 sge_idx = RX_SGE(le16_to_cpu(cqe->sgl_or_raw_data.sgl[j])); /* FW gives the indices of the SGE as if the ring is an array (meaning that "next" element will consume 2 indices) */ @@ -408,13 +443,28 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, } static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, - u16 queue, int pad, int len, union eth_rx_cqe *cqe, + u16 queue, struct eth_end_agg_rx_cqe *cqe, u16 cqe_idx) { - struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue]; + struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; + struct sw_rx_bd *rx_buf = &tpa_info->first_buf; + u8 pad = tpa_info->placement_offset; + u16 len = tpa_info->len_on_bd; struct sk_buff *skb = rx_buf->skb; /* alloc new skb */ - struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); + struct sk_buff *new_skb; + u8 old_tpa_state = tpa_info->tpa_state; + + tpa_info->tpa_state = BNX2X_TPA_STOP; + + /* If we there was an error during the handling of the TPA_START - + * drop this aggregation. + */ + if (old_tpa_state == BNX2X_TPA_ERROR) + goto drop; + + /* Try to allocate the new skb */ + new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); /* Unmap skb in the pool anyway, as we are going to change pool entry status to BNX2X_TPA_STOP even if new skb allocation @@ -423,11 +473,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, fp->rx_buf_size, DMA_FROM_DEVICE); if (likely(new_skb)) { - /* fix ip xsum and give it to the stack */ - /* (no need to map the new skb) */ - u16 parsing_flags = - le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags); - prefetch(skb); prefetch(((char *)(skb)) + L1_CACHE_BYTES); @@ -447,21 +492,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, skb->protocol = eth_type_trans(skb, bp->dev); skb->ip_summed = CHECKSUM_UNNECESSARY; - { - struct iphdr *iph; - - iph = (struct iphdr *)skb->data; - iph->check = 0; - iph->check = ip_fast_csum((u8 *)iph, iph->ihl); - } - - if (!bnx2x_fill_frag_skb(bp, fp, skb, - &cqe->fast_path_cqe, cqe_idx, - parsing_flags)) { - if (parsing_flags & PARSING_FLAGS_VLAN) - __vlan_hwaccel_put_tag(skb, - le16_to_cpu(cqe->fast_path_cqe. - vlan_tag)); + if (!bnx2x_fill_frag_skb(bp, fp, queue, skb, cqe, cqe_idx)) { + if (tpa_info->parsing_flags & PARSING_FLAGS_VLAN) + __vlan_hwaccel_put_tag(skb, tpa_info->vlan_tag); napi_gro_receive(&fp->napi, skb); } else { DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages" @@ -471,16 +504,16 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* put new skb in bin */ - fp->tpa_pool[queue].skb = new_skb; + rx_buf->skb = new_skb; - } else { - /* else drop the packet and keep the buffer in the bin */ - DP(NETIF_MSG_RX_STATUS, - "Failed to allocate new skb - dropping packet!\n"); - fp->eth_q_stats.rx_skb_alloc_failed++; + return; } - fp->tpa_state[queue] = BNX2X_TPA_STOP; +drop: + /* drop the packet and keep the buffer in the bin */ + DP(NETIF_MSG_RX_STATUS, + "Failed to allocate or map a new skb - dropping packet!\n"); + fp->eth_q_stats.rx_skb_alloc_failed++; } /* Set Toeplitz hash value in the skb using the value from the @@ -534,9 +567,16 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) struct sw_rx_bd *rx_buf = NULL; struct sk_buff *skb; union eth_rx_cqe *cqe; + struct eth_fast_path_rx_cqe *cqe_fp; u8 cqe_fp_flags; + enum eth_rx_cqe_type cqe_fp_type; u16 len, pad; +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return 0; +#endif + comp_ring_cons = RCQ_BD(sw_comp_cons); bd_prod = RX_BD(bd_prod); bd_cons = RX_BD(bd_cons); @@ -549,17 +589,18 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) PAGE_SIZE + 1)); cqe = &fp->rx_comp_ring[comp_ring_cons]; - cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; + cqe_fp = &cqe->fast_path_cqe; + cqe_fp_flags = cqe_fp->type_error_flags; + cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE; DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x" " queue %x vlan %x len %u\n", CQE_TYPE(cqe_fp_flags), - cqe_fp_flags, cqe->fast_path_cqe.status_flags, - le32_to_cpu(cqe->fast_path_cqe.rss_hash_result), - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), - le16_to_cpu(cqe->fast_path_cqe.pkt_len)); + cqe_fp_flags, cqe_fp->status_flags, + le32_to_cpu(cqe_fp->rss_hash_result), + le16_to_cpu(cqe_fp->vlan_tag), le16_to_cpu(cqe_fp->pkt_len)); /* is this a slowpath msg? */ - if (unlikely(CQE_TYPE(cqe_fp_flags))) { + if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) { bnx2x_sp_event(fp, cqe); goto next_cqe; @@ -568,61 +609,59 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) rx_buf = &fp->rx_buf_ring[bd_cons]; skb = rx_buf->skb; prefetch(skb); - len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); - pad = cqe->fast_path_cqe.placement_offset; - /* - If CQE is marked both TPA_START and TPA_END it is - * a non-TPA CQE. - * - FP CQE will always have either TPA_START or/and - * TPA_STOP flags set. - */ - if ((!fp->disable_tpa) && - (TPA_TYPE(cqe_fp_flags) != - (TPA_TYPE_START | TPA_TYPE_END))) { - u16 queue = cqe->fast_path_cqe.queue_index; + if (!CQE_TYPE_FAST(cqe_fp_type)) { +#ifdef BNX2X_STOP_ON_ERROR + /* sanity check */ + if (fp->disable_tpa && + (CQE_TYPE_START(cqe_fp_type) || + CQE_TYPE_STOP(cqe_fp_type))) + BNX2X_ERR("START/STOP packet while " + "disable_tpa type %x\n", + CQE_TYPE(cqe_fp_type)); +#endif - if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_START) { + if (CQE_TYPE_START(cqe_fp_type)) { + u16 queue = cqe_fp->queue_index; DP(NETIF_MSG_RX_STATUS, "calling tpa_start on queue %d\n", queue); bnx2x_tpa_start(fp, queue, skb, - bd_cons, bd_prod); + bd_cons, bd_prod, + cqe_fp); - /* Set Toeplitz hash for an LRO skb */ + /* Set Toeplitz hash for LRO skb */ bnx2x_set_skb_rxhash(bp, cqe, skb); goto next_rx; - } else { /* TPA_STOP */ + + } else { + u16 queue = + cqe->end_agg_cqe.queue_index; DP(NETIF_MSG_RX_STATUS, "calling tpa_stop on queue %d\n", queue); - if (!BNX2X_RX_SUM_FIX(cqe)) - BNX2X_ERR("STOP on none TCP " - "data\n"); - - /* This is a size of the linear data - on this skb */ - len = le16_to_cpu(cqe->fast_path_cqe. - len_on_bd); - bnx2x_tpa_stop(bp, fp, queue, pad, - len, cqe, comp_ring_cons); + bnx2x_tpa_stop(bp, fp, queue, + &cqe->end_agg_cqe, + comp_ring_cons); #ifdef BNX2X_STOP_ON_ERROR if (bp->panic) return 0; #endif - bnx2x_update_sge_prod(fp, - &cqe->fast_path_cqe); + bnx2x_update_sge_prod(fp, cqe_fp); goto next_cqe; } } - + /* non TPA */ + len = le16_to_cpu(cqe_fp->pkt_len); + pad = cqe_fp->placement_offset; dma_sync_single_for_device(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), - pad + RX_COPY_THRESH, - DMA_FROM_DEVICE); + pad + RX_COPY_THRESH, + DMA_FROM_DEVICE); prefetch(((char *)(skb)) + L1_CACHE_BYTES); /* is this an error packet? */ @@ -641,8 +680,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) (len <= RX_COPY_THRESH)) { struct sk_buff *new_skb; - new_skb = netdev_alloc_skb(bp->dev, - len + pad); + new_skb = netdev_alloc_skb(bp->dev, len + pad); if (new_skb == NULL) { DP(NETIF_MSG_RX_ERR, "ERROR packet dropped " @@ -688,6 +726,7 @@ reuse_rx: skb_checksum_none_assert(skb); if (bp->dev->features & NETIF_F_RXCSUM) { + if (likely(BNX2X_RX_CSUM_OK(cqe))) skb->ip_summed = CHECKSUM_UNNECESSARY; else @@ -697,10 +736,10 @@ reuse_rx: skb_record_rx_queue(skb, fp->index); - if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN) + if (le16_to_cpu(cqe_fp->pars_flags.flags) & + PARSING_FLAGS_VLAN) __vlan_hwaccel_put_tag(skb, - le16_to_cpu(cqe->fast_path_cqe.vlan_tag)); + le16_to_cpu(cqe_fp->vlan_tag)); napi_gro_receive(&fp->napi, skb); @@ -926,7 +965,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) { int func = BP_FUNC(bp); int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : - ETH_MAX_AGGREGATION_QUEUES_E1H; + ETH_MAX_AGGREGATION_QUEUES_E1H_E2; u16 ring_prod; int i, j; @@ -938,11 +977,16 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) "mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size); if (!fp->disable_tpa) { - /* Fill the per-aggregation pool */ + /* Fill the per-aggregtion pool */ for (i = 0; i < max_agg_queues; i++) { - fp->tpa_pool[i].skb = - netdev_alloc_skb(bp->dev, fp->rx_buf_size); - if (!fp->tpa_pool[i].skb) { + struct bnx2x_agg_info *tpa_info = + &fp->tpa_info[i]; + struct sw_rx_bd *first_buf = + &tpa_info->first_buf; + + first_buf->skb = netdev_alloc_skb(bp->dev, + fp->rx_buf_size); + if (!first_buf->skb) { BNX2X_ERR("Failed to allocate TPA " "skb pool for queue[%d] - " "disabling TPA on this " @@ -951,10 +995,8 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) fp->disable_tpa = 1; break; } - dma_unmap_addr_set((struct sw_rx_bd *) - &bp->fp->tpa_pool[i], - mapping, 0); - fp->tpa_state[i] = BNX2X_TPA_STOP; + dma_unmap_addr_set(first_buf, mapping, 0); + tpa_info->tpa_state = BNX2X_TPA_STOP; } /* "next page" elements initialization */ @@ -970,13 +1012,13 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { BNX2X_ERR("was only able to allocate " "%d rx sges\n", i); - BNX2X_ERR("disabling TPA for" - " queue[%d]\n", j); + BNX2X_ERR("disabling TPA for " + "queue[%d]\n", j); /* Cleanup already allocated elements */ - bnx2x_free_rx_sge_range(bp, - fp, ring_prod); - bnx2x_free_tpa_pool(bp, - fp, max_agg_queues); + bnx2x_free_rx_sge_range(bp, fp, + ring_prod); + bnx2x_free_tpa_pool(bp, fp, + max_agg_queues); fp->disable_tpa = 1; ring_prod = 0; break; @@ -1004,7 +1046,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) if (j != 0) continue; - if (!CHIP_IS_E2(bp)) { + if (CHIP_IS_E1(bp)) { REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), U64_LO(fp->rx_comp_mapping)); @@ -1048,7 +1090,6 @@ static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp) if (skb == NULL) continue; - dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), fp->rx_buf_size, DMA_FROM_DEVICE); @@ -1070,7 +1111,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp) if (!fp->disable_tpa) bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : - ETH_MAX_AGGREGATION_QUEUES_E1H); + ETH_MAX_AGGREGATION_QUEUES_E1H_E2); } } @@ -1234,7 +1275,6 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) } offset++; - fp->state = BNX2X_FP_STATE_IRQ; } i = BNX2X_NUM_ETH_QUEUES(bp); @@ -1274,25 +1314,46 @@ static int bnx2x_req_irq(struct bnx2x *bp) rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags, bp->dev->name, bp->dev); - if (!rc) - bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ; - return rc; } -static void bnx2x_napi_enable(struct bnx2x *bp) +static inline int bnx2x_setup_irqs(struct bnx2x *bp) +{ + int rc = 0; + if (bp->flags & USING_MSIX_FLAG) { + rc = bnx2x_req_msix_irqs(bp); + if (rc) + return rc; + } else { + bnx2x_ack_int(bp); + rc = bnx2x_req_irq(bp); + if (rc) { + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); + return rc; + } + if (bp->flags & USING_MSI_FLAG) { + bp->dev->irq = bp->pdev->irq; + netdev_info(bp->dev, "using MSI IRQ %d\n", + bp->pdev->irq); + } + } + + return 0; +} + +static inline void bnx2x_napi_enable(struct bnx2x *bp) { int i; - for_each_napi_queue(bp, i) + for_each_rx_queue(bp, i) napi_enable(&bnx2x_fp(bp, i, napi)); } -static void bnx2x_napi_disable(struct bnx2x *bp) +static inline void bnx2x_napi_disable(struct bnx2x *bp) { int i; - for_each_napi_queue(bp, i) + for_each_rx_queue(bp, i) napi_disable(&bnx2x_fp(bp, i, napi)); } @@ -1310,7 +1371,6 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) { bnx2x_int_disable_sync(bp, disable_hw); bnx2x_napi_disable(bp); - netif_tx_disable(bp->dev); } u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) @@ -1361,26 +1421,6 @@ void bnx2x_set_num_queues(struct bnx2x *bp) bp->num_queues += NONE_ETH_CONTEXT_USE; } -#ifdef BCM_CNIC -static inline void bnx2x_set_fcoe_eth_macs(struct bnx2x *bp) -{ - if (!NO_FCOE(bp)) { - if (!IS_MF_SD(bp)) - bnx2x_set_fip_eth_mac_addr(bp, 1); - bnx2x_set_all_enode_macs(bp, 1); - bp->flags |= FCOE_MACS_SET; - } -} -#endif - -static void bnx2x_release_firmware(struct bnx2x *bp) -{ - kfree(bp->init_ops_offsets); - kfree(bp->init_ops); - kfree(bp->init_data); - release_firmware(bp->firmware); -} - static inline int bnx2x_set_real_num_queues(struct bnx2x *bp) { int rc, num = bp->num_queues; @@ -1412,27 +1452,198 @@ static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) */ fp->rx_buf_size = BNX2X_FCOE_MINI_JUMBO_MTU + ETH_OVREHEAD + - BNX2X_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; + BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; else fp->rx_buf_size = - bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + - IP_HEADER_ALIGNMENT_PADDING; + bp->dev->mtu + ETH_OVREHEAD + + BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; } } +static inline int bnx2x_init_rss_pf(struct bnx2x *bp) +{ + int i; + u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0}; + u8 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp); + + /* + * Prepare the inital contents fo the indirection table if RSS is + * enabled + */ + if (bp->multi_mode != ETH_RSS_MODE_DISABLED) { + for (i = 0; i < sizeof(ind_table); i++) + ind_table[i] = + bp->fp->cl_id + (i % num_eth_queues); + } + + /* + * For 57710 and 57711 SEARCHER configuration (rss_keys) is + * per-port, so if explicit configuration is needed , do it only + * for a PMF. + * + * For 57712 and newer on the other hand it's a per-function + * configuration. + */ + return bnx2x_config_rss_pf(bp, ind_table, + bp->port.pmf || !CHIP_IS_E1x(bp)); +} + +int bnx2x_config_rss_pf(struct bnx2x *bp, u8 *ind_table, bool config_hash) +{ + struct bnx2x_config_rss_params params = {0}; + int i; + + /* Although RSS is meaningless when there is a single HW queue we + * still need it enabled in order to have HW Rx hash generated. + * + * if (!is_eth_multi(bp)) + * bp->multi_mode = ETH_RSS_MODE_DISABLED; + */ + + params.rss_obj = &bp->rss_conf_obj; + + __set_bit(RAMROD_COMP_WAIT, ¶ms.ramrod_flags); + + /* RSS mode */ + switch (bp->multi_mode) { + case ETH_RSS_MODE_DISABLED: + __set_bit(BNX2X_RSS_MODE_DISABLED, ¶ms.rss_flags); + break; + case ETH_RSS_MODE_REGULAR: + __set_bit(BNX2X_RSS_MODE_REGULAR, ¶ms.rss_flags); + break; + case ETH_RSS_MODE_VLAN_PRI: + __set_bit(BNX2X_RSS_MODE_VLAN_PRI, ¶ms.rss_flags); + break; + case ETH_RSS_MODE_E1HOV_PRI: + __set_bit(BNX2X_RSS_MODE_E1HOV_PRI, ¶ms.rss_flags); + break; + case ETH_RSS_MODE_IP_DSCP: + __set_bit(BNX2X_RSS_MODE_IP_DSCP, ¶ms.rss_flags); + break; + default: + BNX2X_ERR("Unknown multi_mode: %d\n", bp->multi_mode); + return -EINVAL; + } + + /* If RSS is enabled */ + if (bp->multi_mode != ETH_RSS_MODE_DISABLED) { + /* RSS configuration */ + __set_bit(BNX2X_RSS_IPV4, ¶ms.rss_flags); + __set_bit(BNX2X_RSS_IPV4_TCP, ¶ms.rss_flags); + __set_bit(BNX2X_RSS_IPV6, ¶ms.rss_flags); + __set_bit(BNX2X_RSS_IPV6_TCP, ¶ms.rss_flags); + + /* Hash bits */ + params.rss_result_mask = MULTI_MASK; + + memcpy(params.ind_table, ind_table, sizeof(params.ind_table)); + + if (config_hash) { + /* RSS keys */ + for (i = 0; i < sizeof(params.rss_key) / 4; i++) + params.rss_key[i] = random32(); + + __set_bit(BNX2X_RSS_SET_SRCH, ¶ms.rss_flags); + } + } + + return bnx2x_config_rss(bp, ¶ms); +} + +static inline int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) +{ + struct bnx2x_func_state_params func_params = {0}; + + /* Prepare parameters for function state transitions */ + __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); + + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_HW_INIT; + + func_params.params.hw_init.load_phase = load_code; + + return bnx2x_func_state_change(bp, &func_params); +} + +/* + * Cleans the object that have internal lists without sending + * ramrods. Should be run when interrutps are disabled. + */ +static void bnx2x_squeeze_objects(struct bnx2x *bp) +{ + int rc; + unsigned long ramrod_flags = 0, vlan_mac_flags = 0; + struct bnx2x_mcast_ramrod_params rparam = {0}; + struct bnx2x_vlan_mac_obj *mac_obj = &bp->fp->mac_obj; + + /***************** Cleanup MACs' object first *************************/ + + /* Wait for completion of requested */ + __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); + /* Perform a dry cleanup */ + __set_bit(RAMROD_DRV_CLR_ONLY, &ramrod_flags); + + /* Clean ETH primary MAC */ + __set_bit(BNX2X_ETH_MAC, &vlan_mac_flags); + rc = mac_obj->delete_all(bp, &bp->fp->mac_obj, &vlan_mac_flags, + &ramrod_flags); + if (rc != 0) + BNX2X_ERR("Failed to clean ETH MACs: %d\n", rc); + + /* Cleanup UC list */ + vlan_mac_flags = 0; + __set_bit(BNX2X_UC_LIST_MAC, &vlan_mac_flags); + rc = mac_obj->delete_all(bp, mac_obj, &vlan_mac_flags, + &ramrod_flags); + if (rc != 0) + BNX2X_ERR("Failed to clean UC list MACs: %d\n", rc); + + /***************** Now clean mcast object *****************************/ + rparam.mcast_obj = &bp->mcast_obj; + __set_bit(RAMROD_DRV_CLR_ONLY, &rparam.ramrod_flags); + + /* Add a DEL command... */ + rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL); + if (rc < 0) + BNX2X_ERR("Failed to add a new DEL command to a multi-cast " + "object: %d\n", rc); + + /* ...and wait until all pending commands are cleared */ + rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_CONT); + while (rc != 0) { + if (rc < 0) { + BNX2X_ERR("Failed to clean multi-cast object: %d\n", + rc); + return; + } + + rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_CONT); + } +} + +#ifndef BNX2X_STOP_ON_ERROR +#define LOAD_ERROR_EXIT(bp, label) \ + do { \ + (bp)->state = BNX2X_STATE_ERROR; \ + goto label; \ + } while (0) +#else +#define LOAD_ERROR_EXIT(bp, label) \ + do { \ + (bp)->state = BNX2X_STATE_ERROR; \ + (bp)->panic = 1; \ + return -EBUSY; \ + } while (0) +#endif + /* must be called with rtnl_lock */ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { + int port = BP_PORT(bp); u32 load_code; int i, rc; - /* Set init arrays */ - rc = bnx2x_init_firmware(bp); - if (rc) { - BNX2X_ERR("Error loading firmware\n"); - return rc; - } - #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) return -EPERM; @@ -1459,6 +1670,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Set the receive queues buffer size */ bnx2x_set_rx_buf_size(bp); + /* + * set the tpa flag for each queue. The tpa flag determines the queue + * minimal size so it must be set prior to queue memory allocation + */ for_each_queue(bp, i) bnx2x_fp(bp, i, disable_tpa) = ((bp->flags & TPA_ENABLE_FLAG) == 0); @@ -1478,31 +1693,30 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_set_real_num_queues(bp); if (rc) { BNX2X_ERR("Unable to set real_num_queues\n"); - goto load_error0; + LOAD_ERROR_EXIT(bp, load_error0); } bnx2x_napi_enable(bp); /* Send LOAD_REQUEST command to MCP - Returns the type of LOAD command: - if it is the first port to be initialized - common blocks should be initialized, otherwise - not - */ + * Returns the type of LOAD command: + * if it is the first port to be initialized + * common blocks should be initialized, otherwise - not + */ if (!BP_NOMCP(bp)) { load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; - goto load_error1; + LOAD_ERROR_EXIT(bp, load_error1); } if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { rc = -EBUSY; /* other port in diagnostic mode */ - goto load_error1; + LOAD_ERROR_EXIT(bp, load_error1); } } else { int path = BP_PATH(bp); - int port = BP_PORT(bp); DP(NETIF_MSG_IFUP, "NO MCP - load counts[%d] %d, %d, %d\n", path, load_count[path][0], load_count[path][1], @@ -1528,30 +1742,45 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->port.pmf = 0; DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); + /* Init Function state controlling object */ + bnx2x__init_func_obj(bp); + /* Initialize HW */ rc = bnx2x_init_hw(bp, load_code); if (rc) { BNX2X_ERR("HW init failed, aborting\n"); bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); - goto load_error2; + LOAD_ERROR_EXIT(bp, load_error2); } /* Connect to IRQs */ rc = bnx2x_setup_irqs(bp); if (rc) { bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); - goto load_error2; + LOAD_ERROR_EXIT(bp, load_error2); } /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp, load_code); + /* Init per-function objects */ + bnx2x_init_bp_objs(bp); + if (((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP)) && - (bp->common.shmem2_base)) - SHMEM2_WR(bp, dcc_support, - (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV | - SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV)); + (bp->common.shmem2_base)) { + if (SHMEM2_HAS(bp, dcc_support)) + SHMEM2_WR(bp, dcc_support, + (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV | + SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV)); + } + + bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; + rc = bnx2x_func_start(bp); + if (rc) { + BNX2X_ERR("Function start failed!\n"); + LOAD_ERROR_EXIT(bp, load_error3); + } /* Send LOAD_DONE command to MCP */ if (!BP_NOMCP(bp)) { @@ -1559,74 +1788,38 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; - goto load_error3; + LOAD_ERROR_EXIT(bp, load_error3); } } - bnx2x_dcbx_init(bp); - - bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - - rc = bnx2x_func_start(bp); - if (rc) { - BNX2X_ERR("Function start failed!\n"); -#ifndef BNX2X_STOP_ON_ERROR - goto load_error3; -#else - bp->panic = 1; - return -EBUSY; -#endif - } - - rc = bnx2x_setup_client(bp, &bp->fp[0], 1 /* Leading */); + rc = bnx2x_setup_leading(bp); if (rc) { BNX2X_ERR("Setup leading failed!\n"); -#ifndef BNX2X_STOP_ON_ERROR - goto load_error3; -#else - bp->panic = 1; - return -EBUSY; -#endif - } - - if (!CHIP_IS_E1(bp) && - (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED)) { - DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; + LOAD_ERROR_EXIT(bp, load_error3); } #ifdef BCM_CNIC /* Enable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 1); #endif for_each_nondefault_queue(bp, i) { - rc = bnx2x_setup_client(bp, &bp->fp[i], 0); + rc = bnx2x_setup_queue(bp, &bp->fp[i], 0); if (rc) -#ifdef BCM_CNIC - goto load_error4; -#else - goto load_error3; -#endif + LOAD_ERROR_EXIT(bp, load_error4); } + rc = bnx2x_init_rss_pf(bp); + if (rc) + LOAD_ERROR_EXIT(bp, load_error4); + /* Now when Clients are configured we are ready to work */ bp->state = BNX2X_STATE_OPEN; -#ifdef BCM_CNIC - bnx2x_set_fcoe_eth_macs(bp); -#endif - - bnx2x_set_eth_mac(bp, 1); - - /* Clear MC configuration */ - if (CHIP_IS_E1(bp)) - bnx2x_invalidate_e1_mc_list(bp); - else - bnx2x_invalidate_e1h_mc_list(bp); - - /* Clear UC lists configuration */ - bnx2x_invalidate_uc_list(bp); + /* Configure a ucast MAC */ + rc = bnx2x_set_eth_mac(bp, true); + if (rc) + LOAD_ERROR_EXIT(bp, load_error4); if (bp->pending_max) { bnx2x_update_max_mf_config(bp, bp->pending_max); @@ -1636,15 +1829,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); - /* Initialize Rx filtering */ + /* Start fast path */ + + /* Initialize Rx filter. */ + netif_addr_lock_bh(bp->dev); bnx2x_set_rx_mode(bp->dev); + netif_addr_unlock_bh(bp->dev); - /* Start fast path */ + /* Start the Tx */ switch (load_mode) { case LOAD_NORMAL: /* Tx queue should be only reenabled */ netif_tx_wake_all_queues(bp->dev); - /* Initialize the receive filter. */ break; case LOAD_OPEN: @@ -1673,18 +1869,28 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif bnx2x_inc_load_cnt(bp); - bnx2x_release_firmware(bp); + /* Wait for all pending SP commands to complete */ + if (!bnx2x_wait_sp_comp(bp, ~0x0UL)) { + BNX2X_ERR("Timeout waiting for SP elements to complete\n"); + bnx2x_nic_unload(bp, UNLOAD_CLOSE); + return -EBUSY; + } + bnx2x_dcbx_init(bp); return 0; -#ifdef BCM_CNIC +#ifndef BNX2X_STOP_ON_ERROR load_error4: +#ifdef BCM_CNIC /* Disable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 0); + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0); #endif load_error3: bnx2x_int_disable_sync(bp, 1); + /* Clean queueable objects */ + bnx2x_squeeze_objects(bp); + /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); for_each_rx_queue(bp, i) @@ -1704,9 +1910,8 @@ load_error1: load_error0: bnx2x_free_mem(bp); - bnx2x_release_firmware(bp); - return rc; +#endif /* ! BNX2X_STOP_ON_ERROR */ } /* must be called with rtnl_lock */ @@ -1728,18 +1933,19 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); #endif bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; + smp_mb(); - /* Set "drop all" */ bp->rx_mode = BNX2X_RX_MODE_NONE; - bnx2x_set_storm_rx_mode(bp); /* Stop Tx */ bnx2x_tx_disable(bp); del_timer_sync(&bp->timer); - SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb, - (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); + /* Set ALWAYS_ALIVE bit in shmem */ + bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; + + bnx2x_drv_pulse(bp); bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -1754,6 +1960,12 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_free_irq(bp); } + /* + * At this stage no more interrupts will arrive so we may safly clean + * the queueable objects here in case they failed to get cleaned so far. + */ + bnx2x_squeeze_objects(bp); + bp->port.pmf = 0; /* Free SKBs, SGEs, TPA pool and driver internals */ @@ -2154,7 +2366,6 @@ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, static inline void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb, struct eth_tx_start_bd *tx_start_bd, u32 xmit_type) { - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; if (xmit_type & XMIT_CSUM_V4) @@ -2166,7 +2377,6 @@ static inline void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb, if (!(xmit_type & XMIT_CSUM_TCP)) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IS_UDP; - } /** @@ -2234,7 +2444,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct bnx2x_fastpath *fp; struct netdev_queue *txq; struct sw_tx_bd *tx_buf; - struct eth_tx_start_bd *tx_start_bd; + struct eth_tx_start_bd *tx_start_bd, *first_bd; struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; @@ -2296,7 +2506,15 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) } } #endif - + /* Map skb linear data for DMA */ + mapping = dma_map_single(&bp->pdev->dev, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + DP(NETIF_MSG_TX_QUEUED, "SKB mapping failed - " + "silently dropping this SKB\n"); + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } /* Please read carefully. First we use one BD which we mark as start, then we have a parsing info BD (used for TSO or xsum), @@ -2306,12 +2524,19 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) And above all, all pdb sizes are in words - NOT DWORDS! */ - pkt_prod = fp->tx_pkt_prod++; + /* get current pkt produced now - advance it just before sending packet + * since mapping of pages may fail and cause packet to be dropped + */ + pkt_prod = fp->tx_pkt_prod; bd_prod = TX_BD(fp->tx_bd_prod); - /* get a tx_buf and first BD */ + /* get a tx_buf and first BD + * tx_start_bd may be changed during SPLIT, + * but first_bd will always stay first + */ tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)]; tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; + first_bd = tx_start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_ETH_ADDR_TYPE, @@ -2343,7 +2568,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (xmit_type & XMIT_CSUM) bnx2x_set_sbd_csum(bp, skb, tx_start_bd, xmit_type); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { pbd_e2 = &fp->tx_desc_ring[bd_prod].parse_bd_e2; memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); /* Set PBD in checksum offload case */ @@ -2351,6 +2576,20 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) hlen = bnx2x_set_pbd_csum_e2(bp, skb, &pbd_e2_parsing_data, xmit_type); + if (IS_MF_SI(bp)) { + /* + * fill in the MAC addresses in the PBD - for local + * switching + */ + bnx2x_set_fw_mac_addr(&pbd_e2->src_mac_addr_hi, + &pbd_e2->src_mac_addr_mid, + &pbd_e2->src_mac_addr_lo, + eth->h_source); + bnx2x_set_fw_mac_addr(&pbd_e2->dst_mac_addr_hi, + &pbd_e2->dst_mac_addr_mid, + &pbd_e2->dst_mac_addr_lo, + eth->h_dest); + } } else { pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); @@ -2360,15 +2599,10 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) } - /* Map skb linear data for DMA */ - mapping = dma_map_single(&bp->pdev->dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); - /* Setup the data pointer of the first BD of the packet */ tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */ - tx_start_bd->nbd = cpu_to_le16(nbd); + nbd = 2; /* start_bd + pbd + frags (updated when pages are mapped) */ tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); pkt_size = tx_start_bd->nbytes; @@ -2391,7 +2625,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(skb_headlen(skb) > hlen)) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, xmit_type); else @@ -2410,19 +2644,34 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + mapping = dma_map_page(&bp->pdev->dev, frag->page, + frag->page_offset, frag->size, + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + + DP(NETIF_MSG_TX_QUEUED, "Unable to map page - " + "dropping packet...\n"); + + /* we need unmap all buffers already mapped + * for this SKB; + * first_bd->nbd need to be properly updated + * before call to bnx2x_free_tx_pkt + */ + first_bd->nbd = cpu_to_le16(nbd); + bnx2x_free_tx_pkt(bp, fp, TX_BD(fp->tx_pkt_prod)); + return NETDEV_TX_OK; + } + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); tx_data_bd = &fp->tx_desc_ring[bd_prod].reg_bd; if (total_pkt_bd == NULL) total_pkt_bd = &fp->tx_desc_ring[bd_prod].reg_bd; - mapping = dma_map_page(&bp->pdev->dev, frag->page, - frag->page_offset, - frag->size, DMA_TO_DEVICE); - tx_data_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_data_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); tx_data_bd->nbytes = cpu_to_le16(frag->size); le16_add_cpu(&pkt_size, frag->size); + nbd++; DP(NETIF_MSG_TX_QUEUED, "frag %d bd @%p addr (%x:%x) nbytes %d\n", @@ -2432,6 +2681,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) DP(NETIF_MSG_TX_QUEUED, "last bd @%p\n", tx_data_bd); + /* update with actual num BDs */ + first_bd->nbd = cpu_to_le16(nbd); + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); /* now send a tx doorbell, counting the next BD @@ -2440,6 +2692,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (TX_BD_POFF(bd_prod) < nbd) nbd++; + /* total_pkt_bytes should be set on the first data BD if + * it's not an LSO packet and there is more than one + * data BD. In this case pkt_size is limited by an MTU value. + * However we prefer to set it for an LSO packet (while we don't + * have to) in order to save some CPU cycles in a none-LSO + * case, when we much more care about them. + */ if (total_pkt_bd != NULL) total_pkt_bd->total_pkt_bytes = pkt_size; @@ -2460,6 +2719,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) pbd_e2->parsing_data); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); + fp->tx_pkt_prod++; /* * Make sure that the BD data is updated before updating the producer * since FW might read the BD right after the producer is updated. @@ -2500,15 +2760,23 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; struct bnx2x *bp = netdev_priv(dev); + int rc = 0; if (!is_valid_ether_addr((u8 *)(addr->sa_data))) return -EINVAL; + if (netif_running(dev)) { + rc = bnx2x_set_eth_mac(bp, false); + if (rc) + return rc; + } + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + if (netif_running(dev)) - bnx2x_set_eth_mac(bp, 1); + rc = bnx2x_set_eth_mac(bp, true); - return 0; + return rc; } static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) @@ -2525,7 +2793,7 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) } else { #endif /* status blocks */ - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) BNX2X_PCI_FREE(sb->e2_sb, bnx2x_fp(bp, fp_index, status_blk_mapping), @@ -2581,7 +2849,7 @@ void bnx2x_free_fp_mem(struct bnx2x *bp) static inline void set_sb_shortcuts(struct bnx2x *bp, int index) { union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { bnx2x_fp(bp, index, sb_index_values) = (__le16 *)status_blk.e2_sb->sb.index_values; bnx2x_fp(bp, index, sb_running_index) = @@ -2618,7 +2886,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) if (!IS_FCOE_IDX(index)) { #endif /* status blocks */ - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) BNX2X_PCI_ALLOC(sb->e2_sb, &bnx2x_fp(bp, index, status_blk_mapping), sizeof(struct host_hc_status_block_e2)); @@ -2747,30 +3015,6 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) return 0; } -static int bnx2x_setup_irqs(struct bnx2x *bp) -{ - int rc = 0; - if (bp->flags & USING_MSIX_FLAG) { - rc = bnx2x_req_msix_irqs(bp); - if (rc) - return rc; - } else { - bnx2x_ack_int(bp); - rc = bnx2x_req_irq(bp); - if (rc) { - BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); - return rc; - } - if (bp->flags & USING_MSI_FLAG) { - bp->dev->irq = bp->pdev->irq; - netdev_info(bp->dev, "using MSI IRQ %d\n", - bp->pdev->irq); - } - } - - return 0; -} - void bnx2x_free_mem_bp(struct bnx2x *bp) { kfree(bp->fp); @@ -3021,3 +3265,57 @@ int bnx2x_resume(struct pci_dev *pdev) return rc; } + + +void bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt, + u32 cid) +{ + /* ustorm cxt validation */ + cxt->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, cid), + CDU_REGION_NUMBER_UCM_AG, ETH_CONNECTION_TYPE); + /* xcontext validation */ + cxt->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, cid), + CDU_REGION_NUMBER_XCM_AG, ETH_CONNECTION_TYPE); +} + +static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port, + u8 fw_sb_id, u8 sb_index, + u8 ticks) +{ + + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_TIMEOUT_OFFSET(fw_sb_id, sb_index); + REG_WR8(bp, addr, ticks); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d ticks %d\n", + port, fw_sb_id, sb_index, ticks); +} + +static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port, + u16 fw_sb_id, u8 sb_index, + u8 disable) +{ + u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(fw_sb_id, sb_index); + u16 flags = REG_RD16(bp, addr); + /* clear and set */ + flags &= ~HC_INDEX_DATA_HC_ENABLED; + flags |= enable_flag; + REG_WR16(bp, addr, flags); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d disable %d\n", + port, fw_sb_id, sb_index, disable); +} + +void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u8 fw_sb_id, + u8 sb_index, u8 disable, u16 usec) +{ + int port = BP_PORT(bp); + u8 ticks = usec / BNX2X_BTR; + + storm_memset_hc_timeout(bp, port, fw_sb_id, sb_index, ticks); + + disable = disable ? 1 : (usec ? 0 : 1); + storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable); +} diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 5a97f92b340..944bcaeeba4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -18,11 +18,15 @@ #define BNX2X_CMN_H #include +#include #include #include "bnx2x.h" +/* This is used as a replacement for an MCP if it's not present */ +extern int load_count[2][3]; /* per-path: 0-common, 1-port0, 2-port1 */ + extern int num_queues; /************************ Macros ********************************/ @@ -61,6 +65,73 @@ extern int num_queues; /*********************** Interfaces **************************** * Functions that need to be implemented by each driver version */ +/* Init */ + +/** + * bnx2x_send_unload_req - request unload mode from the MCP. + * + * @bp: driver handle + * @unload_mode: requested function's unload mode + * + * Return unload mode returned by the MCP: COMMON, PORT or FUNC. + */ +u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode); + +/** + * bnx2x_send_unload_done - send UNLOAD_DONE command to the MCP. + * + * @bp: driver handle + */ +void bnx2x_send_unload_done(struct bnx2x *bp); + +/** + * bnx2x_config_rss_pf - configure RSS parameters. + * + * @bp: driver handle + * @ind_table: indirection table to configure + * @config_hash: re-configure RSS hash keys configuration + */ +int bnx2x_config_rss_pf(struct bnx2x *bp, u8 *ind_table, bool config_hash); + +/** + * bnx2x__init_func_obj - init function object + * + * @bp: driver handle + * + * Initializes the Function Object with the appropriate + * parameters which include a function slow path driver + * interface. + */ +void bnx2x__init_func_obj(struct bnx2x *bp); + +/** + * bnx2x_setup_queue - setup eth queue. + * + * @bp: driver handle + * @fp: pointer to the fastpath structure + * @leading: boolean + * + */ +int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, + bool leading); + +/** + * bnx2x_setup_leading - bring up a leading eth queue. + * + * @bp: driver handle + */ +int bnx2x_setup_leading(struct bnx2x *bp); + +/** + * bnx2x_fw_command - send the MCP a request + * + * @bp: driver handle + * @command: request + * @param: request's parameter + * + * block until there is a reply + */ +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); /** * bnx2x_initial_phy_init - initialize link parameters structure variables. @@ -87,6 +158,29 @@ void bnx2x_link_set(struct bnx2x *bp); */ u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes); +/** + * bnx2x_drv_pulse - write driver pulse to shmem + * + * @bp: driver handle + * + * writes the value in bp->fw_drv_pulse_wr_seq to drv_pulse mbox + * in the shmem. + */ +void bnx2x_drv_pulse(struct bnx2x *bp); + +/** + * bnx2x_igu_ack_sb - update IGU with current SB value + * + * @bp: driver handle + * @igu_sb_id: SB id + * @segment: SB segment + * @index: SB index + * @op: SB operation + * @update: is HW update required + */ +void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, + u16 index, u8 op, u8 update); + /** * bnx2x__link_status_update - handles link status change. * @@ -164,21 +258,6 @@ void bnx2x_int_enable(struct bnx2x *bp); */ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); -/** - * bnx2x_init_firmware - loads device firmware - * - * @bp: driver handle - */ -int bnx2x_init_firmware(struct bnx2x *bp); - -/** - * bnx2x_init_hw - init HW blocks according to current initialization stage. - * - * @bp: driver handle - * @load_code: COMMON, PORT or FUNCTION - */ -int bnx2x_init_hw(struct bnx2x *bp, u32 load_code); - /** * bnx2x_nic_init - init driver internals. * @@ -206,16 +285,6 @@ int bnx2x_alloc_mem(struct bnx2x *bp); */ void bnx2x_free_mem(struct bnx2x *bp); -/** - * bnx2x_setup_client - setup eth client. - * - * @bp: driver handle - * @fp: pointer to fastpath structure - * @is_leading: boolean - */ -int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, - int is_leading); - /** * bnx2x_set_num_queues - set number of queues according to mode. * @@ -259,38 +328,44 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); * * Configures according to the value in netdev->dev_addr. */ -void bnx2x_set_eth_mac(struct bnx2x *bp, int set); +int bnx2x_set_eth_mac(struct bnx2x *bp, bool set); -#ifdef BCM_CNIC /** - * bnx2x_set_fip_eth_mac_addr - Set/Clear FIP MAC(s) + * bnx2x_set_rx_mode - set MAC filtering configurations. * - * @bp: driver handle - * @set: set or clear the CAM entry + * @dev: netdevice * - * Used next enties in the CAM after the ETH MAC(s). - * This function will wait until the ramdord completion returns. - * Return 0 if cussess, -ENODEV if ramrod doesn't return. + * called with netif_tx_lock from dev_mcast.c + * If bp->state is OPEN, should be called with + * netif_addr_lock_bh() */ -int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set); +void bnx2x_set_rx_mode(struct net_device *dev); /** - * bnx2x_set_all_enode_macs - Set/Clear ALL_ENODE mcast MAC. + * bnx2x_set_storm_rx_mode - configure MAC filtering rules in a FW. * * @bp: driver handle - * @set: set or clear + * + * If bp->state is OPEN, should be called with + * netif_addr_lock_bh(). */ -int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set); -#endif +void bnx2x_set_storm_rx_mode(struct bnx2x *bp); /** - * bnx2x_set_rx_mode - set MAC filtering configurations. - * - * @dev: netdevice + * bnx2x_set_q_rx_mode - configures rx_mode for a single queue. * - * called with netif_tx_lock from dev_mcast.c + * @bp: driver handle + * @cl_id: client id + * @rx_mode_flags: rx mode configuration + * @rx_accept_flags: rx accept configuration + * @tx_accept_flags: tx accept configuration (tx switch) + * @ramrod_flags: ramrod configuration */ -void bnx2x_set_rx_mode(struct net_device *dev); +void bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, + unsigned long rx_mode_flags, + unsigned long rx_accept_flags, + unsigned long tx_accept_flags, + unsigned long ramrod_flags); /* Parity errors related */ void bnx2x_inc_load_cnt(struct bnx2x *bp); @@ -299,14 +374,6 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp); bool bnx2x_reset_is_done(struct bnx2x *bp); void bnx2x_disable_close_the_gate(struct bnx2x *bp); -/** - * bnx2x_stats_handle - perform statistics handling according to event. - * - * @bp: driver handle - * @event: bnx2x_stats_event - */ -void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); - /** * bnx2x_sp_event - handle ramrods completion. * @@ -315,15 +382,6 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); */ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); -/** - * bnx2x_func_start - init function - * - * @bp: driver handle - * - * Must be called before sending CLIENT_SETUP for the first client. - */ -int bnx2x_func_start(struct bnx2x *bp); - /** * bnx2x_ilt_set_info - prepare ILT configurations. * @@ -355,6 +413,8 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); * @value: new value */ void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value); +/* Error handling */ +void bnx2x_panic_dump(struct bnx2x *bp); void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl); @@ -378,6 +438,9 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p); /* NAPI poll Rx part */ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); +void bnx2x_update_rx_prod(struct bnx2x *bp, struct bnx2x_fastpath *fp, + u16 bd_prod, u16 rx_comp_prod, u16 rx_sge_prod); + /* NAPI poll Tx part */ int bnx2x_tx_int(struct bnx2x_fastpath *fp); @@ -390,7 +453,6 @@ void bnx2x_free_irq(struct bnx2x *bp); void bnx2x_free_fp_mem(struct bnx2x *bp); int bnx2x_alloc_fp_mem(struct bnx2x *bp); - void bnx2x_init_rx_rings(struct bnx2x *bp); void bnx2x_free_skbs(struct bnx2x *bp); void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); @@ -455,19 +517,20 @@ int bnx2x_set_features(struct net_device *dev, u32 features); */ void bnx2x_tx_timeout(struct net_device *dev); +/*********************** Inlines **********************************/ +/*********************** Fast path ********************************/ static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { barrier(); /* status block is written to by the chip */ fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID]; } -static inline void bnx2x_update_rx_prod(struct bnx2x *bp, - struct bnx2x_fastpath *fp, - u16 bd_prod, u16 rx_comp_prod, - u16 rx_sge_prod) +static inline void bnx2x_update_rx_prod_gen(struct bnx2x *bp, + struct bnx2x_fastpath *fp, u16 bd_prod, + u16 rx_comp_prod, u16 rx_sge_prod, u32 start) { struct ustorm_eth_rx_producers rx_prods = {0}; - int i; + u32 i; /* Update producers */ rx_prods.bd_prod = bd_prod; @@ -484,10 +547,8 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, */ wmb(); - for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++) - REG_WR(bp, - BAR_USTRORM_INTMEM + fp->ustorm_rx_prods_offset + i*4, - ((u32 *)&rx_prods)[i]); + for (i = 0; i < sizeof(rx_prods)/4; i++) + REG_WR(bp, start + i*4, ((u32 *)&rx_prods)[i]); mmiowb(); /* keep prod updates ordered */ @@ -517,7 +578,7 @@ static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, barrier(); } -static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, +static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, bool is_Pf) { u32 data, ctl, cnt = 100; @@ -525,7 +586,7 @@ static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL; u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4; u32 sb_bit = 1 << (idu_sb_id%32); - u32 func_encode = BP_FUNC(bp) | + u32 func_encode = func | ((is_Pf == true ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT); u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id; @@ -588,15 +649,6 @@ static inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id, barrier(); } -static inline void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, - u16 index, u8 op, u8 update) -{ - u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8; - - bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update, - igu_addr); -} - static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm, u16 index, u8 op, u8 update) { @@ -703,7 +755,7 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) } /** - * disables tx from stack point of view + * bnx2x_tx_disable - disables tx from stack point of view * * @bp: driver handle */ @@ -738,7 +790,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) int i; /* Add NAPI objects */ - for_each_napi_queue(bp, i) + for_each_rx_queue(bp, i) netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), bnx2x_poll, BNX2X_NAPI_WEIGHT); } @@ -747,7 +799,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp) { int i; - for_each_napi_queue(bp, i) + for_each_rx_queue(bp, i) netif_napi_del(&bnx2x_fp(bp, i, napi)); } @@ -777,7 +829,7 @@ static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) int idx = RX_SGE_CNT * i - 1; for (j = 0; j < 2; j++) { - SGE_MASK_CLEAR_BIT(fp, idx); + BIT_VEC64_CLEAR_BIT(fp->sge_mask, idx); idx--; } } @@ -787,7 +839,7 @@ static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) { /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ memset(fp->sge_mask, 0xff, - (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); + (NUM_RX_SGE >> BIT_VEC64_ELEM_SHIFT)*sizeof(u64)); /* Clear the two last indices in the page to 1: these are the indices that correspond to the "next" element, @@ -869,12 +921,61 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, dma_unmap_addr(cons_rx_buf, mapping), RX_COPY_THRESH, DMA_FROM_DEVICE); - prod_rx_buf->skb = cons_rx_buf->skb; dma_unmap_addr_set(prod_rx_buf, mapping, dma_unmap_addr(cons_rx_buf, mapping)); + prod_rx_buf->skb = cons_rx_buf->skb; *prod_bd = *cons_bd; } +/************************* Init ******************************************/ + +/** + * bnx2x_func_start - init function + * + * @bp: driver handle + * + * Must be called before sending CLIENT_SETUP for the first client. + */ +static inline int bnx2x_func_start(struct bnx2x *bp) +{ + struct bnx2x_func_state_params func_params = {0}; + struct bnx2x_func_start_params *start_params = + &func_params.params.start; + + /* Prepare parameters for function state transitions */ + __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); + + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_START; + + /* Function parameters */ + start_params->mf_mode = bp->mf_mode; + start_params->sd_vlan_tag = bp->mf_ov; + start_params->network_cos_mode = OVERRIDE_COS; + + return bnx2x_func_state_change(bp, &func_params); +} + + +/** + * bnx2x_set_fw_mac_addr - fill in a MAC address in FW format + * + * @fw_hi: pointer to upper part + * @fw_mid: pointer to middle part + * @fw_lo: pointer to lower part + * @mac: pointer to MAC address + */ +static inline void bnx2x_set_fw_mac_addr(u16 *fw_hi, u16 *fw_mid, u16 *fw_lo, + u8 *mac) +{ + ((u8 *)fw_hi)[0] = mac[1]; + ((u8 *)fw_hi)[1] = mac[0]; + ((u8 *)fw_mid)[0] = mac[3]; + ((u8 *)fw_mid)[1] = mac[2]; + ((u8 *)fw_lo)[0] = mac[5]; + ((u8 *)fw_lo)[1] = mac[4]; +} + static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, struct bnx2x_fastpath *fp, int last) { @@ -893,21 +994,20 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, int i; for (i = 0; i < last; i++) { - struct sw_rx_bd *rx_buf = &(fp->tpa_pool[i]); - struct sk_buff *skb = rx_buf->skb; + struct bnx2x_agg_info *tpa_info = &fp->tpa_info[i]; + struct sw_rx_bd *first_buf = &tpa_info->first_buf; + struct sk_buff *skb = first_buf->skb; if (skb == NULL) { DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i); continue; } - - if (fp->tpa_state[i] == BNX2X_TPA_START) + if (tpa_info->tpa_state == BNX2X_TPA_START) dma_unmap_single(&bp->pdev->dev, - dma_unmap_addr(rx_buf, mapping), + dma_unmap_addr(first_buf, mapping), fp->rx_buf_size, DMA_FROM_DEVICE); - dev_kfree_skb(skb); - rx_buf->skb = NULL; + first_buf->skb = NULL; } } @@ -1036,31 +1136,199 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, return i - fp->eth_q_stats.rx_skb_alloc_failed; } +/* Statistics ID are global per chip/path, while Client IDs for E1x are per + * port. + */ +static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp) +{ + if (!CHIP_IS_E1x(fp->bp)) + return fp->cl_id; + else + return fp->cl_id + BP_PORT(fp->bp) * FP_SB_MAX_E1x; +} + +static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp, + bnx2x_obj_type obj_type) +{ + struct bnx2x *bp = fp->bp; + + /* Configure classification DBs */ + bnx2x_init_mac_obj(bp, &fp->mac_obj, fp->cl_id, fp->cid, + BP_FUNC(bp), bnx2x_sp(bp, mac_rdata), + bnx2x_sp_mapping(bp, mac_rdata), + BNX2X_FILTER_MAC_PENDING, + &bp->sp_state, obj_type, + &bp->macs_pool); +} + +/** + * bnx2x_get_path_func_num - get number of active functions + * + * @bp: driver handle + * + * Calculates the number of active (not hidden) functions on the + * current path. + */ +static inline u8 bnx2x_get_path_func_num(struct bnx2x *bp) +{ + u8 func_num = 0, i; + + /* 57710 has only one function per-port */ + if (CHIP_IS_E1(bp)) + return 1; + + /* Calculate a number of functions enabled on the current + * PATH/PORT. + */ + if (CHIP_REV_IS_SLOW(bp)) { + if (IS_MF(bp)) + func_num = 4; + else + func_num = 2; + } else { + for (i = 0; i < E1H_FUNC_MAX / 2; i++) { + u32 func_config = + MF_CFG_RD(bp, + func_mf_config[BP_PORT(bp) + 2 * i]. + config); + func_num += + ((func_config & FUNC_MF_CFG_FUNC_HIDE) ? 0 : 1); + } + } + + WARN_ON(!func_num); + + return func_num; +} + +static inline void bnx2x_init_bp_objs(struct bnx2x *bp) +{ + /* RX_MODE controlling object */ + bnx2x_init_rx_mode_obj(bp, &bp->rx_mode_obj); + + /* multicast configuration controlling object */ + bnx2x_init_mcast_obj(bp, &bp->mcast_obj, bp->fp->cl_id, bp->fp->cid, + BP_FUNC(bp), BP_FUNC(bp), + bnx2x_sp(bp, mcast_rdata), + bnx2x_sp_mapping(bp, mcast_rdata), + BNX2X_FILTER_MCAST_PENDING, &bp->sp_state, + BNX2X_OBJ_TYPE_RX); + + /* Setup CAM credit pools */ + bnx2x_init_mac_credit_pool(bp, &bp->macs_pool, BP_FUNC(bp), + bnx2x_get_path_func_num(bp)); + + /* RSS configuration object */ + bnx2x_init_rss_config_obj(bp, &bp->rss_conf_obj, bp->fp->cl_id, + bp->fp->cid, BP_FUNC(bp), BP_FUNC(bp), + bnx2x_sp(bp, rss_rdata), + bnx2x_sp_mapping(bp, rss_rdata), + BNX2X_FILTER_RSS_CONF_PENDING, &bp->sp_state, + BNX2X_OBJ_TYPE_RX); +} + +static inline u8 bnx2x_fp_qzone_id(struct bnx2x_fastpath *fp) +{ + if (CHIP_IS_E1x(fp->bp)) + return fp->cl_id + BP_PORT(fp->bp) * ETH_MAX_RX_CLIENTS_E1H; + else + return fp->cl_id; +} + +static inline u32 bnx2x_rx_ustorm_prods_offset(struct bnx2x_fastpath *fp) +{ + struct bnx2x *bp = fp->bp; + + if (!CHIP_IS_E1x(bp)) + return USTORM_RX_PRODS_E2_OFFSET(fp->cl_qzone_id); + else + return USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); +} + + #ifdef BCM_CNIC +static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx) +{ + return bp->cnic_base_cl_id + cl_idx + + (bp->pf_num >> 1) * NONE_ETH_CONTEXT_USE; +} + +static inline u8 bnx2x_cnic_fw_sb_id(struct bnx2x *bp) +{ + + /* the 'first' id is allocated for the cnic */ + return bp->base_fw_ndsb; +} + +static inline u8 bnx2x_cnic_igu_sb_id(struct bnx2x *bp) +{ + return bp->igu_base_sb; +} + + static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) { - bnx2x_fcoe(bp, cl_id) = BNX2X_FCOE_ETH_CL_ID + - BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; + struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); + unsigned long q_type = 0; + + bnx2x_fcoe(bp, cl_id) = bnx2x_cnic_eth_cl_id(bp, + BNX2X_FCOE_ETH_CL_ID_IDX); + /** Current BNX2X_FCOE_ETH_CID deffinition implies not more than + * 16 ETH clients per function when CNIC is enabled! + * + * Fix it ASAP!!! + */ bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID; bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; bnx2x_fcoe(bp, bp) = bp; - bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED; bnx2x_fcoe(bp, index) = FCOE_IDX; bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; bnx2x_fcoe(bp, tx_cons_sb) = BNX2X_FCOE_L2_TX_INDEX; /* qZone id equals to FW (per path) client id */ - bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fcoe(bp, cl_id) + - BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 : - ETH_MAX_RX_CLIENTS_E1H); + bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fp_qzone_id(fp); /* init shortcut */ - bnx2x_fcoe(bp, ustorm_rx_prods_offset) = CHIP_IS_E2(bp) ? - USTORM_RX_PRODS_E2_OFFSET(bnx2x_fcoe(bp, cl_qzone_id)) : - USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), bnx2x_fcoe_fp(bp)->cl_id); - + bnx2x_fcoe(bp, ustorm_rx_prods_offset) = + bnx2x_rx_ustorm_prods_offset(fp); + + /* Configure Queue State object */ + __set_bit(BNX2X_Q_TYPE_HAS_RX, &q_type); + __set_bit(BNX2X_Q_TYPE_HAS_TX, &q_type); + bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, fp->cid, BP_FUNC(bp), + bnx2x_sp(bp, q_rdata), bnx2x_sp_mapping(bp, q_rdata), + q_type); + + DP(NETIF_MSG_IFUP, "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d fw_sb %d " + "igu_sb %d\n", + fp->index, bp, fp->status_blk.e2_sb, fp->cl_id, fp->fw_sb_id, + fp->igu_sb_id); } #endif +static inline int bnx2x_clean_tx_queue(struct bnx2x *bp, + struct bnx2x_fastpath *fp) +{ + int cnt = 1000; + + while (bnx2x_has_tx_work_unload(fp)) { + if (!cnt) { + BNX2X_ERR("timeout waiting for queue[%d]: " + "fp->tx_pkt_prod(%d) != fp->tx_pkt_cons(%d)\n", + fp->index, fp->tx_pkt_prod, fp->tx_pkt_cons); +#ifdef BNX2X_STOP_ON_ERROR + bnx2x_panic(); + return -EBUSY; +#else + break; +#endif + } + cnt--; + usleep_range(1000, 1000); + } + + return 0; +} + int bnx2x_get_link_cfg_idx(struct bnx2x *bp); static inline void __storm_memset_struct(struct bnx2x *bp, @@ -1071,48 +1339,81 @@ static inline void __storm_memset_struct(struct bnx2x *bp, REG_WR(bp, addr + (i * 4), data[i]); } -static inline void storm_memset_mac_filters(struct bnx2x *bp, - struct tstorm_eth_mac_filter_config *mac_filters, - u16 abs_fid) +static inline void storm_memset_func_cfg(struct bnx2x *bp, + struct tstorm_eth_function_common_config *tcfg, + u16 abs_fid) { - size_t size = sizeof(struct tstorm_eth_mac_filter_config); + size_t size = sizeof(struct tstorm_eth_function_common_config); u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_MAC_FILTER_CONFIG_OFFSET(abs_fid); + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); - __storm_memset_struct(bp, addr, size, (u32 *)mac_filters); + __storm_memset_struct(bp, addr, size, (u32 *)tcfg); } static inline void storm_memset_cmng(struct bnx2x *bp, struct cmng_struct_per_port *cmng, u8 port) { - size_t size = - sizeof(struct rate_shaping_vars_per_port) + - sizeof(struct fairness_vars_per_port) + - sizeof(struct safc_struct_per_port) + - sizeof(struct pfc_struct_per_port); + size_t size = sizeof(struct cmng_struct_per_port); u32 addr = BAR_XSTRORM_INTMEM + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port); __storm_memset_struct(bp, addr, size, (u32 *)cmng); +} + +/** + * bnx2x_wait_sp_comp - wait for the outstanding SP commands. + * + * @bp: driver handle + * @mask: bits that need to be cleared + */ +static inline bool bnx2x_wait_sp_comp(struct bnx2x *bp, unsigned long mask) +{ + int tout = 5000; /* Wait for 5 secs tops */ + + while (tout--) { + smp_mb(); + netif_addr_lock_bh(bp->dev); + if (!(bp->sp_state & mask)) { + netif_addr_unlock_bh(bp->dev); + return true; + } + netif_addr_unlock_bh(bp->dev); - addr += size + 4 /* SKIP DCB+LLFC */; - size = sizeof(struct cmng_struct_per_port) - - size /* written */ - 4 /*skipped*/; + usleep_range(1000, 1000); + } + + smp_mb(); + + netif_addr_lock_bh(bp->dev); + if (bp->sp_state & mask) { + BNX2X_ERR("Filtering completion timed out. sp_state 0x%lx, " + "mask 0x%lx\n", bp->sp_state, mask); + netif_addr_unlock_bh(bp->dev); + return false; + } + netif_addr_unlock_bh(bp->dev); - __storm_memset_struct(bp, addr, size, - (u32 *)(cmng->traffic_type_to_priority_cos)); + return true; } -/* HW Lock for shared dual port PHYs */ +/** + * bnx2x_set_ctx_validation - set CDU context validation values + * + * @bp: driver handle + * @cxt: context of the connection on the host memory + * @cid: SW CID of the connection to be configured + */ +void bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt, + u32 cid); + +void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u8 fw_sb_id, + u8 sb_index, u8 disable, u16 usec); void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); -void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, - u8 sb_index, u8 disable, u16 usec); - /** * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration. * diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 410a49e571a..aaed9f09c32 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -55,15 +55,14 @@ static void bnx2x_pfc_set(struct bnx2x *bp) struct bnx2x_nig_brb_pfc_port_params pfc_params = {0}; u32 pri_bit, val = 0; u8 pri; + int i; /* Tx COS configuration */ - if (bp->dcbx_port_params.ets.cos_params[0].pauseable) - pfc_params.rx_cos0_priority_mask = - bp->dcbx_port_params.ets.cos_params[0].pri_bitmask; - if (bp->dcbx_port_params.ets.cos_params[1].pauseable) - pfc_params.rx_cos1_priority_mask = - bp->dcbx_port_params.ets.cos_params[1].pri_bitmask; - + for (i = 0; i < bp->dcbx_port_params.ets.num_of_cos; i++) + if (bp->dcbx_port_params.ets.cos_params[i].pauseable) + pfc_params.rx_cos_priority_mask[i] = + bp->dcbx_port_params.ets. + cos_params[i].pri_bitmask; /** * Rx COS configuration @@ -378,7 +377,7 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, static void bnx2x_pfc_set_pfc(struct bnx2x *bp) { - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { if (BP_PORT(bp)) { BNX2X_ERR("4 port mode is not supported"); return; @@ -406,7 +405,7 @@ static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) 0 /* connectionless */, 0 /* dataHi is zero */, 0 /* dataLo is zero */, - 1 /* common */); + NONE_CONNECTION_TYPE); } static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) @@ -417,7 +416,7 @@ static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) 0, /* connectionless */ U64_HI(bnx2x_sp_mapping(bp, pfc_config)), U64_LO(bnx2x_sp_mapping(bp, pfc_config)), - 1 /* commmon */); + NONE_CONNECTION_TYPE); } static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) @@ -425,7 +424,7 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets); u8 status = 0; - bnx2x_ets_disabled(&bp->link_params); + bnx2x_ets_disabled(&bp->link_params/*, &bp->link_vars*/); if (!ets->enabled) return; @@ -527,6 +526,7 @@ static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp) BNX2X_ERR("FW doesn't support dcbx_neg_res_offset\n"); return -EINVAL; } + rc = bnx2x_dcbx_read_mib(bp, (u32 *)&local_mib, dcbx_neg_res_offset, DCBX_READ_LOCAL_MIB); @@ -563,15 +563,6 @@ u8 bnx2x_dcbx_dcbnl_app_idtype(struct dcbx_app_priority_entry *ent) DCB_APP_IDTYPE_ETHTYPE; } -static inline -void bnx2x_dcbx_invalidate_local_apps(struct bnx2x *bp) -{ - int i; - for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) - bp->dcbx_local_feat.app.app_pri_tbl[i].appBitfield &= - ~DCBX_APP_ENTRY_VALID; -} - int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall) { int i, err = 0; @@ -597,32 +588,28 @@ int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall) } #endif +static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) +{ + if (SHMEM2_HAS(bp, drv_flags)) { + u32 drv_flags; + bnx2x_acquire_hw_lock(bp, HW_LOCK_DRV_FLAGS); + drv_flags = SHMEM2_RD(bp, drv_flags); + + if (set) + SET_FLAGS(drv_flags, flags); + else + RESET_FLAGS(drv_flags, flags); + + SHMEM2_WR(bp, drv_flags, drv_flags); + DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags); + bnx2x_release_hw_lock(bp, HW_LOCK_DRV_FLAGS); + } +} + void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) { switch (state) { case BNX2X_DCBX_STATE_NEG_RECEIVED: -#ifdef BCM_CNIC - if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { - struct cnic_ops *c_ops; - struct cnic_eth_dev *cp = &bp->cnic_eth_dev; - bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; - cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO; - cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI; - - rcu_read_lock(); - c_ops = rcu_dereference(bp->cnic_ops); - if (c_ops) { - bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD); - rcu_read_unlock(); - return; - } - rcu_read_unlock(); - } - - /* fall through if no CNIC initialized */ - case BNX2X_DCBX_STATE_ISCSI_STOPPED: -#endif - { DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n"); #ifdef BCM_DCBNL @@ -646,41 +633,28 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat, bp->dcbx_error); - if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { -#ifdef BCM_DCBNL - /** - * Add new app tlvs to dcbnl - */ - bnx2x_dcbnl_update_applist(bp, false); -#endif - bnx2x_dcbx_stop_hw_tx(bp); - return; - } - /* fall through */ + /* mark DCBX result for PMF migration */ + bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 1); #ifdef BCM_DCBNL /** - * Invalidate the local app tlvs if they are not added - * to the dcbnl app list to avoid deleting them from - * the list later on + * Add new app tlvs to dcbnl */ - bnx2x_dcbx_invalidate_local_apps(bp); + bnx2x_dcbnl_update_applist(bp, false); #endif + bnx2x_dcbx_stop_hw_tx(bp); + + return; } case BNX2X_DCBX_STATE_TX_PAUSED: DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n"); bnx2x_pfc_set_pfc(bp); bnx2x_dcbx_update_ets_params(bp); - if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { - bnx2x_dcbx_resume_hw_tx(bp); - return; - } - /* fall through */ + bnx2x_dcbx_resume_hw_tx(bp); + return; case BNX2X_DCBX_STATE_TX_RELEASED: DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n"); - if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) - bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0); - + bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0); return; default: BNX2X_ERR("Unknown DCBX_STATE\n"); @@ -868,7 +842,7 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) { - if (CHIP_IS_E2(bp) && !CHIP_MODE_IS_4_PORT(bp)) { + if (!CHIP_IS_E1x(bp) && !CHIP_MODE_IS_4_PORT(bp)) { bp->dcb_state = dcb_on; bp->dcbx_enabled = dcbx_enabled; } else { @@ -966,7 +940,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp) DP(NETIF_MSG_LINK, "dcb_state %d bp->port.pmf %d\n", bp->dcb_state, bp->port.pmf); - if (bp->dcb_state == BNX2X_DCB_STATE_ON && bp->port.pmf && + if (bp->dcb_state == BNX2X_DCB_STATE_ON && bp->port.pmf && SHMEM2_HAS(bp, dcbx_lldp_params_offset)) { dcbx_lldp_params_offset = SHMEM2_RD(bp, dcbx_lldp_params_offset); @@ -974,6 +948,8 @@ void bnx2x_dcbx_init(struct bnx2x *bp) DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", dcbx_lldp_params_offset); + bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); + if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { bnx2x_dcbx_lldp_updated_params(bp, dcbx_lldp_params_offset); @@ -981,46 +957,12 @@ void bnx2x_dcbx_init(struct bnx2x *bp) bnx2x_dcbx_admin_mib_updated_params(bp, dcbx_lldp_params_offset); - /* set default configuration BC has */ - bnx2x_dcbx_set_params(bp, - BNX2X_DCBX_STATE_NEG_RECEIVED); - + /* Let HW start negotiation */ bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 0); } } } - -void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp) -{ - struct priority_cos pricos[MAX_PFC_TRAFFIC_TYPES]; - u32 i = 0, addr; - memset(pricos, 0, sizeof(pricos)); - /* Default initialization */ - for (i = 0; i < MAX_PFC_TRAFFIC_TYPES; i++) - pricos[i].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED; - - /* Store per port struct to internal memory */ - addr = BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + - offsetof(struct cmng_struct_per_port, - traffic_type_to_priority_cos); - __storm_memset_struct(bp, addr, sizeof(pricos), (u32 *)pricos); - - - /* LLFC disabled.*/ - REG_WR8(bp , BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + - offsetof(struct cmng_struct_per_port, llfc_mode), - LLFC_MODE_NONE); - - /* DCBX disabled.*/ - REG_WR8(bp , BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + - offsetof(struct cmng_struct_per_port, dcb_enabled), - DCB_DISABLED); -} - static void bnx2x_dcbx_print_cos_params(struct bnx2x *bp, struct flow_control_configuration *pfc_fw_cfg) @@ -1591,13 +1533,7 @@ static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) /* Fw version should be incremented each update */ pfc_fw_cfg->dcb_version = ++bp->dcb_version; - pfc_fw_cfg->dcb_enabled = DCB_ENABLED; - - /* Default initialization */ - for (pri = 0; pri < MAX_PFC_TRAFFIC_TYPES ; pri++) { - tt2cos[pri].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED; - tt2cos[pri].cos = 0; - } + pfc_fw_cfg->dcb_enabled = 1; /* Fill priority parameters */ for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) { @@ -1605,14 +1541,37 @@ static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) pri_bit = 1 << tt2cos[pri].priority; /* Fill COS parameters based on COS calculated to - * make it more generally for future use */ + * make it more general for future use */ for (cos = 0; cos < bp->dcbx_port_params.ets.num_of_cos; cos++) if (bp->dcbx_port_params.ets.cos_params[cos]. pri_bitmask & pri_bit) tt2cos[pri].cos = cos; } + + /* we never want the FW to add a 0 vlan tag */ + pfc_fw_cfg->dont_add_pri_0_en = 1; + bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg); } + +void bnx2x_dcbx_pmf_update(struct bnx2x *bp) +{ + /* if we need to syncronize DCBX result from prev PMF + * read it from shmem and update bp accordingly + */ + if (SHMEM2_HAS(bp, drv_flags) && + GET_FLAGS(SHMEM2_RD(bp, drv_flags), DRV_FLAGS_DCB_CONFIGURED)) { + /* Read neg results if dcbx is in the FW */ + if (bnx2x_dcbx_read_shmem_neg_results(bp)) + return; + + bnx2x_dump_dcbx_drv_param(bp, &bp->dcbx_local_feat, + bp->dcbx_error); + bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat, + bp->dcbx_error); + } +} + /* DCB netlink */ #ifdef BCM_DCBNL diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h index 5bedd85e94d..7887834cd65 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.h +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -179,9 +179,6 @@ void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled); enum { BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1, -#ifdef BCM_CNIC - BNX2X_DCBX_STATE_ISCSI_STOPPED, -#endif BNX2X_DCBX_STATE_TX_PAUSED, BNX2X_DCBX_STATE_TX_RELEASED }; diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h index fb3ff7c4d7c..407531a9ab1 100644 --- a/drivers/net/bnx2x/bnx2x_dump.h +++ b/drivers/net/bnx2x/bnx2x_dump.h @@ -25,34 +25,55 @@ /*definitions */ -#define XSTORM_WAITP_ADDR 0x2b8a80 -#define TSTORM_WAITP_ADDR 0x1b8a80 -#define USTORM_WAITP_ADDR 0x338a80 -#define CSTORM_WAITP_ADDR 0x238a80 -#define TSTORM_CAM_MODE 0x1B1440 - -#define MAX_TIMER_PENDING 200 -#define TIMER_SCAN_DONT_CARE 0xFF -#define RI_E1 0x1 -#define RI_E1H 0x2 -#define RI_E2 0x4 -#define RI_ONLINE 0x100 -#define RI_PATH0_DUMP 0x200 -#define RI_PATH1_DUMP 0x400 -#define RI_E1_OFFLINE (RI_E1) -#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) -#define RI_E1H_OFFLINE (RI_E1H) -#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) -#define RI_E2_OFFLINE (RI_E2) -#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) -#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) -#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) -#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) -#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) -#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) -#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) -#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2) -#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) +#define XSTORM_WAITP_ADDR 0x2b8a80 +#define TSTORM_WAITP_ADDR 0x1b8a80 +#define USTORM_WAITP_ADDR 0x338a80 +#define CSTORM_WAITP_ADDR 0x238a80 +#define TSTORM_CAM_MODE 0x1B1440 + +#define MAX_TIMER_PENDING 200 +#define TIMER_SCAN_DONT_CARE 0xFF +#define RI_E1 0x1 +#define RI_E1H 0x2 +#define RI_E2 0x4 +#define RI_E3 0x8 +#define RI_ONLINE 0x100 +#define RI_PATH0_DUMP 0x200 +#define RI_PATH1_DUMP 0x400 +#define RI_E1_OFFLINE (RI_E1) +#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) +#define RI_E1H_OFFLINE (RI_E1H) +#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) +#define RI_E2_OFFLINE (RI_E2) +#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) +#define RI_E3_OFFLINE (RI_E3) +#define RI_E3_ONLINE (RI_E3 | RI_ONLINE) +#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) +#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E1E1HE2_OFFLINE (RI_E1 | RI_E1H | RI_E2) +#define RI_E1E1HE2_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) +#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) +#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) +#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) +#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) +#define RI_E1E3_OFFLINE (RI_E1 | RI_E3) +#define RI_E1E3_ONLINE (RI_E1 | RI_E3 | RI_ONLINE) +#define RI_E1HE3_OFFLINE (RI_E1H | RI_E3) +#define RI_E1HE3_ONLINE (RI_E1H | RI_E3 | RI_ONLINE) +#define RI_E2E3_OFFLINE (RI_E2 | RI_E3) +#define RI_E2E3_ONLINE (RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E1E1HE3_OFFLINE (RI_E1 | RI_E1H | RI_E3) +#define RI_E1E1HE3_ONLINE (RI_E1 | RI_E1H | RI_E3 | RI_ONLINE) +#define RI_E1HE2E3_OFFLINE (RI_E2 | RI_E1H | RI_E3) +#define RI_E1HE2E3_ONLINE (RI_E2 | RI_E1H | RI_E3 | RI_ONLINE) +#define RI_E1E2E3_OFFLINE (RI_E2 | RI_E1 | RI_E3) +#define RI_E1E2E3_ONLINE (RI_E2 | RI_E1 | RI_E3 | RI_ONLINE) +#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3) +#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_ONLINE) + +#define DBG_DMP_TRACE_BUFFER_SIZE 0x800 +#define DBG_DMP_TRACE_BUFFER_OFFSET(shmem0_offset) \ + ((shmem0_offset) - DBG_DMP_TRACE_BUFFER_SIZE) struct dump_sign { u32 time_stamp; @@ -86,185 +107,255 @@ struct wreg_addr { u16 info; }; -#define REGS_COUNT 834 -static const struct reg_addr reg_addrs[REGS_COUNT] = { +static const struct reg_addr reg_addrs[] = { { 0x2000, 341, RI_ALL_ONLINE }, { 0x2800, 103, RI_ALL_ONLINE }, { 0x3000, 287, RI_ALL_ONLINE }, { 0x3800, 331, RI_ALL_ONLINE }, - { 0x8800, 6, RI_ALL_ONLINE }, { 0x8818, 1, RI_E1HE2_ONLINE }, - { 0x9000, 164, RI_E2_ONLINE }, { 0x9400, 33, RI_E2_ONLINE }, - { 0xa000, 27, RI_ALL_ONLINE }, { 0xa06c, 1, RI_E1E1H_ONLINE }, - { 0xa070, 71, RI_ALL_ONLINE }, { 0xa18c, 4, RI_E1E1H_ONLINE }, - { 0xa19c, 62, RI_ALL_ONLINE }, { 0xa294, 2, RI_E1E1H_ONLINE }, - { 0xa29c, 56, RI_ALL_ONLINE }, { 0xa39c, 7, RI_E1HE2_ONLINE }, - { 0xa3c0, 3, RI_E1HE2_ONLINE }, { 0xa3d0, 1, RI_E1HE2_ONLINE }, - { 0xa3d8, 1, RI_E1HE2_ONLINE }, { 0xa3e0, 1, RI_E1HE2_ONLINE }, - { 0xa3e8, 1, RI_E1HE2_ONLINE }, { 0xa3f0, 1, RI_E1HE2_ONLINE }, - { 0xa3f8, 1, RI_E1HE2_ONLINE }, { 0xa400, 43, RI_ALL_ONLINE }, - { 0xa4ac, 2, RI_E1E1H_ONLINE }, { 0xa4b4, 1, RI_ALL_ONLINE }, + { 0x8800, 6, RI_ALL_ONLINE }, { 0x8818, 1, RI_E1HE2E3_ONLINE }, + { 0x9000, 147, RI_E2E3_ONLINE }, { 0x924c, 1, RI_E2_ONLINE }, + { 0x9250, 16, RI_E2E3_ONLINE }, { 0x9400, 33, RI_E2E3_ONLINE }, + { 0x9484, 5, RI_E3_ONLINE }, { 0xa000, 27, RI_ALL_ONLINE }, + { 0xa06c, 1, RI_E1E1H_ONLINE }, { 0xa070, 71, RI_ALL_ONLINE }, + { 0xa18c, 4, RI_E1E1H_ONLINE }, { 0xa19c, 62, RI_ALL_ONLINE }, + { 0xa294, 2, RI_E1E1H_ONLINE }, { 0xa29c, 2, RI_ALL_ONLINE }, + { 0xa2a4, 2, RI_E1E1HE2_ONLINE }, { 0xa2ac, 52, RI_ALL_ONLINE }, + { 0xa39c, 7, RI_E1HE2E3_ONLINE }, { 0xa3b8, 2, RI_E3_ONLINE }, + { 0xa3c0, 3, RI_E1HE2E3_ONLINE }, { 0xa3d0, 1, RI_E1HE2E3_ONLINE }, + { 0xa3d8, 1, RI_E1HE2E3_ONLINE }, { 0xa3e0, 1, RI_E1HE2E3_ONLINE }, + { 0xa3e8, 1, RI_E1HE2E3_ONLINE }, { 0xa3f0, 1, RI_E1HE2E3_ONLINE }, + { 0xa3f8, 1, RI_E1HE2E3_ONLINE }, { 0xa400, 40, RI_ALL_ONLINE }, + { 0xa4a0, 1, RI_E1E1HE2_ONLINE }, { 0xa4a4, 2, RI_ALL_ONLINE }, + { 0xa4ac, 2, RI_E1E1H_ONLINE }, { 0xa4b4, 1, RI_E1E1HE2_ONLINE }, { 0xa4b8, 2, RI_E1E1H_ONLINE }, { 0xa4c0, 3, RI_ALL_ONLINE }, - { 0xa4cc, 5, RI_E1E1H_ONLINE }, { 0xa4e0, 9, RI_ALL_ONLINE }, - { 0xa504, 1, RI_E1E1H_ONLINE }, { 0xa508, 3, RI_ALL_ONLINE }, - { 0xa518, 1, RI_ALL_ONLINE }, { 0xa520, 1, RI_ALL_ONLINE }, - { 0xa528, 1, RI_ALL_ONLINE }, { 0xa530, 1, RI_ALL_ONLINE }, - { 0xa538, 1, RI_ALL_ONLINE }, { 0xa540, 1, RI_ALL_ONLINE }, - { 0xa548, 1, RI_E1E1H_ONLINE }, { 0xa550, 1, RI_E1E1H_ONLINE }, - { 0xa558, 1, RI_E1E1H_ONLINE }, { 0xa560, 1, RI_E1E1H_ONLINE }, - { 0xa568, 1, RI_E1E1H_ONLINE }, { 0xa570, 1, RI_ALL_ONLINE }, - { 0xa580, 1, RI_ALL_ONLINE }, { 0xa590, 1, RI_ALL_ONLINE }, - { 0xa5a0, 1, RI_ALL_ONLINE }, { 0xa5c0, 1, RI_ALL_ONLINE }, - { 0xa5e0, 1, RI_E1HE2_ONLINE }, { 0xa5e8, 1, RI_E1HE2_ONLINE }, - { 0xa5f0, 1, RI_E1HE2_ONLINE }, { 0xa5f8, 10, RI_E1HE2_ONLINE }, - { 0xa620, 111, RI_E2_ONLINE }, { 0xa800, 51, RI_E2_ONLINE }, - { 0xa8d4, 4, RI_E2_ONLINE }, { 0xa8e8, 1, RI_E2_ONLINE }, - { 0xa8f0, 1, RI_E2_ONLINE }, { 0x10000, 236, RI_ALL_ONLINE }, - { 0x10400, 57, RI_ALL_ONLINE }, { 0x104e8, 2, RI_ALL_ONLINE }, + { 0xa4cc, 5, RI_E1E1H_ONLINE }, { 0xa4e0, 3, RI_ALL_ONLINE }, + { 0xa4fc, 2, RI_ALL_ONLINE }, { 0xa504, 1, RI_E1E1H_ONLINE }, + { 0xa508, 3, RI_ALL_ONLINE }, { 0xa518, 1, RI_ALL_ONLINE }, + { 0xa520, 1, RI_ALL_ONLINE }, { 0xa528, 1, RI_ALL_ONLINE }, + { 0xa530, 1, RI_ALL_ONLINE }, { 0xa538, 1, RI_ALL_ONLINE }, + { 0xa540, 1, RI_ALL_ONLINE }, { 0xa548, 1, RI_E1E1H_ONLINE }, + { 0xa550, 1, RI_E1E1H_ONLINE }, { 0xa558, 1, RI_E1E1H_ONLINE }, + { 0xa560, 1, RI_E1E1H_ONLINE }, { 0xa568, 1, RI_E1E1H_ONLINE }, + { 0xa570, 1, RI_ALL_ONLINE }, { 0xa580, 1, RI_ALL_ONLINE }, + { 0xa590, 1, RI_ALL_ONLINE }, { 0xa5a0, 1, RI_E1E1HE2_ONLINE }, + { 0xa5c0, 1, RI_ALL_ONLINE }, { 0xa5e0, 1, RI_E1HE2E3_ONLINE }, + { 0xa5e8, 1, RI_E1HE2E3_ONLINE }, { 0xa5f0, 1, RI_E1HE2E3_ONLINE }, + { 0xa5f8, 1, RI_E1HE2_ONLINE }, { 0xa5fc, 9, RI_E1HE2E3_ONLINE }, + { 0xa620, 6, RI_E2E3_ONLINE }, { 0xa638, 20, RI_E2_ONLINE }, + { 0xa688, 42, RI_E2E3_ONLINE }, { 0xa730, 1, RI_E2_ONLINE }, + { 0xa734, 2, RI_E2E3_ONLINE }, { 0xa73c, 4, RI_E2_ONLINE }, + { 0xa74c, 5, RI_E2E3_ONLINE }, { 0xa760, 5, RI_E2_ONLINE }, + { 0xa774, 7, RI_E2E3_ONLINE }, { 0xa790, 15, RI_E2_ONLINE }, + { 0xa7cc, 4, RI_E2E3_ONLINE }, { 0xa7e0, 6, RI_E3_ONLINE }, + { 0xa800, 18, RI_E2_ONLINE }, { 0xa848, 33, RI_E2E3_ONLINE }, + { 0xa8cc, 2, RI_E3_ONLINE }, { 0xa8d4, 4, RI_E2E3_ONLINE }, + { 0xa8e4, 1, RI_E3_ONLINE }, { 0xa8e8, 1, RI_E2E3_ONLINE }, + { 0xa8f0, 1, RI_E2E3_ONLINE }, { 0xa8f8, 30, RI_E3_ONLINE }, + { 0xa974, 73, RI_E3_ONLINE }, { 0xac30, 1, RI_E3_ONLINE }, + { 0xac40, 1, RI_E3_ONLINE }, { 0xac50, 1, RI_E3_ONLINE }, + { 0x10000, 9, RI_ALL_ONLINE }, { 0x10024, 1, RI_E1E1HE2_ONLINE }, + { 0x10028, 5, RI_ALL_ONLINE }, { 0x1003c, 6, RI_E1E1HE2_ONLINE }, + { 0x10054, 20, RI_ALL_ONLINE }, { 0x100a4, 4, RI_E1E1HE2_ONLINE }, + { 0x100b4, 11, RI_ALL_ONLINE }, { 0x100e0, 4, RI_E1E1HE2_ONLINE }, + { 0x100f0, 8, RI_ALL_ONLINE }, { 0x10110, 6, RI_E1E1HE2_ONLINE }, + { 0x10128, 110, RI_ALL_ONLINE }, { 0x102e0, 4, RI_E1E1HE2_ONLINE }, + { 0x102f0, 18, RI_ALL_ONLINE }, { 0x10338, 20, RI_E1E1HE2_ONLINE }, + { 0x10388, 10, RI_ALL_ONLINE }, { 0x10400, 6, RI_E1E1HE2_ONLINE }, + { 0x10418, 6, RI_ALL_ONLINE }, { 0x10430, 10, RI_E1E1HE2_ONLINE }, + { 0x10458, 22, RI_ALL_ONLINE }, { 0x104b0, 12, RI_E1E1HE2_ONLINE }, + { 0x104e0, 1, RI_ALL_ONLINE }, { 0x104e8, 2, RI_ALL_ONLINE }, { 0x104f4, 2, RI_ALL_ONLINE }, { 0x10500, 146, RI_ALL_ONLINE }, - { 0x10750, 2, RI_ALL_ONLINE }, { 0x10760, 2, RI_ALL_ONLINE }, - { 0x10770, 2, RI_ALL_ONLINE }, { 0x10780, 2, RI_ALL_ONLINE }, - { 0x10790, 2, RI_ALL_ONLINE }, { 0x107a0, 2, RI_ALL_ONLINE }, - { 0x107b0, 2, RI_ALL_ONLINE }, { 0x107c0, 2, RI_ALL_ONLINE }, - { 0x107d0, 2, RI_ALL_ONLINE }, { 0x107e0, 2, RI_ALL_ONLINE }, + { 0x10750, 2, RI_E1E1HE2_ONLINE }, { 0x10760, 2, RI_E1E1HE2_ONLINE }, + { 0x10770, 2, RI_E1E1HE2_ONLINE }, { 0x10780, 2, RI_E1E1HE2_ONLINE }, + { 0x10790, 2, RI_ALL_ONLINE }, { 0x107a0, 2, RI_E1E1HE2_ONLINE }, + { 0x107b0, 2, RI_E1E1HE2_ONLINE }, { 0x107c0, 2, RI_E1E1HE2_ONLINE }, + { 0x107d0, 2, RI_E1E1HE2_ONLINE }, { 0x107e0, 2, RI_ALL_ONLINE }, { 0x10880, 2, RI_ALL_ONLINE }, { 0x10900, 2, RI_ALL_ONLINE }, - { 0x16000, 26, RI_E1HE2_ONLINE }, { 0x16070, 18, RI_E1HE2_ONLINE }, - { 0x160c0, 27, RI_E1HE2_ONLINE }, { 0x16140, 1, RI_E1HE2_ONLINE }, - { 0x16160, 1, RI_E1HE2_ONLINE }, { 0x16180, 2, RI_E1HE2_ONLINE }, - { 0x161c0, 2, RI_E1HE2_ONLINE }, { 0x16204, 5, RI_E1HE2_ONLINE }, - { 0x18000, 1, RI_E1HE2_ONLINE }, { 0x18008, 1, RI_E1HE2_ONLINE }, - { 0x18010, 35, RI_E2_ONLINE }, { 0x180a4, 2, RI_E2_ONLINE }, - { 0x180c0, 191, RI_E2_ONLINE }, { 0x18440, 1, RI_E2_ONLINE }, - { 0x18460, 1, RI_E2_ONLINE }, { 0x18480, 2, RI_E2_ONLINE }, - { 0x184c0, 2, RI_E2_ONLINE }, { 0x18500, 15, RI_E2_ONLINE }, - { 0x20000, 24, RI_ALL_ONLINE }, { 0x20060, 8, RI_ALL_ONLINE }, - { 0x20080, 94, RI_ALL_ONLINE }, { 0x201f8, 1, RI_E1E1H_ONLINE }, - { 0x201fc, 1, RI_ALL_ONLINE }, { 0x20200, 1, RI_E1E1H_ONLINE }, - { 0x20204, 1, RI_ALL_ONLINE }, { 0x20208, 1, RI_E1E1H_ONLINE }, - { 0x2020c, 39, RI_ALL_ONLINE }, { 0x202c8, 1, RI_E2_ONLINE }, - { 0x202d8, 4, RI_E2_ONLINE }, { 0x20400, 2, RI_ALL_ONLINE }, - { 0x2040c, 8, RI_ALL_ONLINE }, { 0x2042c, 18, RI_E1HE2_ONLINE }, - { 0x20480, 1, RI_ALL_ONLINE }, { 0x20500, 1, RI_ALL_ONLINE }, - { 0x20600, 1, RI_ALL_ONLINE }, { 0x28000, 1, RI_ALL_ONLINE }, - { 0x28004, 8191, RI_ALL_OFFLINE }, { 0x30000, 1, RI_ALL_ONLINE }, - { 0x30004, 16383, RI_ALL_OFFLINE }, { 0x40000, 98, RI_ALL_ONLINE }, - { 0x401a8, 8, RI_E1HE2_ONLINE }, { 0x401c8, 1, RI_E1H_ONLINE }, - { 0x401cc, 2, RI_E1HE2_ONLINE }, { 0x401d4, 2, RI_E2_ONLINE }, - { 0x40200, 4, RI_ALL_ONLINE }, { 0x40220, 18, RI_E2_ONLINE }, - { 0x40400, 43, RI_ALL_ONLINE }, { 0x404cc, 3, RI_E1HE2_ONLINE }, - { 0x404e0, 1, RI_E2_ONLINE }, { 0x40500, 2, RI_ALL_ONLINE }, + { 0x16000, 1, RI_E1HE2_ONLINE }, { 0x16004, 25, RI_E1HE2E3_ONLINE }, + { 0x16070, 18, RI_E1HE2E3_ONLINE }, { 0x160c0, 7, RI_E1HE2E3_ONLINE }, + { 0x160dc, 2, RI_E1HE2_ONLINE }, { 0x160e4, 10, RI_E1HE2E3_ONLINE }, + { 0x1610c, 2, RI_E1HE2_ONLINE }, { 0x16114, 6, RI_E1HE2E3_ONLINE }, + { 0x16140, 48, RI_E1HE2E3_ONLINE }, { 0x16204, 5, RI_E1HE2E3_ONLINE }, + { 0x18000, 1, RI_E1HE2E3_ONLINE }, { 0x18008, 1, RI_E1HE2E3_ONLINE }, + { 0x18010, 35, RI_E2E3_ONLINE }, { 0x180a4, 2, RI_E2E3_ONLINE }, + { 0x180c0, 109, RI_E2E3_ONLINE }, { 0x18274, 1, RI_E2_ONLINE }, + { 0x18278, 81, RI_E2E3_ONLINE }, { 0x18440, 63, RI_E2E3_ONLINE }, + { 0x18570, 42, RI_E3_ONLINE }, { 0x20000, 24, RI_ALL_ONLINE }, + { 0x20060, 8, RI_ALL_ONLINE }, { 0x20080, 94, RI_ALL_ONLINE }, + { 0x201f8, 1, RI_E1E1H_ONLINE }, { 0x201fc, 1, RI_ALL_ONLINE }, + { 0x20200, 1, RI_E1E1H_ONLINE }, { 0x20204, 1, RI_ALL_ONLINE }, + { 0x20208, 1, RI_E1E1H_ONLINE }, { 0x2020c, 39, RI_ALL_ONLINE }, + { 0x202c8, 1, RI_E2E3_ONLINE }, { 0x202d8, 4, RI_E2E3_ONLINE }, + { 0x20400, 2, RI_ALL_ONLINE }, { 0x2040c, 8, RI_ALL_ONLINE }, + { 0x2042c, 18, RI_E1HE2E3_ONLINE }, { 0x20480, 1, RI_ALL_ONLINE }, + { 0x20500, 1, RI_ALL_ONLINE }, { 0x20600, 1, RI_ALL_ONLINE }, + { 0x28000, 1, RI_ALL_ONLINE }, { 0x28004, 8191, RI_ALL_OFFLINE }, + { 0x30000, 1, RI_ALL_ONLINE }, { 0x30004, 16383, RI_ALL_OFFLINE }, + { 0x40000, 98, RI_ALL_ONLINE }, { 0x401a8, 8, RI_E1HE2E3_ONLINE }, + { 0x401c8, 1, RI_E1H_ONLINE }, { 0x401cc, 2, RI_E1HE2E3_ONLINE }, + { 0x401d4, 2, RI_E2E3_ONLINE }, { 0x40200, 4, RI_ALL_ONLINE }, + { 0x40220, 18, RI_E2E3_ONLINE }, { 0x40268, 2, RI_E3_ONLINE }, + { 0x40400, 43, RI_ALL_ONLINE }, { 0x404cc, 3, RI_E1HE2E3_ONLINE }, + { 0x404e0, 1, RI_E2E3_ONLINE }, { 0x40500, 2, RI_ALL_ONLINE }, { 0x40510, 2, RI_ALL_ONLINE }, { 0x40520, 2, RI_ALL_ONLINE }, { 0x40530, 2, RI_ALL_ONLINE }, { 0x40540, 2, RI_ALL_ONLINE }, - { 0x40550, 10, RI_E2_ONLINE }, { 0x40610, 2, RI_E2_ONLINE }, - { 0x42000, 164, RI_ALL_ONLINE }, { 0x422c0, 4, RI_E2_ONLINE }, - { 0x422d4, 5, RI_E1HE2_ONLINE }, { 0x422e8, 1, RI_E2_ONLINE }, + { 0x40550, 10, RI_E2E3_ONLINE }, { 0x40610, 2, RI_E2E3_ONLINE }, + { 0x42000, 164, RI_ALL_ONLINE }, { 0x422c0, 4, RI_E2E3_ONLINE }, + { 0x422d4, 5, RI_E1HE2E3_ONLINE }, { 0x422e8, 1, RI_E2E3_ONLINE }, { 0x42400, 49, RI_ALL_ONLINE }, { 0x424c8, 38, RI_ALL_ONLINE }, - { 0x42568, 2, RI_ALL_ONLINE }, { 0x42640, 5, RI_E2_ONLINE }, + { 0x42568, 2, RI_ALL_ONLINE }, { 0x42640, 5, RI_E2E3_ONLINE }, { 0x42800, 1, RI_ALL_ONLINE }, { 0x50000, 1, RI_ALL_ONLINE }, { 0x50004, 19, RI_ALL_ONLINE }, { 0x50050, 8, RI_ALL_ONLINE }, - { 0x50070, 88, RI_ALL_ONLINE }, { 0x501f0, 4, RI_E1HE2_ONLINE }, + { 0x50070, 88, RI_ALL_ONLINE }, { 0x501f0, 4, RI_E1HE2E3_ONLINE }, { 0x50200, 2, RI_ALL_ONLINE }, { 0x5020c, 7, RI_ALL_ONLINE }, - { 0x50228, 6, RI_E1HE2_ONLINE }, { 0x50240, 1, RI_ALL_ONLINE }, - { 0x50280, 1, RI_ALL_ONLINE }, { 0x50300, 1, RI_E2_ONLINE }, - { 0x5030c, 1, RI_E2_ONLINE }, { 0x50318, 1, RI_E2_ONLINE }, - { 0x5031c, 1, RI_E2_ONLINE }, { 0x50320, 2, RI_E2_ONLINE }, + { 0x50228, 6, RI_E1HE2E3_ONLINE }, { 0x50240, 1, RI_ALL_ONLINE }, + { 0x50280, 1, RI_ALL_ONLINE }, { 0x50300, 1, RI_E2E3_ONLINE }, + { 0x5030c, 1, RI_E2E3_ONLINE }, { 0x50318, 1, RI_E2E3_ONLINE }, + { 0x5031c, 1, RI_E2E3_ONLINE }, { 0x50320, 2, RI_E2E3_ONLINE }, { 0x52000, 1, RI_ALL_ONLINE }, { 0x54000, 1, RI_ALL_ONLINE }, { 0x54004, 3327, RI_ALL_OFFLINE }, { 0x58000, 1, RI_ALL_ONLINE }, { 0x58004, 8191, RI_E1E1H_OFFLINE }, { 0x60000, 26, RI_ALL_ONLINE }, { 0x60068, 8, RI_E1E1H_ONLINE }, { 0x60088, 12, RI_ALL_ONLINE }, { 0x600b8, 9, RI_E1E1H_ONLINE }, { 0x600dc, 1, RI_ALL_ONLINE }, - { 0x600e0, 5, RI_E1E1H_ONLINE }, { 0x600f4, 1, RI_ALL_ONLINE }, + { 0x600e0, 5, RI_E1E1H_ONLINE }, { 0x600f4, 1, RI_E1E1HE2_ONLINE }, { 0x600f8, 1, RI_E1E1H_ONLINE }, { 0x600fc, 8, RI_ALL_ONLINE }, - { 0x6013c, 24, RI_E1H_ONLINE }, { 0x6019c, 2, RI_E2_ONLINE }, - { 0x601ac, 18, RI_E2_ONLINE }, { 0x60200, 1, RI_ALL_ONLINE }, - { 0x60204, 2, RI_ALL_OFFLINE }, { 0x60210, 13, RI_E2_ONLINE }, + { 0x6013c, 24, RI_E1H_ONLINE }, { 0x6019c, 2, RI_E2E3_ONLINE }, + { 0x601ac, 18, RI_E2E3_ONLINE }, { 0x60200, 1, RI_ALL_ONLINE }, + { 0x60204, 2, RI_ALL_OFFLINE }, { 0x60210, 13, RI_E2E3_ONLINE }, { 0x61000, 1, RI_ALL_ONLINE }, { 0x61004, 511, RI_ALL_OFFLINE }, - { 0x70000, 8, RI_ALL_ONLINE }, { 0x70020, 8184, RI_ALL_OFFLINE }, + { 0x61800, 512, RI_E3_OFFLINE }, { 0x70000, 8, RI_ALL_ONLINE }, + { 0x70020, 8184, RI_ALL_OFFLINE }, { 0x78000, 8192, RI_E3_OFFLINE }, { 0x85000, 3, RI_ALL_ONLINE }, { 0x8501c, 7, RI_ALL_ONLINE }, { 0x85048, 1, RI_ALL_ONLINE }, { 0x85200, 32, RI_ALL_ONLINE }, - { 0xc1000, 7, RI_ALL_ONLINE }, { 0xc103c, 2, RI_E2_ONLINE }, + { 0xb0000, 16384, RI_E1H_ONLINE }, + { 0xc1000, 7, RI_ALL_ONLINE }, { 0xc103c, 2, RI_E2E3_ONLINE }, { 0xc1800, 2, RI_ALL_ONLINE }, { 0xc2000, 164, RI_ALL_ONLINE }, - { 0xc22c0, 5, RI_E2_ONLINE }, { 0xc22d8, 4, RI_E2_ONLINE }, + { 0xc22c0, 5, RI_E2E3_ONLINE }, { 0xc22d8, 4, RI_E2E3_ONLINE }, { 0xc2400, 49, RI_ALL_ONLINE }, { 0xc24c8, 38, RI_ALL_ONLINE }, { 0xc2568, 2, RI_ALL_ONLINE }, { 0xc2600, 1, RI_ALL_ONLINE }, - { 0xc4000, 165, RI_ALL_ONLINE }, { 0xc42d8, 2, RI_E2_ONLINE }, - { 0xc42e0, 7, RI_E1HE2_ONLINE }, { 0xc42fc, 1, RI_E2_ONLINE }, + { 0xc4000, 165, RI_ALL_ONLINE }, { 0xc42d8, 2, RI_E2E3_ONLINE }, + { 0xc42e0, 7, RI_E1HE2E3_ONLINE }, { 0xc42fc, 1, RI_E2E3_ONLINE }, { 0xc4400, 51, RI_ALL_ONLINE }, { 0xc44d0, 38, RI_ALL_ONLINE }, - { 0xc4570, 2, RI_ALL_ONLINE }, { 0xc4578, 5, RI_E2_ONLINE }, + { 0xc4570, 2, RI_ALL_ONLINE }, { 0xc4578, 5, RI_E2E3_ONLINE }, { 0xc4600, 1, RI_ALL_ONLINE }, { 0xd0000, 19, RI_ALL_ONLINE }, { 0xd004c, 8, RI_ALL_ONLINE }, { 0xd006c, 91, RI_ALL_ONLINE }, - { 0xd01fc, 1, RI_E2_ONLINE }, { 0xd0200, 2, RI_ALL_ONLINE }, - { 0xd020c, 7, RI_ALL_ONLINE }, { 0xd0228, 18, RI_E1HE2_ONLINE }, + { 0xd01fc, 1, RI_E2E3_ONLINE }, { 0xd0200, 2, RI_ALL_ONLINE }, + { 0xd020c, 7, RI_ALL_ONLINE }, { 0xd0228, 18, RI_E1HE2E3_ONLINE }, { 0xd0280, 1, RI_ALL_ONLINE }, { 0xd0300, 1, RI_ALL_ONLINE }, { 0xd0400, 1, RI_ALL_ONLINE }, { 0xd4000, 1, RI_ALL_ONLINE }, { 0xd4004, 2559, RI_ALL_OFFLINE }, { 0xd8000, 1, RI_ALL_ONLINE }, { 0xd8004, 8191, RI_ALL_OFFLINE }, { 0xe0000, 21, RI_ALL_ONLINE }, { 0xe0054, 8, RI_ALL_ONLINE }, { 0xe0074, 49, RI_ALL_ONLINE }, { 0xe0138, 1, RI_E1E1H_ONLINE }, { 0xe013c, 35, RI_ALL_ONLINE }, - { 0xe01f4, 2, RI_E2_ONLINE }, { 0xe0200, 2, RI_ALL_ONLINE }, - { 0xe020c, 8, RI_ALL_ONLINE }, { 0xe022c, 18, RI_E1HE2_ONLINE }, - { 0xe0280, 1, RI_ALL_ONLINE }, { 0xe0300, 1, RI_ALL_ONLINE }, - { 0xe1000, 1, RI_ALL_ONLINE }, { 0xe2000, 1, RI_ALL_ONLINE }, - { 0xe2004, 2047, RI_ALL_OFFLINE }, { 0xf0000, 1, RI_ALL_ONLINE }, - { 0xf0004, 16383, RI_ALL_OFFLINE }, { 0x101000, 12, RI_ALL_ONLINE }, - { 0x101050, 1, RI_E1HE2_ONLINE }, { 0x101054, 3, RI_E2_ONLINE }, - { 0x101100, 1, RI_ALL_ONLINE }, { 0x101800, 8, RI_ALL_ONLINE }, - { 0x102000, 18, RI_ALL_ONLINE }, { 0x102068, 6, RI_E2_ONLINE }, - { 0x102080, 17, RI_ALL_ONLINE }, { 0x1020c8, 8, RI_E1H_ONLINE }, - { 0x1020e8, 9, RI_E2_ONLINE }, { 0x102400, 1, RI_ALL_ONLINE }, - { 0x103000, 26, RI_ALL_ONLINE }, { 0x103098, 5, RI_E1HE2_ONLINE }, - { 0x1030ac, 10, RI_E2_ONLINE }, { 0x1030d8, 8, RI_E2_ONLINE }, - { 0x103400, 1, RI_E2_ONLINE }, { 0x103404, 135, RI_E2_OFFLINE }, - { 0x103800, 8, RI_ALL_ONLINE }, { 0x104000, 63, RI_ALL_ONLINE }, - { 0x10411c, 16, RI_E2_ONLINE }, { 0x104200, 17, RI_ALL_ONLINE }, - { 0x104400, 64, RI_ALL_ONLINE }, { 0x104500, 192, RI_ALL_OFFLINE }, - { 0x104800, 64, RI_ALL_ONLINE }, { 0x104900, 192, RI_ALL_OFFLINE }, - { 0x105000, 256, RI_ALL_ONLINE }, { 0x105400, 768, RI_ALL_OFFLINE }, - { 0x107000, 7, RI_E2_ONLINE }, { 0x108000, 33, RI_E1E1H_ONLINE }, + { 0xe01f4, 1, RI_E2_ONLINE }, { 0xe01f8, 1, RI_E2E3_ONLINE }, + { 0xe0200, 2, RI_ALL_ONLINE }, { 0xe020c, 8, RI_ALL_ONLINE }, + { 0xe022c, 18, RI_E1HE2E3_ONLINE }, { 0xe0280, 1, RI_ALL_ONLINE }, + { 0xe0300, 1, RI_ALL_ONLINE }, { 0xe1000, 1, RI_ALL_ONLINE }, + { 0xe2000, 1, RI_ALL_ONLINE }, { 0xe2004, 2047, RI_ALL_OFFLINE }, + { 0xf0000, 1, RI_ALL_ONLINE }, { 0xf0004, 16383, RI_ALL_OFFLINE }, + { 0x101000, 12, RI_ALL_ONLINE }, { 0x101050, 1, RI_E1HE2E3_ONLINE }, + { 0x101054, 3, RI_E2E3_ONLINE }, { 0x101100, 1, RI_ALL_ONLINE }, + { 0x101800, 8, RI_ALL_ONLINE }, { 0x102000, 18, RI_ALL_ONLINE }, + { 0x102068, 6, RI_E2E3_ONLINE }, { 0x102080, 17, RI_ALL_ONLINE }, + { 0x1020c8, 8, RI_E1H_ONLINE }, { 0x1020e8, 9, RI_E2E3_ONLINE }, + { 0x102400, 1, RI_ALL_ONLINE }, { 0x103000, 26, RI_ALL_ONLINE }, + { 0x103098, 5, RI_E1HE2E3_ONLINE }, { 0x1030ac, 2, RI_E2E3_ONLINE }, + { 0x1030b4, 1, RI_E2_ONLINE }, { 0x1030b8, 7, RI_E2E3_ONLINE }, + { 0x1030d8, 8, RI_E2E3_ONLINE }, { 0x103400, 1, RI_E2E3_ONLINE }, + { 0x103404, 135, RI_E2E3_OFFLINE }, { 0x103800, 8, RI_ALL_ONLINE }, + { 0x104000, 63, RI_ALL_ONLINE }, { 0x10411c, 16, RI_E2E3_ONLINE }, + { 0x104200, 17, RI_ALL_ONLINE }, { 0x104400, 64, RI_ALL_ONLINE }, + { 0x104500, 192, RI_ALL_OFFLINE }, { 0x104800, 64, RI_ALL_ONLINE }, + { 0x104900, 192, RI_ALL_OFFLINE }, { 0x105000, 256, RI_ALL_ONLINE }, + { 0x105400, 768, RI_ALL_OFFLINE }, { 0x107000, 7, RI_E2E3_ONLINE }, + { 0x10701c, 1, RI_E3_ONLINE }, { 0x108000, 33, RI_E1E1H_ONLINE }, { 0x1080ac, 5, RI_E1H_ONLINE }, { 0x108100, 5, RI_E1E1H_ONLINE }, { 0x108120, 5, RI_E1E1H_ONLINE }, { 0x108200, 74, RI_E1E1H_ONLINE }, { 0x108400, 74, RI_E1E1H_ONLINE }, { 0x108800, 152, RI_E1E1H_ONLINE }, - { 0x110000, 111, RI_E2_ONLINE }, { 0x110200, 4, RI_E2_ONLINE }, - { 0x120000, 2, RI_ALL_ONLINE }, { 0x120008, 4, RI_ALL_ONLINE }, - { 0x120018, 3, RI_ALL_ONLINE }, { 0x120024, 4, RI_ALL_ONLINE }, - { 0x120034, 3, RI_ALL_ONLINE }, { 0x120040, 4, RI_ALL_ONLINE }, - { 0x120050, 3, RI_ALL_ONLINE }, { 0x12005c, 4, RI_ALL_ONLINE }, - { 0x12006c, 3, RI_ALL_ONLINE }, { 0x120078, 4, RI_ALL_ONLINE }, - { 0x120088, 3, RI_ALL_ONLINE }, { 0x120094, 4, RI_ALL_ONLINE }, - { 0x1200a4, 3, RI_ALL_ONLINE }, { 0x1200b0, 4, RI_ALL_ONLINE }, - { 0x1200c0, 3, RI_ALL_ONLINE }, { 0x1200cc, 4, RI_ALL_ONLINE }, - { 0x1200dc, 3, RI_ALL_ONLINE }, { 0x1200e8, 4, RI_ALL_ONLINE }, - { 0x1200f8, 3, RI_ALL_ONLINE }, { 0x120104, 4, RI_ALL_ONLINE }, - { 0x120114, 1, RI_ALL_ONLINE }, { 0x120118, 22, RI_ALL_ONLINE }, - { 0x120170, 2, RI_E1E1H_ONLINE }, { 0x120178, 243, RI_ALL_ONLINE }, - { 0x120544, 4, RI_E1E1H_ONLINE }, { 0x120554, 7, RI_ALL_ONLINE }, - { 0x12059c, 6, RI_E1HE2_ONLINE }, { 0x1205b4, 1, RI_E1HE2_ONLINE }, - { 0x1205b8, 16, RI_E1HE2_ONLINE }, { 0x1205f8, 4, RI_E2_ONLINE }, - { 0x120618, 1, RI_E2_ONLINE }, { 0x12061c, 20, RI_E1HE2_ONLINE }, - { 0x12066c, 11, RI_E1HE2_ONLINE }, { 0x120698, 5, RI_E2_ONLINE }, - { 0x1206b0, 76, RI_E2_ONLINE }, { 0x1207fc, 1, RI_E2_ONLINE }, - { 0x120808, 66, RI_ALL_ONLINE }, { 0x120910, 7, RI_E2_ONLINE }, - { 0x120930, 9, RI_E2_ONLINE }, { 0x120a00, 2, RI_ALL_ONLINE }, - { 0x122000, 2, RI_ALL_ONLINE }, { 0x122008, 2046, RI_E1_OFFLINE }, - { 0x128000, 2, RI_E1HE2_ONLINE }, { 0x128008, 6142, RI_E1HE2_OFFLINE }, - { 0x130000, 35, RI_E2_ONLINE }, { 0x130100, 29, RI_E2_ONLINE }, - { 0x130180, 1, RI_E2_ONLINE }, { 0x130200, 1, RI_E2_ONLINE }, - { 0x130280, 1, RI_E2_ONLINE }, { 0x130300, 5, RI_E2_ONLINE }, - { 0x130380, 1, RI_E2_ONLINE }, { 0x130400, 1, RI_E2_ONLINE }, - { 0x130480, 5, RI_E2_ONLINE }, { 0x130800, 72, RI_E2_ONLINE }, - { 0x131000, 136, RI_E2_ONLINE }, { 0x132000, 148, RI_E2_ONLINE }, - { 0x134000, 544, RI_E2_ONLINE }, { 0x140000, 64, RI_ALL_ONLINE }, - { 0x140100, 5, RI_E1E1H_ONLINE }, { 0x140114, 45, RI_ALL_ONLINE }, - { 0x140200, 6, RI_ALL_ONLINE }, { 0x140220, 4, RI_E2_ONLINE }, - { 0x140240, 4, RI_E2_ONLINE }, { 0x140260, 4, RI_E2_ONLINE }, - { 0x140280, 4, RI_E2_ONLINE }, { 0x1402a0, 4, RI_E2_ONLINE }, - { 0x1402c0, 4, RI_E2_ONLINE }, { 0x1402e0, 13, RI_E2_ONLINE }, - { 0x144000, 4, RI_E1E1H_ONLINE }, { 0x148000, 4, RI_E1E1H_ONLINE }, - { 0x14c000, 4, RI_E1E1H_ONLINE }, { 0x150000, 4, RI_E1E1H_ONLINE }, - { 0x154000, 4, RI_E1E1H_ONLINE }, { 0x158000, 4, RI_E1E1H_ONLINE }, - { 0x15c000, 2, RI_E1HE2_ONLINE }, { 0x15c008, 5, RI_E1H_ONLINE }, - { 0x15c020, 27, RI_E2_ONLINE }, { 0x15c090, 13, RI_E2_ONLINE }, - { 0x15c0c8, 34, RI_E2_ONLINE }, { 0x161000, 7, RI_ALL_ONLINE }, - { 0x16103c, 2, RI_E2_ONLINE }, { 0x161800, 2, RI_ALL_ONLINE }, - { 0x164000, 60, RI_ALL_ONLINE }, { 0x164110, 2, RI_E1HE2_ONLINE }, - { 0x164118, 15, RI_E2_ONLINE }, { 0x164200, 1, RI_ALL_ONLINE }, + { 0x110000, 111, RI_E2E3_ONLINE }, { 0x1101dc, 1, RI_E3_ONLINE }, + { 0x110200, 4, RI_E2E3_ONLINE }, { 0x120000, 2, RI_ALL_ONLINE }, + { 0x120008, 4, RI_ALL_ONLINE }, { 0x120018, 3, RI_ALL_ONLINE }, + { 0x120024, 4, RI_ALL_ONLINE }, { 0x120034, 3, RI_ALL_ONLINE }, + { 0x120040, 4, RI_ALL_ONLINE }, { 0x120050, 3, RI_ALL_ONLINE }, + { 0x12005c, 4, RI_ALL_ONLINE }, { 0x12006c, 3, RI_ALL_ONLINE }, + { 0x120078, 4, RI_ALL_ONLINE }, { 0x120088, 3, RI_ALL_ONLINE }, + { 0x120094, 4, RI_ALL_ONLINE }, { 0x1200a4, 3, RI_ALL_ONLINE }, + { 0x1200b0, 4, RI_ALL_ONLINE }, { 0x1200c0, 3, RI_ALL_ONLINE }, + { 0x1200cc, 4, RI_ALL_ONLINE }, { 0x1200dc, 3, RI_ALL_ONLINE }, + { 0x1200e8, 4, RI_ALL_ONLINE }, { 0x1200f8, 3, RI_ALL_ONLINE }, + { 0x120104, 4, RI_ALL_ONLINE }, { 0x120114, 1, RI_ALL_ONLINE }, + { 0x120118, 22, RI_ALL_ONLINE }, { 0x120170, 2, RI_E1E1H_ONLINE }, + { 0x120178, 243, RI_ALL_ONLINE }, { 0x120544, 4, RI_E1E1H_ONLINE }, + { 0x120554, 6, RI_ALL_ONLINE }, { 0x12059c, 6, RI_E1HE2E3_ONLINE }, + { 0x1205b4, 1, RI_E1HE2E3_ONLINE }, { 0x1205b8, 15, RI_E1HE2E3_ONLINE }, + { 0x1205f4, 1, RI_E1HE2_ONLINE }, { 0x1205f8, 4, RI_E2E3_ONLINE }, + { 0x120618, 1, RI_E2E3_ONLINE }, { 0x12061c, 20, RI_E1HE2E3_ONLINE }, + { 0x12066c, 11, RI_E1HE2E3_ONLINE }, { 0x120698, 3, RI_E2E3_ONLINE }, + { 0x1206a4, 1, RI_E2_ONLINE }, { 0x1206a8, 1, RI_E2E3_ONLINE }, + { 0x1206b0, 75, RI_E2E3_ONLINE }, { 0x1207dc, 1, RI_E2_ONLINE }, + { 0x1207fc, 1, RI_E2E3_ONLINE }, { 0x12080c, 65, RI_ALL_ONLINE }, + { 0x120910, 7, RI_E2E3_ONLINE }, { 0x120930, 9, RI_E2E3_ONLINE }, + { 0x12095c, 37, RI_E3_ONLINE }, { 0x120a00, 2, RI_E1E1HE2_ONLINE }, + { 0x120b00, 1, RI_E3_ONLINE }, { 0x122000, 2, RI_ALL_ONLINE }, + { 0x122008, 2046, RI_E1_OFFLINE }, { 0x128000, 2, RI_E1HE2E3_ONLINE }, + { 0x128008, 6142, RI_E1HE2E3_OFFLINE }, + { 0x130000, 35, RI_E2E3_ONLINE }, + { 0x130100, 29, RI_E2E3_ONLINE }, { 0x130180, 1, RI_E2E3_ONLINE }, + { 0x130200, 1, RI_E2E3_ONLINE }, { 0x130280, 1, RI_E2E3_ONLINE }, + { 0x130300, 5, RI_E2E3_ONLINE }, { 0x130380, 1, RI_E2E3_ONLINE }, + { 0x130400, 1, RI_E2E3_ONLINE }, { 0x130480, 5, RI_E2E3_ONLINE }, + { 0x130800, 72, RI_E2E3_ONLINE }, { 0x131000, 136, RI_E2E3_ONLINE }, + { 0x132000, 148, RI_E2E3_ONLINE }, { 0x134000, 544, RI_E2E3_ONLINE }, + { 0x140000, 64, RI_ALL_ONLINE }, { 0x140100, 5, RI_E1E1H_ONLINE }, + { 0x140114, 45, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE }, + { 0x140220, 4, RI_E2E3_ONLINE }, { 0x140240, 4, RI_E2E3_ONLINE }, + { 0x140260, 4, RI_E2E3_ONLINE }, { 0x140280, 4, RI_E2E3_ONLINE }, + { 0x1402a0, 4, RI_E2E3_ONLINE }, { 0x1402c0, 4, RI_E2E3_ONLINE }, + { 0x1402e0, 13, RI_E2E3_ONLINE }, { 0x144000, 4, RI_E1E1H_ONLINE }, + { 0x148000, 4, RI_E1E1H_ONLINE }, { 0x14c000, 4, RI_E1E1H_ONLINE }, + { 0x150000, 4, RI_E1E1H_ONLINE }, { 0x154000, 4, RI_E1E1H_ONLINE }, + { 0x158000, 4, RI_E1E1H_ONLINE }, { 0x15c000, 2, RI_E1HE2E3_ONLINE }, + { 0x15c008, 5, RI_E1H_ONLINE }, { 0x15c020, 27, RI_E2E3_ONLINE }, + { 0x15c090, 13, RI_E2E3_ONLINE }, { 0x15c0c8, 34, RI_E2E3_ONLINE }, + { 0x15c150, 4, RI_E3_ONLINE }, { 0x160004, 6, RI_E3_ONLINE }, + { 0x160040, 6, RI_E3_ONLINE }, { 0x16005c, 6, RI_E3_ONLINE }, + { 0x160078, 2, RI_E3_ONLINE }, { 0x160300, 8, RI_E3_ONLINE }, + { 0x160330, 6, RI_E3_ONLINE }, { 0x160404, 6, RI_E3_ONLINE }, + { 0x160440, 6, RI_E3_ONLINE }, { 0x16045c, 6, RI_E3_ONLINE }, + { 0x160478, 2, RI_E3_ONLINE }, { 0x160700, 8, RI_E3_ONLINE }, + { 0x160730, 6, RI_E3_ONLINE }, { 0x161000, 7, RI_ALL_ONLINE }, + { 0x16103c, 2, RI_E2E3_ONLINE }, { 0x161800, 2, RI_ALL_ONLINE }, + { 0x162000, 54, RI_E3_ONLINE }, { 0x162200, 60, RI_E3_ONLINE }, + { 0x162400, 54, RI_E3_ONLINE }, { 0x162600, 60, RI_E3_ONLINE }, + { 0x162800, 54, RI_E3_ONLINE }, { 0x162a00, 60, RI_E3_ONLINE }, + { 0x162c00, 54, RI_E3_ONLINE }, { 0x162e00, 60, RI_E3_ONLINE }, + { 0x163000, 1, RI_E3_ONLINE }, { 0x163008, 1, RI_E3_ONLINE }, + { 0x163010, 1, RI_E3_ONLINE }, { 0x163018, 1, RI_E3_ONLINE }, + { 0x163020, 5, RI_E3_ONLINE }, { 0x163038, 3, RI_E3_ONLINE }, + { 0x163048, 3, RI_E3_ONLINE }, { 0x163058, 1, RI_E3_ONLINE }, + { 0x163060, 1, RI_E3_ONLINE }, { 0x163068, 1, RI_E3_ONLINE }, + { 0x163070, 3, RI_E3_ONLINE }, { 0x163080, 1, RI_E3_ONLINE }, + { 0x163088, 3, RI_E3_ONLINE }, { 0x163098, 1, RI_E3_ONLINE }, + { 0x1630a0, 1, RI_E3_ONLINE }, { 0x1630a8, 1, RI_E3_ONLINE }, + { 0x1630c0, 1, RI_E3_ONLINE }, { 0x1630c8, 1, RI_E3_ONLINE }, + { 0x1630d0, 1, RI_E3_ONLINE }, { 0x1630d8, 1, RI_E3_ONLINE }, + { 0x1630e0, 2, RI_E3_ONLINE }, { 0x163110, 1, RI_E3_ONLINE }, + { 0x163120, 2, RI_E3_ONLINE }, { 0x163420, 4, RI_E3_ONLINE }, + { 0x163438, 2, RI_E3_ONLINE }, { 0x163488, 2, RI_E3_ONLINE }, + { 0x163520, 2, RI_E3_ONLINE }, { 0x163800, 1, RI_E3_ONLINE }, + { 0x163808, 1, RI_E3_ONLINE }, { 0x163810, 1, RI_E3_ONLINE }, + { 0x163818, 1, RI_E3_ONLINE }, { 0x163820, 5, RI_E3_ONLINE }, + { 0x163838, 3, RI_E3_ONLINE }, { 0x163848, 3, RI_E3_ONLINE }, + { 0x163858, 1, RI_E3_ONLINE }, { 0x163860, 1, RI_E3_ONLINE }, + { 0x163868, 1, RI_E3_ONLINE }, { 0x163870, 3, RI_E3_ONLINE }, + { 0x163880, 1, RI_E3_ONLINE }, { 0x163888, 3, RI_E3_ONLINE }, + { 0x163898, 1, RI_E3_ONLINE }, { 0x1638a0, 1, RI_E3_ONLINE }, + { 0x1638a8, 1, RI_E3_ONLINE }, { 0x1638c0, 1, RI_E3_ONLINE }, + { 0x1638c8, 1, RI_E3_ONLINE }, { 0x1638d0, 1, RI_E3_ONLINE }, + { 0x1638d8, 1, RI_E3_ONLINE }, { 0x1638e0, 2, RI_E3_ONLINE }, + { 0x163910, 1, RI_E3_ONLINE }, { 0x163920, 2, RI_E3_ONLINE }, + { 0x163c20, 4, RI_E3_ONLINE }, { 0x163c38, 2, RI_E3_ONLINE }, + { 0x163c88, 2, RI_E3_ONLINE }, { 0x163d20, 2, RI_E3_ONLINE }, + { 0x164000, 60, RI_ALL_ONLINE }, { 0x164110, 2, RI_E1HE2E3_ONLINE }, + { 0x164118, 15, RI_E2E3_ONLINE }, { 0x164200, 1, RI_ALL_ONLINE }, { 0x164208, 1, RI_ALL_ONLINE }, { 0x164210, 1, RI_ALL_ONLINE }, { 0x164218, 1, RI_ALL_ONLINE }, { 0x164220, 1, RI_ALL_ONLINE }, { 0x164228, 1, RI_ALL_ONLINE }, { 0x164230, 1, RI_ALL_ONLINE }, @@ -273,9 +364,9 @@ static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x164258, 1, RI_ALL_ONLINE }, { 0x164260, 1, RI_ALL_ONLINE }, { 0x164270, 2, RI_ALL_ONLINE }, { 0x164280, 2, RI_ALL_ONLINE }, { 0x164800, 2, RI_ALL_ONLINE }, { 0x165000, 2, RI_ALL_ONLINE }, - { 0x166000, 164, RI_ALL_ONLINE }, { 0x1662cc, 7, RI_E2_ONLINE }, + { 0x166000, 164, RI_ALL_ONLINE }, { 0x1662cc, 7, RI_E2E3_ONLINE }, { 0x166400, 49, RI_ALL_ONLINE }, { 0x1664c8, 38, RI_ALL_ONLINE }, - { 0x166568, 2, RI_ALL_ONLINE }, { 0x166570, 5, RI_E2_ONLINE }, + { 0x166568, 2, RI_ALL_ONLINE }, { 0x166570, 5, RI_E2E3_ONLINE }, { 0x166800, 1, RI_ALL_ONLINE }, { 0x168000, 137, RI_ALL_ONLINE }, { 0x168224, 2, RI_E1E1H_ONLINE }, { 0x16822c, 29, RI_ALL_ONLINE }, { 0x1682a0, 12, RI_E1E1H_ONLINE }, { 0x1682d0, 12, RI_ALL_ONLINE }, @@ -285,89 +376,94 @@ static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16a000, 1, RI_ALL_ONLINE }, { 0x16a004, 1535, RI_ALL_OFFLINE }, { 0x16c000, 1, RI_ALL_ONLINE }, { 0x16c004, 1535, RI_ALL_OFFLINE }, { 0x16e000, 16, RI_E1H_ONLINE }, - { 0x16e040, 8, RI_E2_ONLINE }, { 0x16e100, 1, RI_E1H_ONLINE }, + { 0x16e040, 8, RI_E2E3_ONLINE }, { 0x16e100, 1, RI_E1H_ONLINE }, { 0x16e200, 2, RI_E1H_ONLINE }, { 0x16e400, 161, RI_E1H_ONLINE }, - { 0x16e684, 2, RI_E1HE2_ONLINE }, { 0x16e68c, 12, RI_E1H_ONLINE }, - { 0x16e6bc, 4, RI_E1HE2_ONLINE }, { 0x16e6cc, 4, RI_E1H_ONLINE }, - { 0x16e6e0, 12, RI_E2_ONLINE }, { 0x16e768, 17, RI_E2_ONLINE }, + { 0x16e684, 2, RI_E1HE2E3_ONLINE }, { 0x16e68c, 12, RI_E1H_ONLINE }, + { 0x16e6bc, 4, RI_E1HE2E3_ONLINE }, { 0x16e6cc, 4, RI_E1H_ONLINE }, + { 0x16e6e0, 12, RI_E2E3_ONLINE }, { 0x16e768, 17, RI_E2E3_ONLINE }, { 0x170000, 24, RI_ALL_ONLINE }, { 0x170060, 4, RI_E1E1H_ONLINE }, - { 0x170070, 65, RI_ALL_ONLINE }, { 0x170194, 11, RI_E2_ONLINE }, - { 0x1701c4, 1, RI_E2_ONLINE }, { 0x1701cc, 7, RI_E2_ONLINE }, - { 0x1701ec, 1, RI_E2_ONLINE }, { 0x1701f4, 1, RI_E2_ONLINE }, - { 0x170200, 4, RI_ALL_ONLINE }, { 0x170214, 1, RI_ALL_ONLINE }, - { 0x170218, 77, RI_E2_ONLINE }, { 0x170400, 64, RI_E2_ONLINE }, - { 0x178000, 1, RI_ALL_ONLINE }, { 0x180000, 61, RI_ALL_ONLINE }, - { 0x18013c, 2, RI_E1HE2_ONLINE }, { 0x180200, 58, RI_ALL_ONLINE }, - { 0x180340, 4, RI_ALL_ONLINE }, { 0x180380, 1, RI_E2_ONLINE }, - { 0x180388, 1, RI_E2_ONLINE }, { 0x180390, 1, RI_E2_ONLINE }, - { 0x180398, 1, RI_E2_ONLINE }, { 0x1803a0, 5, RI_E2_ONLINE }, + { 0x170070, 65, RI_ALL_ONLINE }, { 0x170194, 11, RI_E2E3_ONLINE }, + { 0x1701c4, 1, RI_E2E3_ONLINE }, { 0x1701cc, 7, RI_E2E3_ONLINE }, + { 0x1701e8, 1, RI_E3_ONLINE }, { 0x1701ec, 1, RI_E2E3_ONLINE }, + { 0x1701f4, 1, RI_E2E3_ONLINE }, { 0x170200, 4, RI_ALL_ONLINE }, + { 0x170214, 1, RI_ALL_ONLINE }, { 0x170218, 77, RI_E2E3_ONLINE }, + { 0x170400, 64, RI_E2E3_ONLINE }, { 0x178000, 1, RI_ALL_ONLINE }, + { 0x180000, 61, RI_ALL_ONLINE }, { 0x18013c, 2, RI_E1HE2E3_ONLINE }, + { 0x180200, 58, RI_ALL_ONLINE }, { 0x180340, 4, RI_ALL_ONLINE }, + { 0x180380, 1, RI_E2E3_ONLINE }, { 0x180388, 1, RI_E2E3_ONLINE }, + { 0x180390, 1, RI_E2E3_ONLINE }, { 0x180398, 1, RI_E2E3_ONLINE }, + { 0x1803a0, 5, RI_E2E3_ONLINE }, { 0x1803b4, 2, RI_E3_ONLINE }, { 0x180400, 1, RI_ALL_ONLINE }, { 0x180404, 255, RI_E1E1H_OFFLINE }, { 0x181000, 4, RI_ALL_ONLINE }, { 0x181010, 1020, RI_ALL_OFFLINE }, - { 0x1a0000, 1, RI_ALL_ONLINE }, { 0x1a0004, 5631, RI_ALL_OFFLINE }, - { 0x1a5800, 2560, RI_E1HE2_OFFLINE }, { 0x1a8000, 1, RI_ALL_ONLINE }, - { 0x1a8004, 8191, RI_E1HE2_OFFLINE }, { 0x1b0000, 1, RI_ALL_ONLINE }, - { 0x1b0004, 15, RI_E1H_OFFLINE }, { 0x1b0040, 1, RI_E1HE2_ONLINE }, - { 0x1b0044, 239, RI_E1H_OFFLINE }, { 0x1b0400, 1, RI_ALL_ONLINE }, - { 0x1b0404, 255, RI_E1H_OFFLINE }, { 0x1b0800, 1, RI_ALL_ONLINE }, - { 0x1b0840, 1, RI_E1HE2_ONLINE }, { 0x1b0c00, 1, RI_ALL_ONLINE }, - { 0x1b1000, 1, RI_ALL_ONLINE }, { 0x1b1040, 1, RI_E1HE2_ONLINE }, - { 0x1b1400, 1, RI_ALL_ONLINE }, { 0x1b1440, 1, RI_E1HE2_ONLINE }, - { 0x1b1480, 1, RI_E1HE2_ONLINE }, { 0x1b14c0, 1, RI_E1HE2_ONLINE }, - { 0x1b1800, 128, RI_ALL_OFFLINE }, { 0x1b1c00, 128, RI_ALL_OFFLINE }, - { 0x1b2000, 1, RI_ALL_ONLINE }, { 0x1b2400, 1, RI_E1HE2_ONLINE }, - { 0x1b2404, 5631, RI_E2_OFFLINE }, { 0x1b8000, 1, RI_ALL_ONLINE }, - { 0x1b8040, 1, RI_ALL_ONLINE }, { 0x1b8080, 1, RI_ALL_ONLINE }, - { 0x1b80c0, 1, RI_ALL_ONLINE }, { 0x1b8100, 1, RI_ALL_ONLINE }, - { 0x1b8140, 1, RI_ALL_ONLINE }, { 0x1b8180, 1, RI_ALL_ONLINE }, - { 0x1b81c0, 1, RI_ALL_ONLINE }, { 0x1b8200, 1, RI_ALL_ONLINE }, - { 0x1b8240, 1, RI_ALL_ONLINE }, { 0x1b8280, 1, RI_ALL_ONLINE }, - { 0x1b82c0, 1, RI_ALL_ONLINE }, { 0x1b8300, 1, RI_ALL_ONLINE }, - { 0x1b8340, 1, RI_ALL_ONLINE }, { 0x1b8380, 1, RI_ALL_ONLINE }, - { 0x1b83c0, 1, RI_ALL_ONLINE }, { 0x1b8400, 1, RI_ALL_ONLINE }, - { 0x1b8440, 1, RI_ALL_ONLINE }, { 0x1b8480, 1, RI_ALL_ONLINE }, - { 0x1b84c0, 1, RI_ALL_ONLINE }, { 0x1b8500, 1, RI_ALL_ONLINE }, - { 0x1b8540, 1, RI_ALL_ONLINE }, { 0x1b8580, 1, RI_ALL_ONLINE }, - { 0x1b85c0, 19, RI_E2_ONLINE }, { 0x1b8800, 1, RI_ALL_ONLINE }, - { 0x1b8840, 1, RI_ALL_ONLINE }, { 0x1b8880, 1, RI_ALL_ONLINE }, - { 0x1b88c0, 1, RI_ALL_ONLINE }, { 0x1b8900, 1, RI_ALL_ONLINE }, - { 0x1b8940, 1, RI_ALL_ONLINE }, { 0x1b8980, 1, RI_ALL_ONLINE }, - { 0x1b89c0, 1, RI_ALL_ONLINE }, { 0x1b8a00, 1, RI_ALL_ONLINE }, - { 0x1b8a40, 1, RI_ALL_ONLINE }, { 0x1b8a80, 1, RI_ALL_ONLINE }, - { 0x1b8ac0, 1, RI_ALL_ONLINE }, { 0x1b8b00, 1, RI_ALL_ONLINE }, - { 0x1b8b40, 1, RI_ALL_ONLINE }, { 0x1b8b80, 1, RI_ALL_ONLINE }, - { 0x1b8bc0, 1, RI_ALL_ONLINE }, { 0x1b8c00, 1, RI_ALL_ONLINE }, - { 0x1b8c40, 1, RI_ALL_ONLINE }, { 0x1b8c80, 1, RI_ALL_ONLINE }, - { 0x1b8cc0, 1, RI_ALL_ONLINE }, { 0x1b8cc4, 1, RI_E2_ONLINE }, - { 0x1b8d00, 1, RI_ALL_ONLINE }, { 0x1b8d40, 1, RI_ALL_ONLINE }, - { 0x1b8d80, 1, RI_ALL_ONLINE }, { 0x1b8dc0, 1, RI_ALL_ONLINE }, - { 0x1b8e00, 1, RI_ALL_ONLINE }, { 0x1b8e40, 1, RI_ALL_ONLINE }, - { 0x1b8e80, 1, RI_ALL_ONLINE }, { 0x1b8e84, 1, RI_E2_ONLINE }, - { 0x1b8ec0, 1, RI_E1HE2_ONLINE }, { 0x1b8f00, 1, RI_E1HE2_ONLINE }, - { 0x1b8f40, 1, RI_E1HE2_ONLINE }, { 0x1b8f80, 1, RI_E1HE2_ONLINE }, - { 0x1b8fc0, 1, RI_E1HE2_ONLINE }, { 0x1b8fc4, 2, RI_E2_ONLINE }, - { 0x1b8fd0, 6, RI_E2_ONLINE }, { 0x1b9000, 1, RI_E2_ONLINE }, - { 0x1b9040, 3, RI_E2_ONLINE }, { 0x1b9400, 14, RI_E2_ONLINE }, - { 0x1b943c, 19, RI_E2_ONLINE }, { 0x1b9490, 10, RI_E2_ONLINE }, - { 0x1c0000, 2, RI_ALL_ONLINE }, { 0x200000, 65, RI_ALL_ONLINE }, - { 0x20014c, 2, RI_E1HE2_ONLINE }, { 0x200200, 58, RI_ALL_ONLINE }, - { 0x200340, 4, RI_ALL_ONLINE }, { 0x200380, 1, RI_E2_ONLINE }, - { 0x200388, 1, RI_E2_ONLINE }, { 0x200390, 1, RI_E2_ONLINE }, - { 0x200398, 1, RI_E2_ONLINE }, { 0x2003a0, 1, RI_E2_ONLINE }, - { 0x2003a8, 2, RI_E2_ONLINE }, { 0x200400, 1, RI_ALL_ONLINE }, - { 0x200404, 255, RI_E1E1H_OFFLINE }, { 0x202000, 4, RI_ALL_ONLINE }, - { 0x202010, 2044, RI_ALL_OFFLINE }, { 0x220000, 1, RI_ALL_ONLINE }, - { 0x220004, 5631, RI_ALL_OFFLINE }, { 0x225800, 2560, RI_E1HE2_OFFLINE}, - { 0x228000, 1, RI_ALL_ONLINE }, { 0x228004, 8191, RI_E1HE2_OFFLINE }, + { 0x182000, 4, RI_E3_ONLINE }, { 0x1a0000, 1, RI_ALL_ONLINE }, + { 0x1a0004, 5631, RI_ALL_OFFLINE }, + { 0x1a5800, 2560, RI_E1HE2E3_OFFLINE }, + { 0x1a8000, 1, RI_ALL_ONLINE }, { 0x1a8004, 8191, RI_E1HE2E3_OFFLINE }, + { 0x1b0000, 1, RI_ALL_ONLINE }, { 0x1b0004, 15, RI_E1H_OFFLINE }, + { 0x1b0040, 1, RI_E1HE2E3_ONLINE }, { 0x1b0044, 239, RI_E1H_OFFLINE }, + { 0x1b0400, 1, RI_ALL_ONLINE }, { 0x1b0404, 255, RI_E1H_OFFLINE }, + { 0x1b0800, 1, RI_ALL_ONLINE }, { 0x1b0840, 1, RI_E1HE2E3_ONLINE }, + { 0x1b0c00, 1, RI_ALL_ONLINE }, { 0x1b1000, 1, RI_ALL_ONLINE }, + { 0x1b1040, 1, RI_E1HE2E3_ONLINE }, { 0x1b1400, 1, RI_ALL_ONLINE }, + { 0x1b1440, 1, RI_E1HE2E3_ONLINE }, { 0x1b1480, 1, RI_E1HE2E3_ONLINE }, + { 0x1b14c0, 1, RI_E1HE2E3_ONLINE }, { 0x1b1800, 128, RI_ALL_OFFLINE }, + { 0x1b1c00, 128, RI_ALL_OFFLINE }, { 0x1b2000, 1, RI_ALL_ONLINE }, + { 0x1b2400, 1, RI_E1HE2E3_ONLINE }, { 0x1b2404, 5631, RI_E2E3_OFFLINE }, + { 0x1b8000, 1, RI_ALL_ONLINE }, { 0x1b8040, 1, RI_ALL_ONLINE }, + { 0x1b8080, 1, RI_ALL_ONLINE }, { 0x1b80c0, 1, RI_ALL_ONLINE }, + { 0x1b8100, 1, RI_ALL_ONLINE }, { 0x1b8140, 1, RI_ALL_ONLINE }, + { 0x1b8180, 1, RI_ALL_ONLINE }, { 0x1b81c0, 1, RI_ALL_ONLINE }, + { 0x1b8200, 1, RI_ALL_ONLINE }, { 0x1b8240, 1, RI_ALL_ONLINE }, + { 0x1b8280, 1, RI_ALL_ONLINE }, { 0x1b82c0, 1, RI_ALL_ONLINE }, + { 0x1b8300, 1, RI_ALL_ONLINE }, { 0x1b8340, 1, RI_ALL_ONLINE }, + { 0x1b8380, 1, RI_ALL_ONLINE }, { 0x1b83c0, 1, RI_ALL_ONLINE }, + { 0x1b8400, 1, RI_ALL_ONLINE }, { 0x1b8440, 1, RI_ALL_ONLINE }, + { 0x1b8480, 1, RI_ALL_ONLINE }, { 0x1b84c0, 1, RI_ALL_ONLINE }, + { 0x1b8500, 1, RI_ALL_ONLINE }, { 0x1b8540, 1, RI_ALL_ONLINE }, + { 0x1b8580, 1, RI_ALL_ONLINE }, { 0x1b85c0, 19, RI_E2E3_ONLINE }, + { 0x1b8800, 1, RI_ALL_ONLINE }, { 0x1b8840, 1, RI_ALL_ONLINE }, + { 0x1b8880, 1, RI_ALL_ONLINE }, { 0x1b88c0, 1, RI_ALL_ONLINE }, + { 0x1b8900, 1, RI_ALL_ONLINE }, { 0x1b8940, 1, RI_ALL_ONLINE }, + { 0x1b8980, 1, RI_ALL_ONLINE }, { 0x1b89c0, 1, RI_ALL_ONLINE }, + { 0x1b8a00, 1, RI_ALL_ONLINE }, { 0x1b8a40, 1, RI_ALL_ONLINE }, + { 0x1b8a80, 1, RI_ALL_ONLINE }, { 0x1b8ac0, 1, RI_ALL_ONLINE }, + { 0x1b8b00, 1, RI_ALL_ONLINE }, { 0x1b8b40, 1, RI_ALL_ONLINE }, + { 0x1b8b80, 1, RI_ALL_ONLINE }, { 0x1b8bc0, 1, RI_ALL_ONLINE }, + { 0x1b8c00, 1, RI_ALL_ONLINE }, { 0x1b8c40, 1, RI_ALL_ONLINE }, + { 0x1b8c80, 1, RI_ALL_ONLINE }, { 0x1b8cc0, 1, RI_ALL_ONLINE }, + { 0x1b8cc4, 1, RI_E2E3_ONLINE }, { 0x1b8d00, 1, RI_ALL_ONLINE }, + { 0x1b8d40, 1, RI_ALL_ONLINE }, { 0x1b8d80, 1, RI_ALL_ONLINE }, + { 0x1b8dc0, 1, RI_ALL_ONLINE }, { 0x1b8e00, 1, RI_ALL_ONLINE }, + { 0x1b8e40, 1, RI_ALL_ONLINE }, { 0x1b8e80, 1, RI_ALL_ONLINE }, + { 0x1b8e84, 1, RI_E2E3_ONLINE }, { 0x1b8ec0, 1, RI_E1HE2E3_ONLINE }, + { 0x1b8f00, 1, RI_E1HE2E3_ONLINE }, { 0x1b8f40, 1, RI_E1HE2E3_ONLINE }, + { 0x1b8f80, 1, RI_E1HE2E3_ONLINE }, { 0x1b8fc0, 1, RI_E1HE2E3_ONLINE }, + { 0x1b8fc4, 2, RI_E2E3_ONLINE }, { 0x1b8fd0, 6, RI_E2E3_ONLINE }, + { 0x1b8fe8, 2, RI_E3_ONLINE }, { 0x1b9000, 1, RI_E2E3_ONLINE }, + { 0x1b9040, 3, RI_E2E3_ONLINE }, { 0x1b905c, 1, RI_E3_ONLINE }, + { 0x1b9400, 14, RI_E2E3_ONLINE }, { 0x1b943c, 19, RI_E2E3_ONLINE }, + { 0x1b9490, 10, RI_E2E3_ONLINE }, { 0x1c0000, 2, RI_ALL_ONLINE }, + { 0x200000, 65, RI_ALL_ONLINE }, { 0x20014c, 2, RI_E1HE2E3_ONLINE }, + { 0x200200, 58, RI_ALL_ONLINE }, { 0x200340, 4, RI_ALL_ONLINE }, + { 0x200380, 1, RI_E2E3_ONLINE }, { 0x200388, 1, RI_E2E3_ONLINE }, + { 0x200390, 1, RI_E2E3_ONLINE }, { 0x200398, 1, RI_E2E3_ONLINE }, + { 0x2003a0, 1, RI_E2E3_ONLINE }, { 0x2003a8, 2, RI_E2E3_ONLINE }, + { 0x200400, 1, RI_ALL_ONLINE }, { 0x200404, 255, RI_E1E1H_OFFLINE }, + { 0x202000, 4, RI_ALL_ONLINE }, { 0x202010, 2044, RI_ALL_OFFLINE }, + { 0x204000, 4, RI_E3_ONLINE }, { 0x220000, 1, RI_ALL_ONLINE }, + { 0x220004, 5631, RI_ALL_OFFLINE }, + { 0x225800, 2560, RI_E1HE2E3_OFFLINE }, + { 0x228000, 1, RI_ALL_ONLINE }, { 0x228004, 8191, RI_E1HE2E3_OFFLINE }, { 0x230000, 1, RI_ALL_ONLINE }, { 0x230004, 15, RI_E1H_OFFLINE }, - { 0x230040, 1, RI_E1HE2_ONLINE }, { 0x230044, 239, RI_E1H_OFFLINE }, + { 0x230040, 1, RI_E1HE2E3_ONLINE }, { 0x230044, 239, RI_E1H_OFFLINE }, { 0x230400, 1, RI_ALL_ONLINE }, { 0x230404, 255, RI_E1H_OFFLINE }, - { 0x230800, 1, RI_ALL_ONLINE }, { 0x230840, 1, RI_E1HE2_ONLINE }, + { 0x230800, 1, RI_ALL_ONLINE }, { 0x230840, 1, RI_E1HE2E3_ONLINE }, { 0x230c00, 1, RI_ALL_ONLINE }, { 0x231000, 1, RI_ALL_ONLINE }, - { 0x231040, 1, RI_E1HE2_ONLINE }, { 0x231400, 1, RI_ALL_ONLINE }, - { 0x231440, 1, RI_E1HE2_ONLINE }, { 0x231480, 1, RI_E1HE2_ONLINE }, - { 0x2314c0, 1, RI_E1HE2_ONLINE }, { 0x231800, 128, RI_ALL_OFFLINE }, + { 0x231040, 1, RI_E1HE2E3_ONLINE }, { 0x231400, 1, RI_ALL_ONLINE }, + { 0x231440, 1, RI_E1HE2E3_ONLINE }, { 0x231480, 1, RI_E1HE2E3_ONLINE }, + { 0x2314c0, 1, RI_E1HE2E3_ONLINE }, { 0x231800, 128, RI_ALL_OFFLINE }, { 0x231c00, 128, RI_ALL_OFFLINE }, { 0x232000, 1, RI_ALL_ONLINE }, - { 0x232400, 1, RI_E1HE2_ONLINE }, { 0x232404, 5631, RI_E2_OFFLINE }, + { 0x232400, 1, RI_E1HE2E3_ONLINE }, { 0x232404, 5631, RI_E2E3_OFFLINE }, { 0x238000, 1, RI_ALL_ONLINE }, { 0x238040, 1, RI_ALL_ONLINE }, { 0x238080, 1, RI_ALL_ONLINE }, { 0x2380c0, 1, RI_ALL_ONLINE }, { 0x238100, 1, RI_ALL_ONLINE }, { 0x238140, 1, RI_ALL_ONLINE }, @@ -379,7 +475,7 @@ static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x238400, 1, RI_ALL_ONLINE }, { 0x238440, 1, RI_ALL_ONLINE }, { 0x238480, 1, RI_ALL_ONLINE }, { 0x2384c0, 1, RI_ALL_ONLINE }, { 0x238500, 1, RI_ALL_ONLINE }, { 0x238540, 1, RI_ALL_ONLINE }, - { 0x238580, 1, RI_ALL_ONLINE }, { 0x2385c0, 19, RI_E2_ONLINE }, + { 0x238580, 1, RI_ALL_ONLINE }, { 0x2385c0, 19, RI_E2E3_ONLINE }, { 0x238800, 1, RI_ALL_ONLINE }, { 0x238840, 1, RI_ALL_ONLINE }, { 0x238880, 1, RI_ALL_ONLINE }, { 0x2388c0, 1, RI_ALL_ONLINE }, { 0x238900, 1, RI_ALL_ONLINE }, { 0x238940, 1, RI_ALL_ONLINE }, @@ -390,88 +486,91 @@ static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x238b80, 1, RI_ALL_ONLINE }, { 0x238bc0, 1, RI_ALL_ONLINE }, { 0x238c00, 1, RI_ALL_ONLINE }, { 0x238c40, 1, RI_ALL_ONLINE }, { 0x238c80, 1, RI_ALL_ONLINE }, { 0x238cc0, 1, RI_ALL_ONLINE }, - { 0x238cc4, 1, RI_E2_ONLINE }, { 0x238d00, 1, RI_ALL_ONLINE }, + { 0x238cc4, 1, RI_E2E3_ONLINE }, { 0x238d00, 1, RI_ALL_ONLINE }, { 0x238d40, 1, RI_ALL_ONLINE }, { 0x238d80, 1, RI_ALL_ONLINE }, { 0x238dc0, 1, RI_ALL_ONLINE }, { 0x238e00, 1, RI_ALL_ONLINE }, { 0x238e40, 1, RI_ALL_ONLINE }, { 0x238e80, 1, RI_ALL_ONLINE }, - { 0x238e84, 1, RI_E2_ONLINE }, { 0x238ec0, 1, RI_E1HE2_ONLINE }, - { 0x238f00, 1, RI_E1HE2_ONLINE }, { 0x238f40, 1, RI_E1HE2_ONLINE }, - { 0x238f80, 1, RI_E1HE2_ONLINE }, { 0x238fc0, 1, RI_E1HE2_ONLINE }, - { 0x238fc4, 2, RI_E2_ONLINE }, { 0x238fd0, 6, RI_E2_ONLINE }, - { 0x239000, 1, RI_E2_ONLINE }, { 0x239040, 3, RI_E2_ONLINE }, + { 0x238e84, 1, RI_E2E3_ONLINE }, { 0x238ec0, 1, RI_E1HE2E3_ONLINE }, + { 0x238f00, 1, RI_E1HE2E3_ONLINE }, { 0x238f40, 1, RI_E1HE2E3_ONLINE }, + { 0x238f80, 1, RI_E1HE2E3_ONLINE }, { 0x238fc0, 1, RI_E1HE2E3_ONLINE }, + { 0x238fc4, 2, RI_E2E3_ONLINE }, { 0x238fd0, 6, RI_E2E3_ONLINE }, + { 0x238fe8, 2, RI_E3_ONLINE }, { 0x239000, 1, RI_E2E3_ONLINE }, + { 0x239040, 3, RI_E2E3_ONLINE }, { 0x23905c, 1, RI_E3_ONLINE }, { 0x240000, 2, RI_ALL_ONLINE }, { 0x280000, 65, RI_ALL_ONLINE }, - { 0x28014c, 2, RI_E1HE2_ONLINE }, { 0x280200, 58, RI_ALL_ONLINE }, - { 0x280340, 4, RI_ALL_ONLINE }, { 0x280380, 1, RI_E2_ONLINE }, - { 0x280388, 1, RI_E2_ONLINE }, { 0x280390, 1, RI_E2_ONLINE }, - { 0x280398, 1, RI_E2_ONLINE }, { 0x2803a0, 1, RI_E2_ONLINE }, - { 0x2803a8, 2, RI_E2_ONLINE }, { 0x280400, 1, RI_ALL_ONLINE }, + { 0x28014c, 2, RI_E1HE2E3_ONLINE }, { 0x280200, 58, RI_ALL_ONLINE }, + { 0x280340, 4, RI_ALL_ONLINE }, { 0x280380, 1, RI_E2E3_ONLINE }, + { 0x280388, 1, RI_E2E3_ONLINE }, { 0x280390, 1, RI_E2E3_ONLINE }, + { 0x280398, 1, RI_E2E3_ONLINE }, { 0x2803a0, 1, RI_E2E3_ONLINE }, + { 0x2803a8, 2, RI_E2E3_ONLINE }, { 0x280400, 1, RI_ALL_ONLINE }, { 0x280404, 255, RI_E1E1H_OFFLINE }, { 0x282000, 4, RI_ALL_ONLINE }, - { 0x282010, 2044, RI_ALL_OFFLINE }, { 0x2a0000, 1, RI_ALL_ONLINE }, - { 0x2a0004, 5631, RI_ALL_OFFLINE }, { 0x2a5800, 2560, RI_E1HE2_OFFLINE}, - { 0x2a8000, 1, RI_ALL_ONLINE }, { 0x2a8004, 8191, RI_E1HE2_OFFLINE }, - { 0x2b0000, 1, RI_ALL_ONLINE }, { 0x2b0004, 15, RI_E1H_OFFLINE }, - { 0x2b0040, 1, RI_E1HE2_ONLINE }, { 0x2b0044, 239, RI_E1H_OFFLINE }, - { 0x2b0400, 1, RI_ALL_ONLINE }, { 0x2b0404, 255, RI_E1H_OFFLINE }, - { 0x2b0800, 1, RI_ALL_ONLINE }, { 0x2b0840, 1, RI_E1HE2_ONLINE }, - { 0x2b0c00, 1, RI_ALL_ONLINE }, { 0x2b1000, 1, RI_ALL_ONLINE }, - { 0x2b1040, 1, RI_E1HE2_ONLINE }, { 0x2b1400, 1, RI_ALL_ONLINE }, - { 0x2b1440, 1, RI_E1HE2_ONLINE }, { 0x2b1480, 1, RI_E1HE2_ONLINE }, - { 0x2b14c0, 1, RI_E1HE2_ONLINE }, { 0x2b1800, 128, RI_ALL_OFFLINE }, - { 0x2b1c00, 128, RI_ALL_OFFLINE }, { 0x2b2000, 1, RI_ALL_ONLINE }, - { 0x2b2400, 1, RI_E1HE2_ONLINE }, { 0x2b2404, 5631, RI_E2_OFFLINE }, - { 0x2b8000, 1, RI_ALL_ONLINE }, { 0x2b8040, 1, RI_ALL_ONLINE }, - { 0x2b8080, 1, RI_ALL_ONLINE }, { 0x2b80c0, 1, RI_ALL_ONLINE }, - { 0x2b8100, 1, RI_ALL_ONLINE }, { 0x2b8140, 1, RI_ALL_ONLINE }, - { 0x2b8180, 1, RI_ALL_ONLINE }, { 0x2b81c0, 1, RI_ALL_ONLINE }, - { 0x2b8200, 1, RI_ALL_ONLINE }, { 0x2b8240, 1, RI_ALL_ONLINE }, - { 0x2b8280, 1, RI_ALL_ONLINE }, { 0x2b82c0, 1, RI_ALL_ONLINE }, - { 0x2b8300, 1, RI_ALL_ONLINE }, { 0x2b8340, 1, RI_ALL_ONLINE }, - { 0x2b8380, 1, RI_ALL_ONLINE }, { 0x2b83c0, 1, RI_ALL_ONLINE }, - { 0x2b8400, 1, RI_ALL_ONLINE }, { 0x2b8440, 1, RI_ALL_ONLINE }, - { 0x2b8480, 1, RI_ALL_ONLINE }, { 0x2b84c0, 1, RI_ALL_ONLINE }, - { 0x2b8500, 1, RI_ALL_ONLINE }, { 0x2b8540, 1, RI_ALL_ONLINE }, - { 0x2b8580, 1, RI_ALL_ONLINE }, { 0x2b85c0, 19, RI_E2_ONLINE }, - { 0x2b8800, 1, RI_ALL_ONLINE }, { 0x2b8840, 1, RI_ALL_ONLINE }, - { 0x2b8880, 1, RI_ALL_ONLINE }, { 0x2b88c0, 1, RI_ALL_ONLINE }, - { 0x2b8900, 1, RI_ALL_ONLINE }, { 0x2b8940, 1, RI_ALL_ONLINE }, - { 0x2b8980, 1, RI_ALL_ONLINE }, { 0x2b89c0, 1, RI_ALL_ONLINE }, - { 0x2b8a00, 1, RI_ALL_ONLINE }, { 0x2b8a40, 1, RI_ALL_ONLINE }, - { 0x2b8a80, 1, RI_ALL_ONLINE }, { 0x2b8ac0, 1, RI_ALL_ONLINE }, - { 0x2b8b00, 1, RI_ALL_ONLINE }, { 0x2b8b40, 1, RI_ALL_ONLINE }, - { 0x2b8b80, 1, RI_ALL_ONLINE }, { 0x2b8bc0, 1, RI_ALL_ONLINE }, - { 0x2b8c00, 1, RI_ALL_ONLINE }, { 0x2b8c40, 1, RI_ALL_ONLINE }, - { 0x2b8c80, 1, RI_ALL_ONLINE }, { 0x2b8cc0, 1, RI_ALL_ONLINE }, - { 0x2b8cc4, 1, RI_E2_ONLINE }, { 0x2b8d00, 1, RI_ALL_ONLINE }, - { 0x2b8d40, 1, RI_ALL_ONLINE }, { 0x2b8d80, 1, RI_ALL_ONLINE }, - { 0x2b8dc0, 1, RI_ALL_ONLINE }, { 0x2b8e00, 1, RI_ALL_ONLINE }, - { 0x2b8e40, 1, RI_ALL_ONLINE }, { 0x2b8e80, 1, RI_ALL_ONLINE }, - { 0x2b8e84, 1, RI_E2_ONLINE }, { 0x2b8ec0, 1, RI_E1HE2_ONLINE }, - { 0x2b8f00, 1, RI_E1HE2_ONLINE }, { 0x2b8f40, 1, RI_E1HE2_ONLINE }, - { 0x2b8f80, 1, RI_E1HE2_ONLINE }, { 0x2b8fc0, 1, RI_E1HE2_ONLINE }, - { 0x2b8fc4, 2, RI_E2_ONLINE }, { 0x2b8fd0, 6, RI_E2_ONLINE }, - { 0x2b9000, 1, RI_E2_ONLINE }, { 0x2b9040, 3, RI_E2_ONLINE }, - { 0x2b9400, 14, RI_E2_ONLINE }, { 0x2b943c, 19, RI_E2_ONLINE }, - { 0x2b9490, 10, RI_E2_ONLINE }, { 0x2c0000, 2, RI_ALL_ONLINE }, - { 0x300000, 65, RI_ALL_ONLINE }, { 0x30014c, 2, RI_E1HE2_ONLINE }, - { 0x300200, 58, RI_ALL_ONLINE }, { 0x300340, 4, RI_ALL_ONLINE }, - { 0x300380, 1, RI_E2_ONLINE }, { 0x300388, 1, RI_E2_ONLINE }, - { 0x300390, 1, RI_E2_ONLINE }, { 0x300398, 1, RI_E2_ONLINE }, - { 0x3003a0, 1, RI_E2_ONLINE }, { 0x3003a8, 2, RI_E2_ONLINE }, - { 0x300400, 1, RI_ALL_ONLINE }, { 0x300404, 255, RI_E1E1H_OFFLINE }, - { 0x302000, 4, RI_ALL_ONLINE }, { 0x302010, 2044, RI_ALL_OFFLINE }, + { 0x282010, 2044, RI_ALL_OFFLINE }, { 0x284000, 4, RI_E3_ONLINE }, + { 0x2a0000, 1, RI_ALL_ONLINE }, { 0x2a0004, 5631, RI_ALL_OFFLINE }, + { 0x2a5800, 2560, RI_E1HE2E3_OFFLINE }, { 0x2a8000, 1, RI_ALL_ONLINE }, + { 0x2a8004, 8191, RI_E1HE2E3_OFFLINE }, { 0x2b0000, 1, RI_ALL_ONLINE }, + { 0x2b0004, 15, RI_E1H_OFFLINE }, { 0x2b0040, 1, RI_E1HE2E3_ONLINE }, + { 0x2b0044, 239, RI_E1H_OFFLINE }, { 0x2b0400, 1, RI_ALL_ONLINE }, + { 0x2b0404, 255, RI_E1H_OFFLINE }, { 0x2b0800, 1, RI_ALL_ONLINE }, + { 0x2b0840, 1, RI_E1HE2E3_ONLINE }, { 0x2b0c00, 1, RI_ALL_ONLINE }, + { 0x2b1000, 1, RI_ALL_ONLINE }, { 0x2b1040, 1, RI_E1HE2E3_ONLINE }, + { 0x2b1400, 1, RI_ALL_ONLINE }, { 0x2b1440, 1, RI_E1HE2E3_ONLINE }, + { 0x2b1480, 1, RI_E1HE2E3_ONLINE }, { 0x2b14c0, 1, RI_E1HE2E3_ONLINE }, + { 0x2b1800, 128, RI_ALL_OFFLINE }, { 0x2b1c00, 128, RI_ALL_OFFLINE }, + { 0x2b2000, 1, RI_ALL_ONLINE }, { 0x2b2400, 1, RI_E1HE2E3_ONLINE }, + { 0x2b2404, 5631, RI_E2E3_OFFLINE }, { 0x2b8000, 1, RI_ALL_ONLINE }, + { 0x2b8040, 1, RI_ALL_ONLINE }, { 0x2b8080, 1, RI_ALL_ONLINE }, + { 0x2b80c0, 1, RI_ALL_ONLINE }, { 0x2b8100, 1, RI_ALL_ONLINE }, + { 0x2b8140, 1, RI_ALL_ONLINE }, { 0x2b8180, 1, RI_ALL_ONLINE }, + { 0x2b81c0, 1, RI_ALL_ONLINE }, { 0x2b8200, 1, RI_ALL_ONLINE }, + { 0x2b8240, 1, RI_ALL_ONLINE }, { 0x2b8280, 1, RI_ALL_ONLINE }, + { 0x2b82c0, 1, RI_ALL_ONLINE }, { 0x2b8300, 1, RI_ALL_ONLINE }, + { 0x2b8340, 1, RI_ALL_ONLINE }, { 0x2b8380, 1, RI_ALL_ONLINE }, + { 0x2b83c0, 1, RI_ALL_ONLINE }, { 0x2b8400, 1, RI_ALL_ONLINE }, + { 0x2b8440, 1, RI_ALL_ONLINE }, { 0x2b8480, 1, RI_ALL_ONLINE }, + { 0x2b84c0, 1, RI_ALL_ONLINE }, { 0x2b8500, 1, RI_ALL_ONLINE }, + { 0x2b8540, 1, RI_ALL_ONLINE }, { 0x2b8580, 1, RI_ALL_ONLINE }, + { 0x2b85c0, 19, RI_E2E3_ONLINE }, { 0x2b8800, 1, RI_ALL_ONLINE }, + { 0x2b8840, 1, RI_ALL_ONLINE }, { 0x2b8880, 1, RI_ALL_ONLINE }, + { 0x2b88c0, 1, RI_ALL_ONLINE }, { 0x2b8900, 1, RI_ALL_ONLINE }, + { 0x2b8940, 1, RI_ALL_ONLINE }, { 0x2b8980, 1, RI_ALL_ONLINE }, + { 0x2b89c0, 1, RI_ALL_ONLINE }, { 0x2b8a00, 1, RI_ALL_ONLINE }, + { 0x2b8a40, 1, RI_ALL_ONLINE }, { 0x2b8a80, 1, RI_ALL_ONLINE }, + { 0x2b8ac0, 1, RI_ALL_ONLINE }, { 0x2b8b00, 1, RI_ALL_ONLINE }, + { 0x2b8b40, 1, RI_ALL_ONLINE }, { 0x2b8b80, 1, RI_ALL_ONLINE }, + { 0x2b8bc0, 1, RI_ALL_ONLINE }, { 0x2b8c00, 1, RI_ALL_ONLINE }, + { 0x2b8c40, 1, RI_ALL_ONLINE }, { 0x2b8c80, 1, RI_ALL_ONLINE }, + { 0x2b8cc0, 1, RI_ALL_ONLINE }, { 0x2b8cc4, 1, RI_E2E3_ONLINE }, + { 0x2b8d00, 1, RI_ALL_ONLINE }, { 0x2b8d40, 1, RI_ALL_ONLINE }, + { 0x2b8d80, 1, RI_ALL_ONLINE }, { 0x2b8dc0, 1, RI_ALL_ONLINE }, + { 0x2b8e00, 1, RI_ALL_ONLINE }, { 0x2b8e40, 1, RI_ALL_ONLINE }, + { 0x2b8e80, 1, RI_ALL_ONLINE }, { 0x2b8e84, 1, RI_E2E3_ONLINE }, + { 0x2b8ec0, 1, RI_E1HE2E3_ONLINE }, { 0x2b8f00, 1, RI_E1HE2E3_ONLINE }, + { 0x2b8f40, 1, RI_E1HE2E3_ONLINE }, { 0x2b8f80, 1, RI_E1HE2E3_ONLINE }, + { 0x2b8fc0, 1, RI_E1HE2E3_ONLINE }, { 0x2b8fc4, 2, RI_E2E3_ONLINE }, + { 0x2b8fd0, 6, RI_E2E3_ONLINE }, { 0x2b8fe8, 2, RI_E3_ONLINE }, + { 0x2b9000, 1, RI_E2E3_ONLINE }, { 0x2b9040, 3, RI_E2E3_ONLINE }, + { 0x2b905c, 1, RI_E3_ONLINE }, { 0x2b9400, 14, RI_E2E3_ONLINE }, + { 0x2b943c, 19, RI_E2E3_ONLINE }, { 0x2b9490, 10, RI_E2E3_ONLINE }, + { 0x2c0000, 2, RI_ALL_ONLINE }, { 0x300000, 65, RI_ALL_ONLINE }, + { 0x30014c, 2, RI_E1HE2E3_ONLINE }, { 0x300200, 58, RI_ALL_ONLINE }, + { 0x300340, 4, RI_ALL_ONLINE }, { 0x300380, 1, RI_E2E3_ONLINE }, + { 0x300388, 1, RI_E2E3_ONLINE }, { 0x300390, 1, RI_E2E3_ONLINE }, + { 0x300398, 1, RI_E2E3_ONLINE }, { 0x3003a0, 1, RI_E2E3_ONLINE }, + { 0x3003a8, 2, RI_E2E3_ONLINE }, { 0x300400, 1, RI_ALL_ONLINE }, + { 0x300404, 255, RI_E1E1H_OFFLINE }, { 0x302000, 4, RI_ALL_ONLINE }, + { 0x302010, 2044, RI_ALL_OFFLINE }, { 0x304000, 4, RI_E3_ONLINE }, { 0x320000, 1, RI_ALL_ONLINE }, { 0x320004, 5631, RI_ALL_OFFLINE }, - { 0x325800, 2560, RI_E1HE2_OFFLINE }, { 0x328000, 1, RI_ALL_ONLINE }, - { 0x328004, 8191, RI_E1HE2_OFFLINE }, { 0x330000, 1, RI_ALL_ONLINE }, - { 0x330004, 15, RI_E1H_OFFLINE }, { 0x330040, 1, RI_E1HE2_ONLINE }, + { 0x325800, 2560, RI_E1HE2E3_OFFLINE }, { 0x328000, 1, RI_ALL_ONLINE }, + { 0x328004, 8191, RI_E1HE2E3_OFFLINE }, { 0x330000, 1, RI_ALL_ONLINE }, + { 0x330004, 15, RI_E1H_OFFLINE }, { 0x330040, 1, RI_E1HE2E3_ONLINE }, { 0x330044, 239, RI_E1H_OFFLINE }, { 0x330400, 1, RI_ALL_ONLINE }, { 0x330404, 255, RI_E1H_OFFLINE }, { 0x330800, 1, RI_ALL_ONLINE }, - { 0x330840, 1, RI_E1HE2_ONLINE }, { 0x330c00, 1, RI_ALL_ONLINE }, - { 0x331000, 1, RI_ALL_ONLINE }, { 0x331040, 1, RI_E1HE2_ONLINE }, - { 0x331400, 1, RI_ALL_ONLINE }, { 0x331440, 1, RI_E1HE2_ONLINE }, - { 0x331480, 1, RI_E1HE2_ONLINE }, { 0x3314c0, 1, RI_E1HE2_ONLINE }, + { 0x330840, 1, RI_E1HE2E3_ONLINE }, { 0x330c00, 1, RI_ALL_ONLINE }, + { 0x331000, 1, RI_ALL_ONLINE }, { 0x331040, 1, RI_E1HE2E3_ONLINE }, + { 0x331400, 1, RI_ALL_ONLINE }, { 0x331440, 1, RI_E1HE2E3_ONLINE }, + { 0x331480, 1, RI_E1HE2E3_ONLINE }, { 0x3314c0, 1, RI_E1HE2E3_ONLINE }, { 0x331800, 128, RI_ALL_OFFLINE }, { 0x331c00, 128, RI_ALL_OFFLINE }, - { 0x332000, 1, RI_ALL_ONLINE }, { 0x332400, 1, RI_E1HE2_ONLINE }, - { 0x332404, 5631, RI_E2_OFFLINE }, { 0x338000, 1, RI_ALL_ONLINE }, + { 0x332000, 1, RI_ALL_ONLINE }, { 0x332400, 1, RI_E1HE2E3_ONLINE }, + { 0x332404, 5631, RI_E2E3_OFFLINE }, { 0x338000, 1, RI_ALL_ONLINE }, { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, { 0x3380c0, 1, RI_ALL_ONLINE }, { 0x338100, 1, RI_ALL_ONLINE }, { 0x338140, 1, RI_ALL_ONLINE }, { 0x338180, 1, RI_ALL_ONLINE }, @@ -483,7 +582,7 @@ static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x338440, 1, RI_ALL_ONLINE }, { 0x338480, 1, RI_ALL_ONLINE }, { 0x3384c0, 1, RI_ALL_ONLINE }, { 0x338500, 1, RI_ALL_ONLINE }, { 0x338540, 1, RI_ALL_ONLINE }, { 0x338580, 1, RI_ALL_ONLINE }, - { 0x3385c0, 19, RI_E2_ONLINE }, { 0x338800, 1, RI_ALL_ONLINE }, + { 0x3385c0, 19, RI_E2E3_ONLINE }, { 0x338800, 1, RI_ALL_ONLINE }, { 0x338840, 1, RI_ALL_ONLINE }, { 0x338880, 1, RI_ALL_ONLINE }, { 0x3388c0, 1, RI_ALL_ONLINE }, { 0x338900, 1, RI_ALL_ONLINE }, { 0x338940, 1, RI_ALL_ONLINE }, { 0x338980, 1, RI_ALL_ONLINE }, @@ -493,35 +592,48 @@ static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x338b40, 1, RI_ALL_ONLINE }, { 0x338b80, 1, RI_ALL_ONLINE }, { 0x338bc0, 1, RI_ALL_ONLINE }, { 0x338c00, 1, RI_ALL_ONLINE }, { 0x338c40, 1, RI_ALL_ONLINE }, { 0x338c80, 1, RI_ALL_ONLINE }, - { 0x338cc0, 1, RI_ALL_ONLINE }, { 0x338cc4, 1, RI_E2_ONLINE }, + { 0x338cc0, 1, RI_ALL_ONLINE }, { 0x338cc4, 1, RI_E2E3_ONLINE }, { 0x338d00, 1, RI_ALL_ONLINE }, { 0x338d40, 1, RI_ALL_ONLINE }, { 0x338d80, 1, RI_ALL_ONLINE }, { 0x338dc0, 1, RI_ALL_ONLINE }, { 0x338e00, 1, RI_ALL_ONLINE }, { 0x338e40, 1, RI_ALL_ONLINE }, - { 0x338e80, 1, RI_ALL_ONLINE }, { 0x338e84, 1, RI_E2_ONLINE }, - { 0x338ec0, 1, RI_E1HE2_ONLINE }, { 0x338f00, 1, RI_E1HE2_ONLINE }, - { 0x338f40, 1, RI_E1HE2_ONLINE }, { 0x338f80, 1, RI_E1HE2_ONLINE }, - { 0x338fc0, 1, RI_E1HE2_ONLINE }, { 0x338fc4, 2, RI_E2_ONLINE }, - { 0x338fd0, 6, RI_E2_ONLINE }, { 0x339000, 1, RI_E2_ONLINE }, - { 0x339040, 3, RI_E2_ONLINE }, { 0x340000, 2, RI_ALL_ONLINE }, + { 0x338e80, 1, RI_ALL_ONLINE }, { 0x338e84, 1, RI_E2E3_ONLINE }, + { 0x338ec0, 1, RI_E1HE2E3_ONLINE }, { 0x338f00, 1, RI_E1HE2E3_ONLINE }, + { 0x338f40, 1, RI_E1HE2E3_ONLINE }, { 0x338f80, 1, RI_E1HE2E3_ONLINE }, + { 0x338fc0, 1, RI_E1HE2E3_ONLINE }, { 0x338fc4, 2, RI_E2E3_ONLINE }, + { 0x338fd0, 6, RI_E2E3_ONLINE }, { 0x338fe8, 2, RI_E3_ONLINE }, + { 0x339000, 1, RI_E2E3_ONLINE }, { 0x339040, 3, RI_E2E3_ONLINE }, + { 0x33905c, 1, RI_E3_ONLINE }, { 0x340000, 2, RI_ALL_ONLINE }, }; +#define REGS_COUNT ARRAY_SIZE(reg_addrs) -#define IDLE_REGS_COUNT 237 -static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = { +static const struct reg_addr idle_addrs[] = { { 0x2104, 1, RI_ALL_ONLINE }, { 0x2110, 2, RI_ALL_ONLINE }, { 0x211c, 8, RI_ALL_ONLINE }, { 0x2814, 1, RI_ALL_ONLINE }, { 0x281c, 2, RI_ALL_ONLINE }, { 0x2854, 1, RI_ALL_ONLINE }, - { 0x285c, 1, RI_ALL_ONLINE }, { 0x9010, 7, RI_E2_ONLINE }, - { 0x9030, 1, RI_E2_ONLINE }, { 0x9068, 16, RI_E2_ONLINE }, - { 0x9230, 2, RI_E2_ONLINE }, { 0x9244, 1, RI_E2_ONLINE }, - { 0x9298, 1, RI_E2_ONLINE }, { 0x92a8, 1, RI_E2_ONLINE }, - { 0xa38c, 1, RI_ALL_ONLINE }, { 0xa3c4, 1, RI_E1HE2_ONLINE }, - { 0xa408, 1, RI_ALL_ONLINE }, { 0xa42c, 12, RI_ALL_ONLINE }, - { 0xa600, 5, RI_E1HE2_ONLINE }, { 0xa618, 1, RI_E1HE2_ONLINE }, - { 0xa714, 1, RI_E2_ONLINE }, { 0xa720, 1, RI_E2_ONLINE }, - { 0xa750, 1, RI_E2_ONLINE }, { 0xc09c, 1, RI_E1E1H_ONLINE }, - { 0x103b0, 1, RI_ALL_ONLINE }, { 0x103c0, 1, RI_ALL_ONLINE }, - { 0x103d0, 1, RI_E1H_ONLINE }, { 0x183bc, 1, RI_E2_ONLINE }, - { 0x183cc, 1, RI_E2_ONLINE }, { 0x2021c, 11, RI_ALL_ONLINE }, + { 0x285c, 1, RI_ALL_ONLINE }, { 0x3040, 1, RI_ALL_ONLINE }, + { 0x9010, 7, RI_E2E3_ONLINE }, { 0x9030, 1, RI_E2E3_ONLINE }, + { 0x9068, 16, RI_E2E3_ONLINE }, { 0x9230, 2, RI_E2E3_ONLINE }, + { 0x9244, 1, RI_E2E3_ONLINE }, { 0x9298, 1, RI_E2E3_ONLINE }, + { 0x92a8, 1, RI_E2E3_ONLINE }, { 0xa38c, 1, RI_ALL_ONLINE }, + { 0xa3c4, 1, RI_E1HE2E3_ONLINE }, { 0xa404, 3, RI_ALL_ONLINE }, + { 0xa42c, 12, RI_ALL_ONLINE }, { 0xa600, 5, RI_E1HE2E3_ONLINE }, + { 0xa618, 1, RI_E1HE2E3_ONLINE }, { 0xa714, 1, RI_E2E3_ONLINE }, + { 0xa720, 1, RI_E2E3_ONLINE }, { 0xa750, 1, RI_E2E3_ONLINE }, + { 0xc09c, 1, RI_E1E1H_ONLINE }, { 0x103b0, 1, RI_ALL_ONLINE }, + { 0x103c0, 1, RI_ALL_ONLINE }, { 0x103d0, 1, RI_E1H_ONLINE }, + { 0x10418, 1, RI_ALL_ONLINE }, { 0x10420, 1, RI_ALL_ONLINE }, + { 0x10428, 1, RI_ALL_ONLINE }, { 0x10460, 1, RI_ALL_ONLINE }, + { 0x10474, 1, RI_ALL_ONLINE }, { 0x104e0, 1, RI_ALL_ONLINE }, + { 0x104ec, 1, RI_ALL_ONLINE }, { 0x104f8, 1, RI_ALL_ONLINE }, + { 0x10508, 1, RI_ALL_ONLINE }, { 0x10530, 1, RI_ALL_ONLINE }, + { 0x10538, 1, RI_ALL_ONLINE }, { 0x10548, 1, RI_ALL_ONLINE }, + { 0x10558, 1, RI_ALL_ONLINE }, { 0x182a8, 1, RI_E2E3_ONLINE }, + { 0x182b8, 1, RI_E2E3_ONLINE }, { 0x18308, 1, RI_E2E3_ONLINE }, + { 0x18318, 1, RI_E2E3_ONLINE }, { 0x18338, 1, RI_E2E3_ONLINE }, + { 0x18348, 1, RI_E2E3_ONLINE }, { 0x183bc, 1, RI_E2E3_ONLINE }, + { 0x183cc, 1, RI_E2E3_ONLINE }, { 0x18570, 1, RI_E3_ONLINE }, + { 0x18578, 1, RI_E3_ONLINE }, { 0x1858c, 1, RI_E3_ONLINE }, + { 0x18594, 1, RI_E3_ONLINE }, { 0x2021c, 11, RI_ALL_ONLINE }, { 0x202a8, 1, RI_ALL_ONLINE }, { 0x202b8, 1, RI_ALL_ONLINE }, { 0x20404, 1, RI_ALL_ONLINE }, { 0x2040c, 2, RI_ALL_ONLINE }, { 0x2041c, 2, RI_ALL_ONLINE }, { 0x40154, 14, RI_ALL_ONLINE }, @@ -551,8 +663,8 @@ static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = { { 0x102058, 1, RI_ALL_ONLINE }, { 0x102080, 16, RI_ALL_ONLINE }, { 0x103004, 2, RI_ALL_ONLINE }, { 0x103068, 1, RI_ALL_ONLINE }, { 0x103078, 1, RI_ALL_ONLINE }, { 0x103088, 1, RI_ALL_ONLINE }, - { 0x10309c, 2, RI_E1HE2_ONLINE }, { 0x1030b8, 2, RI_E2_ONLINE }, - { 0x1030cc, 1, RI_E2_ONLINE }, { 0x1030e0, 1, RI_E2_ONLINE }, + { 0x10309c, 2, RI_E1HE2E3_ONLINE }, { 0x1030b8, 2, RI_E2E3_ONLINE }, + { 0x1030cc, 1, RI_E2E3_ONLINE }, { 0x1030e0, 1, RI_E2E3_ONLINE }, { 0x104004, 1, RI_ALL_ONLINE }, { 0x104018, 1, RI_ALL_ONLINE }, { 0x104020, 1, RI_ALL_ONLINE }, { 0x10403c, 1, RI_ALL_ONLINE }, { 0x1040fc, 1, RI_ALL_ONLINE }, { 0x10410c, 1, RI_ALL_ONLINE }, @@ -563,28 +675,27 @@ static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = { { 0x120414, 15, RI_ALL_ONLINE }, { 0x120478, 2, RI_ALL_ONLINE }, { 0x12052c, 1, RI_ALL_ONLINE }, { 0x120564, 3, RI_ALL_ONLINE }, { 0x12057c, 1, RI_ALL_ONLINE }, { 0x12058c, 1, RI_ALL_ONLINE }, - { 0x120608, 1, RI_E1HE2_ONLINE }, { 0x120738, 1, RI_E2_ONLINE }, - { 0x120778, 2, RI_E2_ONLINE }, { 0x120808, 3, RI_ALL_ONLINE }, - { 0x120818, 1, RI_ALL_ONLINE }, { 0x120820, 1, RI_ALL_ONLINE }, - { 0x120828, 1, RI_ALL_ONLINE }, { 0x120830, 1, RI_ALL_ONLINE }, - { 0x120838, 1, RI_ALL_ONLINE }, { 0x120840, 1, RI_ALL_ONLINE }, - { 0x120848, 1, RI_ALL_ONLINE }, { 0x120850, 1, RI_ALL_ONLINE }, - { 0x120858, 1, RI_ALL_ONLINE }, { 0x120860, 1, RI_ALL_ONLINE }, - { 0x120868, 1, RI_ALL_ONLINE }, { 0x120870, 1, RI_ALL_ONLINE }, - { 0x120878, 1, RI_ALL_ONLINE }, { 0x120880, 1, RI_ALL_ONLINE }, - { 0x120888, 1, RI_ALL_ONLINE }, { 0x120890, 1, RI_ALL_ONLINE }, - { 0x120898, 1, RI_ALL_ONLINE }, { 0x1208a0, 1, RI_ALL_ONLINE }, - { 0x1208a8, 1, RI_ALL_ONLINE }, { 0x1208b0, 1, RI_ALL_ONLINE }, - { 0x1208b8, 1, RI_ALL_ONLINE }, { 0x1208c0, 1, RI_ALL_ONLINE }, - { 0x1208c8, 1, RI_ALL_ONLINE }, { 0x1208d0, 1, RI_ALL_ONLINE }, - { 0x1208d8, 1, RI_ALL_ONLINE }, { 0x1208e0, 1, RI_ALL_ONLINE }, - { 0x1208e8, 1, RI_ALL_ONLINE }, { 0x1208f0, 1, RI_ALL_ONLINE }, - { 0x1208f8, 1, RI_ALL_ONLINE }, { 0x120900, 1, RI_ALL_ONLINE }, - { 0x120908, 1, RI_ALL_ONLINE }, { 0x120940, 5, RI_E2_ONLINE }, - { 0x130030, 1, RI_E2_ONLINE }, { 0x13004c, 3, RI_E2_ONLINE }, - { 0x130064, 2, RI_E2_ONLINE }, { 0x13009c, 1, RI_E2_ONLINE }, - { 0x130130, 1, RI_E2_ONLINE }, { 0x13016c, 1, RI_E2_ONLINE }, - { 0x130300, 1, RI_E2_ONLINE }, { 0x130480, 1, RI_E2_ONLINE }, + { 0x120608, 1, RI_E1HE2E3_ONLINE }, { 0x120778, 2, RI_E2E3_ONLINE }, + { 0x120808, 3, RI_ALL_ONLINE }, { 0x120818, 1, RI_ALL_ONLINE }, + { 0x120820, 1, RI_ALL_ONLINE }, { 0x120828, 1, RI_ALL_ONLINE }, + { 0x120830, 1, RI_ALL_ONLINE }, { 0x120838, 1, RI_ALL_ONLINE }, + { 0x120840, 1, RI_ALL_ONLINE }, { 0x120848, 1, RI_ALL_ONLINE }, + { 0x120850, 1, RI_ALL_ONLINE }, { 0x120858, 1, RI_ALL_ONLINE }, + { 0x120860, 1, RI_ALL_ONLINE }, { 0x120868, 1, RI_ALL_ONLINE }, + { 0x120870, 1, RI_ALL_ONLINE }, { 0x120878, 1, RI_ALL_ONLINE }, + { 0x120880, 1, RI_ALL_ONLINE }, { 0x120888, 1, RI_ALL_ONLINE }, + { 0x120890, 1, RI_ALL_ONLINE }, { 0x120898, 1, RI_ALL_ONLINE }, + { 0x1208a0, 1, RI_ALL_ONLINE }, { 0x1208a8, 1, RI_ALL_ONLINE }, + { 0x1208b0, 1, RI_ALL_ONLINE }, { 0x1208b8, 1, RI_ALL_ONLINE }, + { 0x1208c0, 1, RI_ALL_ONLINE }, { 0x1208c8, 1, RI_ALL_ONLINE }, + { 0x1208d0, 1, RI_ALL_ONLINE }, { 0x1208d8, 1, RI_ALL_ONLINE }, + { 0x1208e0, 1, RI_ALL_ONLINE }, { 0x1208e8, 1, RI_ALL_ONLINE }, + { 0x1208f0, 1, RI_ALL_ONLINE }, { 0x1208f8, 1, RI_ALL_ONLINE }, + { 0x120900, 1, RI_ALL_ONLINE }, { 0x120908, 1, RI_ALL_ONLINE }, + { 0x130030, 1, RI_E2E3_ONLINE }, { 0x13004c, 3, RI_E2E3_ONLINE }, + { 0x130064, 2, RI_E2E3_ONLINE }, { 0x13009c, 1, RI_E2E3_ONLINE }, + { 0x130130, 1, RI_E2E3_ONLINE }, { 0x13016c, 1, RI_E2E3_ONLINE }, + { 0x130300, 1, RI_E2E3_ONLINE }, { 0x130480, 1, RI_E2E3_ONLINE }, { 0x14005c, 2, RI_ALL_ONLINE }, { 0x1400d0, 2, RI_ALL_ONLINE }, { 0x1400e0, 1, RI_ALL_ONLINE }, { 0x1401c8, 1, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE }, { 0x16101c, 1, RI_ALL_ONLINE }, @@ -602,8 +713,8 @@ static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = { { 0x168438, 1, RI_ALL_ONLINE }, { 0x168448, 1, RI_ALL_ONLINE }, { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16e200, 128, RI_E1H_ONLINE }, { 0x16e404, 2, RI_E1H_ONLINE }, { 0x16e584, 64, RI_E1H_ONLINE }, - { 0x16e684, 2, RI_E1HE2_ONLINE }, { 0x16e68c, 4, RI_E1H_ONLINE }, - { 0x16e6fc, 4, RI_E2_ONLINE }, { 0x1700a4, 1, RI_ALL_ONLINE }, + { 0x16e684, 2, RI_E1HE2E3_ONLINE }, { 0x16e68c, 4, RI_E1H_ONLINE }, + { 0x16e6fc, 4, RI_E2E3_ONLINE }, { 0x1700a4, 1, RI_ALL_ONLINE }, { 0x1700ac, 2, RI_ALL_ONLINE }, { 0x1700c0, 1, RI_ALL_ONLINE }, { 0x170174, 1, RI_ALL_ONLINE }, { 0x170184, 1, RI_ALL_ONLINE }, { 0x1800f4, 1, RI_ALL_ONLINE }, { 0x180104, 1, RI_ALL_ONLINE }, @@ -627,51 +738,61 @@ static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = { { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, { 0x3380c0, 1, RI_ALL_ONLINE } }; +#define IDLE_REGS_COUNT ARRAY_SIZE(idle_addrs) -#define WREGS_COUNT_E1 1 static const u32 read_reg_e1_0[] = { 0x1b1000 }; +#define WREGS_COUNT_E1 ARRAY_SIZE(read_reg_e1_0) static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = { { 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE } }; -#define WREGS_COUNT_E1H 1 static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 }; +#define WREGS_COUNT_E1H ARRAY_SIZE(read_reg_e1h_0) static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = { { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE } }; -#define WREGS_COUNT_E2 1 static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 }; +#define WREGS_COUNT_E2 ARRAY_SIZE(read_reg_e2_0) static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = { { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE } }; -static const struct dump_sign dump_sign_all = { 0x4d18b0a4, 0x60010, 0x3a }; +static const u32 read_reg_e3_0[] = { 0x1b1040, 0x1b1000 }; +#define WREGS_COUNT_E3 ARRAY_SIZE(read_reg_e3_0) + +static const struct wreg_addr wreg_addrs_e3[WREGS_COUNT_E3] = { + { 0x1b0c00, 128, 2, read_reg_e3_0, RI_E3_OFFLINE } }; + +static const struct dump_sign dump_sign_all = { 0x4dbe9fca, 0x60011, 0x3a }; -#define TIMER_REGS_COUNT_E1 2 +static const u32 timer_status_regs_e1[] = { 0x164014, 0x164018 }; +#define TIMER_REGS_COUNT_E1 ARRAY_SIZE(timer_status_regs_e1) -static const u32 timer_status_regs_e1[TIMER_REGS_COUNT_E1] = { - 0x164014, 0x164018 }; static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] = { 0x1640d0, 0x1640d4 }; -#define TIMER_REGS_COUNT_E1H 2 +static const u32 timer_status_regs_e1h[] = { 0x164014, 0x164018 }; +#define TIMER_REGS_COUNT_E1H ARRAY_SIZE(timer_status_regs_e1h) -static const u32 timer_status_regs_e1h[TIMER_REGS_COUNT_E1H] = { - 0x164014, 0x164018 }; static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = { 0x1640d0, 0x1640d4 }; -#define TIMER_REGS_COUNT_E2 2 +static const u32 timer_status_regs_e2[] = { 0x164014, 0x164018 }; +#define TIMER_REGS_COUNT_E2 ARRAY_SIZE(timer_status_regs_e2) -static const u32 timer_status_regs_e2[TIMER_REGS_COUNT_E2] = { - 0x164014, 0x164018 }; static const u32 timer_scan_regs_e2[TIMER_REGS_COUNT_E2] = { 0x1640d0, 0x1640d4 }; +static const u32 timer_status_regs_e3[] = { 0x164014, 0x164018 }; +#define TIMER_REGS_COUNT_E3 ARRAY_SIZE(timer_status_regs_e3) + +static const u32 timer_scan_regs_e3[TIMER_REGS_COUNT_E3] = { + 0x1640d0, 0x1640d4 }; + #define PAGE_MODE_VALUES_E1 0 #define PAGE_READ_REGS_E1 0 @@ -682,7 +803,8 @@ static const u32 page_vals_e1[] = { 0 }; static const u32 page_write_regs_e1[] = { 0 }; -static const struct reg_addr page_read_regs_e1[] = { { 0x0, 0, RI_E1_ONLINE } }; +static const struct reg_addr page_read_regs_e1[] = { + { 0x0, 0, RI_E1_ONLINE } }; #define PAGE_MODE_VALUES_E1H 0 @@ -697,17 +819,24 @@ static const u32 page_write_regs_e1h[] = { 0 }; static const struct reg_addr page_read_regs_e1h[] = { { 0x0, 0, RI_E1H_ONLINE } }; -#define PAGE_MODE_VALUES_E2 2 +static const u32 page_vals_e2[] = { 0, 128 }; +#define PAGE_MODE_VALUES_E2 ARRAY_SIZE(page_vals_e2) -#define PAGE_READ_REGS_E2 1 +static const u32 page_write_regs_e2[] = { 328476 }; +#define PAGE_WRITE_REGS_E2 ARRAY_SIZE(page_write_regs_e2) -#define PAGE_WRITE_REGS_E2 1 +static const struct reg_addr page_read_regs_e2[] = { + { 0x58000, 4608, RI_E2_ONLINE } }; +#define PAGE_READ_REGS_E2 ARRAY_SIZE(page_read_regs_e2) -static const u32 page_vals_e2[PAGE_MODE_VALUES_E2] = { 0, 128 }; +static const u32 page_vals_e3[] = { 0, 128 }; +#define PAGE_MODE_VALUES_E3 ARRAY_SIZE(page_vals_e3) -static const u32 page_write_regs_e2[PAGE_WRITE_REGS_E2] = { 328476 }; +static const u32 page_write_regs_e3[] = { 328476 }; +#define PAGE_WRITE_REGS_E3 ARRAY_SIZE(page_write_regs_e3) -static const struct reg_addr page_read_regs_e2[PAGE_READ_REGS_E2] = { - { 0x58000, 4608, RI_E2_ONLINE } }; +static const struct reg_addr page_read_regs_e3[] = { + { 0x58000, 4608, RI_E3_ONLINE } }; +#define PAGE_READ_REGS_E3 ARRAY_SIZE(page_read_regs_e3) #endif /* BNX2X_DUMP_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 7a133052660..1b4fa1d9800 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -38,8 +38,6 @@ static const struct { char string[ETH_GSTRING_LEN]; } bnx2x_q_stats_arr[] = { /* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%s]: rx_bytes" }, - { Q_STATS_OFFSET32(error_bytes_received_hi), - 8, "[%s]: rx_error_bytes" }, { Q_STATS_OFFSET32(total_unicast_packets_received_hi), 8, "[%s]: rx_ucast_packets" }, { Q_STATS_OFFSET32(total_multicast_packets_received_hi), @@ -53,13 +51,18 @@ static const struct { 4, "[%s]: rx_skb_alloc_discard" }, { Q_STATS_OFFSET32(hw_csum_err), 4, "[%s]: rx_csum_offload_errors" }, -/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%s]: tx_bytes" }, - { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), + { Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%s]: tx_bytes" }, +/* 10 */{ Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), 8, "[%s]: tx_ucast_packets" }, { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi), 8, "[%s]: tx_mcast_packets" }, { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi), - 8, "[%s]: tx_bcast_packets" } + 8, "[%s]: tx_bcast_packets" }, + { Q_STATS_OFFSET32(total_tpa_aggregations_hi), + 8, "[%s]: tpa_aggregations" }, + { Q_STATS_OFFSET32(total_tpa_aggregated_frames_hi), + 8, "[%s]: tpa_aggregated_frames"}, + { Q_STATS_OFFSET32(total_tpa_bytes_hi), 8, "[%s]: tpa_bytes"} }; #define BNX2X_NUM_Q_STATS ARRAY_SIZE(bnx2x_q_stats_arr) @@ -99,8 +102,8 @@ static const struct { 8, STATS_FLAGS_BOTH, "rx_discards" }, { STATS_OFFSET32(mac_filter_discard), 4, STATS_FLAGS_PORT, "rx_filtered_packets" }, - { STATS_OFFSET32(xxoverflow_discard), - 4, STATS_FLAGS_PORT, "rx_fw_discards" }, + { STATS_OFFSET32(mf_tag_discard), + 4, STATS_FLAGS_PORT, "rx_mf_tag_discard" }, { STATS_OFFSET32(brb_drop_hi), 8, STATS_FLAGS_PORT, "rx_brb_discard" }, { STATS_OFFSET32(brb_truncate_hi), @@ -159,7 +162,13 @@ static const struct { { STATS_OFFSET32(etherstatspktsover1522octets_hi), 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" }, { STATS_OFFSET32(pause_frames_sent_hi), - 8, STATS_FLAGS_PORT, "tx_pause_frames" } + 8, STATS_FLAGS_PORT, "tx_pause_frames" }, + { STATS_OFFSET32(total_tpa_aggregations_hi), + 8, STATS_FLAGS_FUNC, "tpa_aggregations" }, + { STATS_OFFSET32(total_tpa_aggregated_frames_hi), + 8, STATS_FLAGS_FUNC, "tpa_aggregated_frames"}, + { STATS_OFFSET32(total_tpa_bytes_hi), + 8, STATS_FLAGS_FUNC, "tpa_bytes"} }; #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) @@ -517,7 +526,7 @@ static int bnx2x_get_regs_len(struct net_device *dev) if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) regdump_len += wreg_addrs_e1h[i].size * (1 + wreg_addrs_e1h[i].read_regs_count); - } else if (CHIP_IS_E2(bp)) { + } else if (!CHIP_IS_E1x(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E2_ONLINE(reg_addrs[i].info)) regdump_len += reg_addrs[i].size; @@ -589,7 +598,7 @@ static void bnx2x_get_regs(struct net_device *dev, dump_hdr.info = RI_E1_ONLINE; else if (CHIP_IS_E1H(bp)) dump_hdr.info = RI_E1H_ONLINE; - else if (CHIP_IS_E2(bp)) + else if (!CHIP_IS_E1x(bp)) dump_hdr.info = RI_E2_ONLINE | (BP_PATH(bp) ? RI_PATH1_DUMP : RI_PATH0_DUMP); @@ -610,14 +619,18 @@ static void bnx2x_get_regs(struct net_device *dev, *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); - } else if (CHIP_IS_E2(bp)) { + } else if (!CHIP_IS_E1x(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E2_ONLINE(reg_addrs[i].info)) for (j = 0; j < reg_addrs[i].size; j++) *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); - bnx2x_read_pages_regs_e2(bp, p); + if (CHIP_IS_E2(bp)) + bnx2x_read_pages_regs_e2(bp, p); + else + /* E3 paged registers read is unimplemented yet */ + WARN_ON(1); } /* Re-enable parity attentions */ bnx2x_clear_blocks_parity(bp); @@ -625,8 +638,6 @@ static void bnx2x_get_regs(struct net_device *dev, bnx2x_enable_blocks_parity(bp); } -#define PHY_FW_VER_LEN 20 - static void bnx2x_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -1334,60 +1345,129 @@ static const struct { { "idle check (online)" } }; +enum { + BNX2X_CHIP_E1_OFST = 0, + BNX2X_CHIP_E1H_OFST, + BNX2X_CHIP_E2_OFST, + BNX2X_CHIP_E3_OFST, + BNX2X_CHIP_E3B0_OFST, + BNX2X_CHIP_MAX_OFST +}; + +#define BNX2X_CHIP_MASK_E1 (1 << BNX2X_CHIP_E1_OFST) +#define BNX2X_CHIP_MASK_E1H (1 << BNX2X_CHIP_E1H_OFST) +#define BNX2X_CHIP_MASK_E2 (1 << BNX2X_CHIP_E2_OFST) +#define BNX2X_CHIP_MASK_E3 (1 << BNX2X_CHIP_E3_OFST) +#define BNX2X_CHIP_MASK_E3B0 (1 << BNX2X_CHIP_E3B0_OFST) + +#define BNX2X_CHIP_MASK_ALL ((1 << BNX2X_CHIP_MAX_OFST) - 1) +#define BNX2X_CHIP_MASK_E1X (BNX2X_CHIP_MASK_E1 | BNX2X_CHIP_MASK_E1H) + static int bnx2x_test_registers(struct bnx2x *bp) { int idx, i, rc = -ENODEV; - u32 wr_val = 0; + u32 wr_val = 0, hw; int port = BP_PORT(bp); static const struct { + u32 hw; u32 offset0; u32 offset1; u32 mask; } reg_tbl[] = { -/* 0 */ { BRB1_REG_PAUSE_LOW_THRESHOLD_0, 4, 0x000003ff }, - { DORQ_REG_DB_ADDR0, 4, 0xffffffff }, - { HC_REG_AGG_INT_0, 4, 0x000003ff }, - { PBF_REG_MAC_IF0_ENABLE, 4, 0x00000001 }, - { PBF_REG_P0_INIT_CRD, 4, 0x000007ff }, - { PRS_REG_CID_PORT_0, 4, 0x00ffffff }, - { PXP2_REG_PSWRQ_CDU0_L2P, 4, 0x000fffff }, - { PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, - { PXP2_REG_PSWRQ_TM0_L2P, 4, 0x000fffff }, - { PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, -/* 10 */ { PXP2_REG_PSWRQ_TSDM0_L2P, 4, 0x000fffff }, - { QM_REG_CONNNUM_0, 4, 0x000fffff }, - { TM_REG_LIN0_MAX_ACTIVE_CID, 4, 0x0003ffff }, - { SRC_REG_KEYRSS0_0, 40, 0xffffffff }, - { SRC_REG_KEYRSS0_7, 40, 0xffffffff }, - { XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 }, - { XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 }, - { XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff }, - { NIG_REG_LLH0_T_BIT, 4, 0x00000001 }, - { NIG_REG_EMAC0_IN_EN, 4, 0x00000001 }, -/* 20 */ { NIG_REG_BMAC0_IN_EN, 4, 0x00000001 }, - { NIG_REG_XCM0_OUT_EN, 4, 0x00000001 }, - { NIG_REG_BRB0_OUT_EN, 4, 0x00000001 }, - { NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 }, - { NIG_REG_LLH0_ACPI_PAT_6_LEN, 68, 0x000000ff }, - { NIG_REG_LLH0_ACPI_PAT_0_CRC, 68, 0xffffffff }, - { NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff }, - { NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff }, - { NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 }, - { NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff }, -/* 30 */ { NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff }, - { NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff }, - { NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 }, - { NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 }, - { NIG_REG_STATUS_INTERRUPT_PORT0, 4, 0x07ffffff }, - { NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 }, - { NIG_REG_SERDES0_CTRL_PHY_ADDR, 16, 0x0000001f }, - - { 0xffffffff, 0, 0x00000000 } +/* 0 */ { BNX2X_CHIP_MASK_ALL, + BRB1_REG_PAUSE_LOW_THRESHOLD_0, 4, 0x000003ff }, + { BNX2X_CHIP_MASK_ALL, + DORQ_REG_DB_ADDR0, 4, 0xffffffff }, + { BNX2X_CHIP_MASK_E1X, + HC_REG_AGG_INT_0, 4, 0x000003ff }, + { BNX2X_CHIP_MASK_ALL, + PBF_REG_MAC_IF0_ENABLE, 4, 0x00000001 }, + { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2 | BNX2X_CHIP_MASK_E3, + PBF_REG_P0_INIT_CRD, 4, 0x000007ff }, + { BNX2X_CHIP_MASK_E3B0, + PBF_REG_INIT_CRD_Q0, 4, 0x000007ff }, + { BNX2X_CHIP_MASK_ALL, + PRS_REG_CID_PORT_0, 4, 0x00ffffff }, + { BNX2X_CHIP_MASK_ALL, + PXP2_REG_PSWRQ_CDU0_L2P, 4, 0x000fffff }, + { BNX2X_CHIP_MASK_ALL, + PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, + { BNX2X_CHIP_MASK_ALL, + PXP2_REG_PSWRQ_TM0_L2P, 4, 0x000fffff }, +/* 10 */ { BNX2X_CHIP_MASK_ALL, + PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, + { BNX2X_CHIP_MASK_ALL, + PXP2_REG_PSWRQ_TSDM0_L2P, 4, 0x000fffff }, + { BNX2X_CHIP_MASK_ALL, + QM_REG_CONNNUM_0, 4, 0x000fffff }, + { BNX2X_CHIP_MASK_ALL, + TM_REG_LIN0_MAX_ACTIVE_CID, 4, 0x0003ffff }, + { BNX2X_CHIP_MASK_ALL, + SRC_REG_KEYRSS0_0, 40, 0xffffffff }, + { BNX2X_CHIP_MASK_ALL, + SRC_REG_KEYRSS0_7, 40, 0xffffffff }, + { BNX2X_CHIP_MASK_ALL, + XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 }, + { BNX2X_CHIP_MASK_ALL, + XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 }, + { BNX2X_CHIP_MASK_ALL, + XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_T_BIT, 4, 0x00000001 }, +/* 20 */ { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2, + NIG_REG_EMAC0_IN_EN, 4, 0x00000001 }, + { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2, + NIG_REG_BMAC0_IN_EN, 4, 0x00000001 }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_XCM0_OUT_EN, 4, 0x00000001 }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_BRB0_OUT_EN, 4, 0x00000001 }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_ACPI_PAT_6_LEN, 68, 0x000000ff }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_ACPI_PAT_0_CRC, 68, 0xffffffff }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 }, +/* 30 */ { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff }, + { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2, + NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 }, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001}, + { BNX2X_CHIP_MASK_ALL, + NIG_REG_STATUS_INTERRUPT_PORT0, 4, 0x07ffffff }, + { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2, + NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 }, + { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2, + NIG_REG_SERDES0_CTRL_PHY_ADDR, 16, 0x0000001f }, + + { BNX2X_CHIP_MASK_ALL, 0xffffffff, 0, 0x00000000 } }; if (!netif_running(bp->dev)) return rc; + if (CHIP_IS_E1(bp)) + hw = BNX2X_CHIP_MASK_E1; + else if (CHIP_IS_E1H(bp)) + hw = BNX2X_CHIP_MASK_E1H; + else if (CHIP_IS_E2(bp)) + hw = BNX2X_CHIP_MASK_E2; + else if (CHIP_IS_E3B0(bp)) + hw = BNX2X_CHIP_MASK_E3B0; + else /* e3 A0 */ + hw = BNX2X_CHIP_MASK_E3; + /* Repeat the test twice: First by writing 0x00000000, second by writing 0xffffffff */ for (idx = 0; idx < 2; idx++) { @@ -1403,8 +1483,7 @@ static int bnx2x_test_registers(struct bnx2x *bp) for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { u32 offset, mask, save_val, val; - if (CHIP_IS_E2(bp) && - reg_tbl[i].offset0 == HC_REG_AGG_INT_0) + if (!(hw & reg_tbl[i].hw)) continue; offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; @@ -1421,7 +1500,7 @@ static int bnx2x_test_registers(struct bnx2x *bp) /* verify value is as expected */ if ((val & mask) != (wr_val & mask)) { - DP(NETIF_MSG_PROBE, + DP(NETIF_MSG_HW, "offset 0x%x: val 0x%x != 0x%x mask 0x%x\n", offset, val, wr_val, mask); goto test_reg_exit; @@ -1438,7 +1517,7 @@ test_reg_exit: static int bnx2x_test_memory(struct bnx2x *bp) { int i, j, rc = -ENODEV; - u32 val; + u32 val, index; static const struct { u32 offset; int size; @@ -1453,32 +1532,44 @@ static int bnx2x_test_memory(struct bnx2x *bp) { 0xffffffff, 0 } }; + static const struct { char *name; u32 offset; - u32 e1_mask; - u32 e1h_mask; - u32 e2_mask; + u32 hw_mask[BNX2X_CHIP_MAX_OFST]; } prty_tbl[] = { - { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0, 0 }, - { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2, 0 }, - { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0, 0 }, - { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0, 0 }, - { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0, 0 }, - { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0, 0 }, - - { NULL, 0xffffffff, 0, 0, 0 } + { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, + {0x3ffc0, 0, 0, 0} }, + { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, + {0x2, 0x2, 0, 0} }, + { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, + {0, 0, 0, 0} }, + { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, + {0x3ffc0, 0, 0, 0} }, + { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, + {0x3ffc0, 0, 0, 0} }, + { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, + {0x3ffc1, 0, 0, 0} }, + + { NULL, 0xffffffff, {0, 0, 0, 0} } }; if (!netif_running(bp->dev)) return rc; + if (CHIP_IS_E1(bp)) + index = BNX2X_CHIP_E1_OFST; + else if (CHIP_IS_E1H(bp)) + index = BNX2X_CHIP_E1H_OFST; + else if (CHIP_IS_E2(bp)) + index = BNX2X_CHIP_E2_OFST; + else /* e3 */ + index = BNX2X_CHIP_E3_OFST; + /* pre-Check the parity status */ for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { val = REG_RD(bp, prty_tbl[i].offset); - if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || - (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || - (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { + if (val & ~(prty_tbl[i].hw_mask[index])) { DP(NETIF_MSG_HW, "%s is 0x%x\n", prty_tbl[i].name, val); goto test_mem_exit; @@ -1493,9 +1584,7 @@ static int bnx2x_test_memory(struct bnx2x *bp) /* Check the parity status */ for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { val = REG_RD(bp, prty_tbl[i].offset); - if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || - (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || - (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { + if (val & ~(prty_tbl[i].hw_mask[index])) { DP(NETIF_MSG_HW, "%s is 0x%x\n", prty_tbl[i].name, val); goto test_mem_exit; @@ -1512,12 +1601,16 @@ static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) { int cnt = 1400; - if (link_up) + if (link_up) { while (bnx2x_link_test(bp, is_serdes) && cnt--) - msleep(10); + msleep(20); + + if (cnt <= 0 && bnx2x_link_test(bp, is_serdes)) + DP(NETIF_MSG_LINK, "Timeout waiting for link up\n"); + } } -static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) +static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) { unsigned int pkt_size, num_pkts, i; struct sk_buff *skb; @@ -1526,14 +1619,14 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) struct bnx2x_fastpath *fp_tx = &bp->fp[0]; u16 tx_start_idx, tx_idx; u16 rx_start_idx, rx_idx; - u16 pkt_prod, bd_prod; + u16 pkt_prod, bd_prod, rx_comp_cons; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; dma_addr_t mapping; union eth_rx_cqe *cqe; - u8 cqe_fp_flags; + u8 cqe_fp_flags, cqe_fp_type; struct sw_rx_bd *rx_buf; u16 len; int rc = -ENODEV; @@ -1545,7 +1638,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) return -EINVAL; break; case BNX2X_MAC_LOOPBACK: - bp->link_params.loopback_mode = LOOPBACK_BMAC; + bp->link_params.loopback_mode = CHIP_IS_E3(bp) ? + LOOPBACK_XMAC : LOOPBACK_BMAC; bnx2x_phy_init(&bp->link_params, &bp->link_vars); break; default: @@ -1566,6 +1660,14 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN)); for (i = ETH_HLEN; i < pkt_size; i++) packet[i] = (unsigned char) (i & 0xff); + mapping = dma_map_single(&bp->pdev->dev, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + rc = -ENOMEM; + dev_kfree_skb(skb); + BNX2X_ERR("Unable to map SKB\n"); + goto test_loopback_exit; + } /* send the loopback packet */ num_pkts = 0; @@ -1580,8 +1682,6 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) bd_prod = TX_BD(fp_tx->tx_bd_prod); tx_start_bd = &fp_tx->tx_desc_ring[bd_prod].start_bd; - mapping = dma_map_single(&bp->pdev->dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */ @@ -1611,6 +1711,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) DOORBELL(bp, fp_tx->index, fp_tx->tx_db.raw); mmiowb(); + barrier(); num_pkts++; fp_tx->tx_bd_prod += 2; /* start + pbd */ @@ -1639,9 +1740,11 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) if (rx_idx != rx_start_idx + num_pkts) goto test_loopback_exit; - cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)]; + rx_comp_cons = le16_to_cpu(fp_rx->rx_comp_cons); + cqe = &fp_rx->rx_comp_ring[RCQ_BD(rx_comp_cons)]; cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; - if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS)) + cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE; + if (!CQE_TYPE_FAST(cqe_fp_type) || (cqe_fp_flags & ETH_RX_ERROR_FALGS)) goto test_loopback_rx_exit; len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); @@ -1649,6 +1752,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) goto test_loopback_rx_exit; rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)]; + dma_sync_single_for_device(&bp->pdev->dev, + dma_unmap_addr(rx_buf, mapping), + fp_rx->rx_buf_size, DMA_FROM_DEVICE); skb = rx_buf->skb; skb_reserve(skb, cqe->fast_path_cqe.placement_offset); for (i = ETH_HLEN; i < pkt_size; i++) @@ -1674,7 +1780,7 @@ test_loopback_exit: return rc; } -static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) +static int bnx2x_test_loopback(struct bnx2x *bp) { int rc = 0, res; @@ -1687,13 +1793,13 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) bnx2x_netif_stop(bp, 1); bnx2x_acquire_phy_lock(bp); - res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up); + res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK); if (res) { DP(NETIF_MSG_PROBE, " PHY loopback failed (res %d)\n", res); rc |= BNX2X_PHY_LOOPBACK_FAILED; } - res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up); + res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK); if (res) { DP(NETIF_MSG_PROBE, " MAC loopback failed (res %d)\n", res); rc |= BNX2X_MAC_LOOPBACK_FAILED; @@ -1765,39 +1871,20 @@ test_nvram_exit: return rc; } +/* Send an EMPTY ramrod on the first queue */ static int bnx2x_test_intr(struct bnx2x *bp) { - struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); - int i, rc; + struct bnx2x_queue_state_params params = {0}; if (!netif_running(bp->dev)) return -ENODEV; - config->hdr.length = 0; - if (CHIP_IS_E1(bp)) - config->hdr.offset = (BP_PORT(bp) ? 32 : 0); - else - config->hdr.offset = BP_FUNC(bp); - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending = 1; - smp_wmb(); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); - if (rc == 0) { - for (i = 0; i < 10; i++) { - if (!bp->set_mac_pending) - break; - smp_rmb(); - msleep_interruptible(10); - } - if (i == 10) - rc = -ENODEV; - } + params.q_obj = &bp->fp->q_obj; + params.cmd = BNX2X_Q_CMD_EMPTY; - return rc; + __set_bit(RAMROD_COMP_WAIT, ¶ms.ramrod_flags); + + return bnx2x_queue_state_change(bp, ¶ms); } static void bnx2x_self_test(struct net_device *dev, @@ -1836,7 +1923,7 @@ static void bnx2x_self_test(struct net_device *dev, bnx2x_nic_unload(bp, UNLOAD_NORMAL); bnx2x_nic_load(bp, LOAD_DIAG); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up, is_serdes); + bnx2x_wait_for_link(bp, 1, is_serdes); if (bnx2x_test_registers(bp) != 0) { buf[0] = 1; @@ -1847,7 +1934,7 @@ static void bnx2x_self_test(struct net_device *dev, etest->flags |= ETH_TEST_FL_FAILED; } - buf[2] = bnx2x_test_loopback(bp, link_up); + buf[2] = bnx2x_test_loopback(bp); if (buf[2] != 0) etest->flags |= ETH_TEST_FL_FAILED; @@ -1885,6 +1972,14 @@ static void bnx2x_self_test(struct net_device *dev, #define IS_MF_MODE_STAT(bp) \ (IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) +/* ethtool statistics are displayed for all regular ethernet queues and the + * fcoe L2 queue if not disabled + */ +static inline int bnx2x_num_stat_queues(struct bnx2x *bp) +{ + return BNX2X_NUM_ETH_QUEUES(bp); +} + static int bnx2x_get_sset_count(struct net_device *dev, int stringset) { struct bnx2x *bp = netdev_priv(dev); @@ -1893,7 +1988,7 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) switch (stringset) { case ETH_SS_STATS: if (is_multi(bp)) { - num_stats = BNX2X_NUM_STAT_QUEUES(bp) * + num_stats = bnx2x_num_stat_queues(bp) * BNX2X_NUM_Q_STATS; if (!IS_MF_MODE_STAT(bp)) num_stats += BNX2X_NUM_STATS; @@ -1926,14 +2021,9 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) case ETH_SS_STATS: if (is_multi(bp)) { k = 0; - for_each_napi_queue(bp, i) { + for_each_eth_queue(bp, i) { memset(queue_name, 0, sizeof(queue_name)); - - if (IS_FCOE_IDX(i)) - sprintf(queue_name, "fcoe"); - else - sprintf(queue_name, "%d", i); - + sprintf(queue_name, "%d", i); for (j = 0; j < BNX2X_NUM_Q_STATS; j++) snprintf(buf + (k + j)*ETH_GSTRING_LEN, ETH_GSTRING_LEN, @@ -1972,7 +2062,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, if (is_multi(bp)) { k = 0; - for_each_napi_queue(bp, i) { + for_each_eth_queue(bp, i) { hw_stats = (u32 *)&bp->fp[i].eth_q_stats; for (j = 0; j < BNX2X_NUM_Q_STATS; j++) { if (bnx2x_q_stats_arr[j].size == 0) { @@ -2090,14 +2180,30 @@ static int bnx2x_get_rxfh_indir(struct net_device *dev, { struct bnx2x *bp = netdev_priv(dev); size_t copy_size = - min_t(size_t, indir->size, TSTORM_INDIRECTION_TABLE_SIZE); + min_t(size_t, indir->size, T_ETH_INDIRECTION_TABLE_SIZE); + u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0}; + size_t i; if (bp->multi_mode == ETH_RSS_MODE_DISABLED) return -EOPNOTSUPP; - indir->size = TSTORM_INDIRECTION_TABLE_SIZE; - memcpy(indir->ring_index, bp->rx_indir_table, - copy_size * sizeof(bp->rx_indir_table[0])); + /* Get the current configuration of the RSS indirection table */ + bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table); + + /* + * We can't use a memcpy() as an internal storage of an + * indirection table is a u8 array while indir->ring_index + * points to an array of u32. + * + * Indirection table contains the FW Client IDs, so we need to + * align the returned table to the Client ID of the leading RSS + * queue. + */ + for (i = 0; i < copy_size; i++) + indir->ring_index[i] = ind_table[i] - bp->fp->cl_id; + + indir->size = T_ETH_INDIRECTION_TABLE_SIZE; + return 0; } @@ -2106,21 +2212,33 @@ static int bnx2x_set_rxfh_indir(struct net_device *dev, { struct bnx2x *bp = netdev_priv(dev); size_t i; + u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0}; + u32 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp); if (bp->multi_mode == ETH_RSS_MODE_DISABLED) return -EOPNOTSUPP; - /* Validate size and indices */ - if (indir->size != TSTORM_INDIRECTION_TABLE_SIZE) + /* validate the size */ + if (indir->size != T_ETH_INDIRECTION_TABLE_SIZE) return -EINVAL; - for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) - if (indir->ring_index[i] >= BNX2X_NUM_ETH_QUEUES(bp)) + + for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) { + /* validate the indices */ + if (indir->ring_index[i] >= num_eth_queues) return -EINVAL; + /* + * The same as in bnx2x_get_rxfh_indir: we can't use a memcpy() + * as an internal storage of an indirection table is a u8 array + * while indir->ring_index points to an array of u32. + * + * Indirection table contains the FW Client IDs, so we need to + * align the received table to the Client ID of the leading RSS + * queue + */ + ind_table[i] = indir->ring_index[i] + bp->fp->cl_id; + } - memcpy(bp->rx_indir_table, indir->ring_index, - indir->size * sizeof(bp->rx_indir_table[0])); - bnx2x_push_indir_table(bp); - return 0; + return bnx2x_config_rss_pf(bp, ind_table, false); } static const struct ethtool_ops bnx2x_ethtool_ops = { diff --git a/drivers/net/bnx2x/bnx2x_fw_defs.h b/drivers/net/bnx2x/bnx2x_fw_defs.h index 9fe367836a5..998652a1b85 100644 --- a/drivers/net/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/bnx2x/bnx2x_fw_defs.h @@ -10,249 +10,221 @@ #ifndef BNX2X_FW_DEFS_H #define BNX2X_FW_DEFS_H -#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[142].base) +#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[148].base) #define CSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ - (IRO[141].base + ((assertListEntry) * IRO[141].m1)) -#define CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ - (IRO[144].base + ((pfId) * IRO[144].m1)) + (IRO[147].base + ((assertListEntry) * IRO[147].m1)) #define CSTORM_EVENT_RING_DATA_OFFSET(pfId) \ - (IRO[149].base + (((pfId)>>1) * IRO[149].m1) + (((pfId)&1) * \ - IRO[149].m2)) + (IRO[153].base + (((pfId)>>1) * IRO[153].m1) + (((pfId)&1) * \ + IRO[153].m2)) #define CSTORM_EVENT_RING_PROD_OFFSET(pfId) \ - (IRO[150].base + (((pfId)>>1) * IRO[150].m1) + (((pfId)&1) * \ - IRO[150].m2)) + (IRO[154].base + (((pfId)>>1) * IRO[154].m1) + (((pfId)&1) * \ + IRO[154].m2)) #define CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(funcId) \ - (IRO[156].base + ((funcId) * IRO[156].m1)) + (IRO[159].base + ((funcId) * IRO[159].m1)) #define CSTORM_FUNC_EN_OFFSET(funcId) \ - (IRO[146].base + ((funcId) * IRO[146].m1)) -#define CSTORM_FUNCTION_MODE_OFFSET (IRO[153].base) -#define CSTORM_IGU_MODE_OFFSET (IRO[154].base) + (IRO[149].base + ((funcId) * IRO[149].m1)) +#define CSTORM_IGU_MODE_OFFSET (IRO[157].base) #define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ - (IRO[311].base + ((pfId) * IRO[311].m1)) + (IRO[315].base + ((pfId) * IRO[315].m1)) #define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ - (IRO[312].base + ((pfId) * IRO[312].m1)) - #define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \ - (IRO[304].base + ((pfId) * IRO[304].m1) + ((iscsiEqId) * \ - IRO[304].m2)) - #define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \ - (IRO[306].base + ((pfId) * IRO[306].m1) + ((iscsiEqId) * \ - IRO[306].m2)) - #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ - (IRO[305].base + ((pfId) * IRO[305].m1) + ((iscsiEqId) * \ - IRO[305].m2)) - #define \ - CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \ - (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * \ - IRO[307].m2)) - #define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \ - (IRO[303].base + ((pfId) * IRO[303].m1) + ((iscsiEqId) * \ - IRO[303].m2)) - #define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \ - (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * \ - IRO[309].m2)) - #define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ - (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * \ - IRO[308].m2)) + (IRO[316].base + ((pfId) * IRO[316].m1)) +#define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \ + (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * IRO[308].m2)) +#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2)) +#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2)) +#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \ + (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2)) +#define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \ + (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * IRO[307].m2)) +#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \ + (IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2)) +#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ + (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2)) #define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ - (IRO[310].base + ((pfId) * IRO[310].m1)) + (IRO[314].base + ((pfId) * IRO[314].m1)) #define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[302].base + ((pfId) * IRO[302].m1)) + (IRO[306].base + ((pfId) * IRO[306].m1)) #define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ - (IRO[301].base + ((pfId) * IRO[301].m1)) + (IRO[305].base + ((pfId) * IRO[305].m1)) #define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ - (IRO[300].base + ((pfId) * IRO[300].m1)) -#define CSTORM_PATH_ID_OFFSET (IRO[159].base) + (IRO[304].base + ((pfId) * IRO[304].m1)) +#define CSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ + (IRO[151].base + ((funcId) * IRO[151].m1)) #define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \ - (IRO[137].base + ((pfId) * IRO[137].m1)) + (IRO[142].base + ((pfId) * IRO[142].m1)) +#define CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(pfId) \ + (IRO[143].base + ((pfId) * IRO[143].m1)) #define CSTORM_SP_STATUS_BLOCK_OFFSET(pfId) \ - (IRO[136].base + ((pfId) * IRO[136].m1)) -#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[136].size) + (IRO[141].base + ((pfId) * IRO[141].m1)) +#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[141].size) #define CSTORM_SP_SYNC_BLOCK_OFFSET(pfId) \ - (IRO[138].base + ((pfId) * IRO[138].m1)) -#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[138].size) -#define CSTORM_STATS_FLAGS_OFFSET(pfId) \ - (IRO[143].base + ((pfId) * IRO[143].m1)) + (IRO[144].base + ((pfId) * IRO[144].m1)) +#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[144].size) +#define CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(sbId, hcIndex) \ + (IRO[136].base + ((sbId) * IRO[136].m1) + ((hcIndex) * IRO[136].m2)) #define CSTORM_STATUS_BLOCK_DATA_OFFSET(sbId) \ - (IRO[129].base + ((sbId) * IRO[129].m1)) + (IRO[133].base + ((sbId) * IRO[133].m1)) +#define CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(sbId) \ + (IRO[134].base + ((sbId) * IRO[134].m1)) +#define CSTORM_STATUS_BLOCK_DATA_TIMEOUT_OFFSET(sbId, hcIndex) \ + (IRO[135].base + ((sbId) * IRO[135].m1) + ((hcIndex) * IRO[135].m2)) #define CSTORM_STATUS_BLOCK_OFFSET(sbId) \ - (IRO[128].base + ((sbId) * IRO[128].m1)) -#define CSTORM_STATUS_BLOCK_SIZE (IRO[128].size) -#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \ (IRO[132].base + ((sbId) * IRO[132].m1)) -#define CSTORM_SYNC_BLOCK_SIZE (IRO[132].size) +#define CSTORM_STATUS_BLOCK_SIZE (IRO[132].size) +#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \ + (IRO[137].base + ((sbId) * IRO[137].m1)) +#define CSTORM_SYNC_BLOCK_SIZE (IRO[137].size) #define CSTORM_VF_PF_CHANNEL_STATE_OFFSET(vfId) \ - (IRO[151].base + ((vfId) * IRO[151].m1)) + (IRO[155].base + ((vfId) * IRO[155].m1)) #define CSTORM_VF_PF_CHANNEL_VALID_OFFSET(vfId) \ - (IRO[152].base + ((vfId) * IRO[152].m1)) + (IRO[156].base + ((vfId) * IRO[156].m1)) #define CSTORM_VF_TO_PF_OFFSET(funcId) \ - (IRO[147].base + ((funcId) * IRO[147].m1)) -#define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[199].base) + (IRO[150].base + ((funcId) * IRO[150].m1)) +#define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[204].base) #define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \ - (IRO[198].base + ((pfId) * IRO[198].m1)) -#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[99].base) + (IRO[203].base + ((pfId) * IRO[203].m1)) +#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[102].base) #define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ - (IRO[98].base + ((assertListEntry) * IRO[98].m1)) - #define TSTORM_CLIENT_CONFIG_OFFSET(portId, clientId) \ - (IRO[197].base + ((portId) * IRO[197].m1) + ((clientId) * \ - IRO[197].m2)) -#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET (IRO[104].base) + (IRO[101].base + ((assertListEntry) * IRO[101].m1)) +#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET (IRO[107].base) #define TSTORM_COMMON_SAFC_WORKAROUND_TIMEOUT_10USEC_OFFSET \ - (IRO[105].base) -#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ - (IRO[96].base + ((pfId) * IRO[96].m1)) -#define TSTORM_FUNC_EN_OFFSET(funcId) \ - (IRO[101].base + ((funcId) * IRO[101].m1)) + (IRO[108].base) #define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \ - (IRO[195].base + ((pfId) * IRO[195].m1)) -#define TSTORM_FUNCTION_MODE_OFFSET (IRO[103].base) -#define TSTORM_INDIRECTION_TABLE_OFFSET(pfId) \ - (IRO[91].base + ((pfId) * IRO[91].m1)) -#define TSTORM_INDIRECTION_TABLE_SIZE (IRO[91].size) - #define \ - TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfId, iscsiConBufPblEntry) \ - (IRO[260].base + ((pfId) * IRO[260].m1) + ((iscsiConBufPblEntry) \ - * IRO[260].m2)) + (IRO[201].base + ((pfId) * IRO[201].m1)) +#define TSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[103].base + ((funcId) * IRO[103].m1)) #define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ - (IRO[264].base + ((pfId) * IRO[264].m1)) + (IRO[271].base + ((pfId) * IRO[271].m1)) #define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \ - (IRO[265].base + ((pfId) * IRO[265].m1)) + (IRO[272].base + ((pfId) * IRO[272].m1)) #define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \ - (IRO[266].base + ((pfId) * IRO[266].m1)) + (IRO[273].base + ((pfId) * IRO[273].m1)) #define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \ - (IRO[267].base + ((pfId) * IRO[267].m1)) + (IRO[274].base + ((pfId) * IRO[274].m1)) #define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[263].base + ((pfId) * IRO[263].m1)) + (IRO[270].base + ((pfId) * IRO[270].m1)) #define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ - (IRO[262].base + ((pfId) * IRO[262].m1)) + (IRO[269].base + ((pfId) * IRO[269].m1)) #define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ - (IRO[261].base + ((pfId) * IRO[261].m1)) + (IRO[268].base + ((pfId) * IRO[268].m1)) #define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ - (IRO[259].base + ((pfId) * IRO[259].m1)) + (IRO[267].base + ((pfId) * IRO[267].m1)) #define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \ - (IRO[269].base + ((pfId) * IRO[269].m1)) + (IRO[276].base + ((pfId) * IRO[276].m1)) #define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ - (IRO[256].base + ((pfId) * IRO[256].m1)) + (IRO[263].base + ((pfId) * IRO[263].m1)) #define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ - (IRO[257].base + ((pfId) * IRO[257].m1)) + (IRO[264].base + ((pfId) * IRO[264].m1)) +#define TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfId) \ + (IRO[265].base + ((pfId) * IRO[265].m1)) #define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ - (IRO[258].base + ((pfId) * IRO[258].m1)) + (IRO[266].base + ((pfId) * IRO[266].m1)) #define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \ - (IRO[196].base + ((pfId) * IRO[196].m1)) - #define TSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, tStatCntId) \ - (IRO[100].base + ((portId) * IRO[100].m1) + ((tStatCntId) * \ - IRO[100].m2)) -#define TSTORM_STATS_FLAGS_OFFSET(pfId) \ - (IRO[95].base + ((pfId) * IRO[95].m1)) + (IRO[202].base + ((pfId) * IRO[202].m1)) +#define TSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ + (IRO[105].base + ((funcId) * IRO[105].m1)) #define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \ - (IRO[211].base + ((pfId) * IRO[211].m1)) + (IRO[216].base + ((pfId) * IRO[216].m1)) #define TSTORM_VF_TO_PF_OFFSET(funcId) \ - (IRO[102].base + ((funcId) * IRO[102].m1)) -#define USTORM_AGG_DATA_OFFSET (IRO[201].base) -#define USTORM_AGG_DATA_SIZE (IRO[201].size) -#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[170].base) + (IRO[104].base + ((funcId) * IRO[104].m1)) +#define USTORM_AGG_DATA_OFFSET (IRO[206].base) +#define USTORM_AGG_DATA_SIZE (IRO[206].size) +#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[177].base) #define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \ - (IRO[169].base + ((assertListEntry) * IRO[169].m1)) + (IRO[176].base + ((assertListEntry) * IRO[176].m1)) +#define USTORM_CQE_PAGE_NEXT_OFFSET(portId, clientId) \ + (IRO[205].base + ((portId) * IRO[205].m1) + ((clientId) * \ + IRO[205].m2)) #define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \ - (IRO[178].base + ((portId) * IRO[178].m1)) -#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ - (IRO[172].base + ((pfId) * IRO[172].m1)) + (IRO[183].base + ((portId) * IRO[183].m1)) #define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \ - (IRO[313].base + ((pfId) * IRO[313].m1)) + (IRO[317].base + ((pfId) * IRO[317].m1)) #define USTORM_FUNC_EN_OFFSET(funcId) \ - (IRO[174].base + ((funcId) * IRO[174].m1)) -#define USTORM_FUNCTION_MODE_OFFSET (IRO[177].base) + (IRO[178].base + ((funcId) * IRO[178].m1)) #define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ - (IRO[277].base + ((pfId) * IRO[277].m1)) + (IRO[281].base + ((pfId) * IRO[281].m1)) #define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ - (IRO[278].base + ((pfId) * IRO[278].m1)) -#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ (IRO[282].base + ((pfId) * IRO[282].m1)) +#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ + (IRO[286].base + ((pfId) * IRO[286].m1)) #define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \ - (IRO[279].base + ((pfId) * IRO[279].m1)) + (IRO[283].base + ((pfId) * IRO[283].m1)) #define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[275].base + ((pfId) * IRO[275].m1)) + (IRO[279].base + ((pfId) * IRO[279].m1)) #define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ - (IRO[274].base + ((pfId) * IRO[274].m1)) + (IRO[278].base + ((pfId) * IRO[278].m1)) #define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ - (IRO[273].base + ((pfId) * IRO[273].m1)) + (IRO[277].base + ((pfId) * IRO[277].m1)) #define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ - (IRO[276].base + ((pfId) * IRO[276].m1)) -#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \ (IRO[280].base + ((pfId) * IRO[280].m1)) +#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \ + (IRO[284].base + ((pfId) * IRO[284].m1)) #define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ - (IRO[281].base + ((pfId) * IRO[281].m1)) + (IRO[285].base + ((pfId) * IRO[285].m1)) #define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \ - (IRO[176].base + ((pfId) * IRO[176].m1)) - #define USTORM_PER_COUNTER_ID_STATS_OFFSET(portId, uStatCntId) \ - (IRO[173].base + ((portId) * IRO[173].m1) + ((uStatCntId) * \ - IRO[173].m2)) - #define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \ - (IRO[204].base + ((portId) * IRO[204].m1) + ((clientId) * \ - IRO[204].m2)) + (IRO[182].base + ((pfId) * IRO[182].m1)) +#define USTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ + (IRO[180].base + ((funcId) * IRO[180].m1)) +#define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \ + (IRO[209].base + ((portId) * IRO[209].m1) + ((clientId) * \ + IRO[209].m2)) #define USTORM_RX_PRODS_E2_OFFSET(qzoneId) \ - (IRO[205].base + ((qzoneId) * IRO[205].m1)) -#define USTORM_STATS_FLAGS_OFFSET(pfId) \ - (IRO[171].base + ((pfId) * IRO[171].m1)) -#define USTORM_TPA_BTR_OFFSET (IRO[202].base) -#define USTORM_TPA_BTR_SIZE (IRO[202].size) + (IRO[210].base + ((qzoneId) * IRO[210].m1)) +#define USTORM_TPA_BTR_OFFSET (IRO[207].base) +#define USTORM_TPA_BTR_SIZE (IRO[207].size) #define USTORM_VF_TO_PF_OFFSET(funcId) \ - (IRO[175].base + ((funcId) * IRO[175].m1)) -#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[59].base) -#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[58].base) -#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[54].base) + (IRO[179].base + ((funcId) * IRO[179].m1)) +#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[67].base) +#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[66].base) +#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[51].base) #define XSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ - (IRO[53].base + ((assertListEntry) * IRO[53].m1)) + (IRO[50].base + ((assertListEntry) * IRO[50].m1)) #define XSTORM_CMNG_PER_PORT_VARS_OFFSET(portId) \ - (IRO[47].base + ((portId) * IRO[47].m1)) -#define XSTORM_E1HOV_OFFSET(pfId) \ - (IRO[55].base + ((pfId) * IRO[55].m1)) -#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ - (IRO[45].base + ((pfId) * IRO[45].m1)) + (IRO[43].base + ((portId) * IRO[43].m1)) #define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(pfId) \ - (IRO[49].base + ((pfId) * IRO[49].m1)) + (IRO[45].base + ((pfId) * IRO[45].m1)) #define XSTORM_FUNC_EN_OFFSET(funcId) \ - (IRO[51].base + ((funcId) * IRO[51].m1)) -#define XSTORM_FUNCTION_MODE_OFFSET (IRO[56].base) + (IRO[47].base + ((funcId) * IRO[47].m1)) #define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ - (IRO[290].base + ((pfId) * IRO[290].m1)) + (IRO[294].base + ((pfId) * IRO[294].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \ - (IRO[293].base + ((pfId) * IRO[293].m1)) + (IRO[297].base + ((pfId) * IRO[297].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \ - (IRO[294].base + ((pfId) * IRO[294].m1)) + (IRO[298].base + ((pfId) * IRO[298].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \ - (IRO[295].base + ((pfId) * IRO[295].m1)) + (IRO[299].base + ((pfId) * IRO[299].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \ - (IRO[296].base + ((pfId) * IRO[296].m1)) + (IRO[300].base + ((pfId) * IRO[300].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \ - (IRO[297].base + ((pfId) * IRO[297].m1)) + (IRO[301].base + ((pfId) * IRO[301].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \ - (IRO[298].base + ((pfId) * IRO[298].m1)) + (IRO[302].base + ((pfId) * IRO[302].m1)) #define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \ - (IRO[299].base + ((pfId) * IRO[299].m1)) + (IRO[303].base + ((pfId) * IRO[303].m1)) #define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[289].base + ((pfId) * IRO[289].m1)) + (IRO[293].base + ((pfId) * IRO[293].m1)) #define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ - (IRO[288].base + ((pfId) * IRO[288].m1)) + (IRO[292].base + ((pfId) * IRO[292].m1)) #define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ - (IRO[287].base + ((pfId) * IRO[287].m1)) + (IRO[291].base + ((pfId) * IRO[291].m1)) #define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ - (IRO[292].base + ((pfId) * IRO[292].m1)) + (IRO[296].base + ((pfId) * IRO[296].m1)) #define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \ - (IRO[291].base + ((pfId) * IRO[291].m1)) + (IRO[295].base + ((pfId) * IRO[295].m1)) #define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \ - (IRO[286].base + ((pfId) * IRO[286].m1)) + (IRO[290].base + ((pfId) * IRO[290].m1)) #define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ - (IRO[285].base + ((pfId) * IRO[285].m1)) + (IRO[289].base + ((pfId) * IRO[289].m1)) #define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \ - (IRO[284].base + ((pfId) * IRO[284].m1)) + (IRO[288].base + ((pfId) * IRO[288].m1)) #define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \ - (IRO[283].base + ((pfId) * IRO[283].m1)) -#define XSTORM_PATH_ID_OFFSET (IRO[65].base) - #define XSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, xStatCntId) \ - (IRO[50].base + ((portId) * IRO[50].m1) + ((xStatCntId) * \ - IRO[50].m2)) + (IRO[287].base + ((pfId) * IRO[287].m1)) #define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \ - (IRO[48].base + ((pfId) * IRO[48].m1)) + (IRO[44].base + ((pfId) * IRO[44].m1)) +#define XSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ + (IRO[49].base + ((funcId) * IRO[49].m1)) #define XSTORM_SPQ_DATA_OFFSET(funcId) \ (IRO[32].base + ((funcId) * IRO[32].m1)) #define XSTORM_SPQ_DATA_SIZE (IRO[32].size) @@ -260,42 +232,37 @@ (IRO[30].base + ((funcId) * IRO[30].m1)) #define XSTORM_SPQ_PROD_OFFSET(funcId) \ (IRO[31].base + ((funcId) * IRO[31].m1)) -#define XSTORM_STATS_FLAGS_OFFSET(pfId) \ - (IRO[43].base + ((pfId) * IRO[43].m1)) #define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(portId) \ - (IRO[206].base + ((portId) * IRO[206].m1)) + (IRO[211].base + ((portId) * IRO[211].m1)) #define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(portId) \ - (IRO[207].base + ((portId) * IRO[207].m1)) + (IRO[212].base + ((portId) * IRO[212].m1)) #define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfId) \ - (IRO[209].base + (((pfId)>>1) * IRO[209].m1) + (((pfId)&1) * \ - IRO[209].m2)) + (IRO[214].base + (((pfId)>>1) * IRO[214].m1) + (((pfId)&1) * \ + IRO[214].m2)) #define XSTORM_VF_TO_PF_OFFSET(funcId) \ - (IRO[52].base + ((funcId) * IRO[52].m1)) + (IRO[48].base + ((funcId) * IRO[48].m1)) #define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0 -/* RSS hash types */ -#define DEFAULT_HASH_TYPE 0 -#define IPV4_HASH_TYPE 1 -#define TCP_IPV4_HASH_TYPE 2 -#define IPV6_HASH_TYPE 3 -#define TCP_IPV6_HASH_TYPE 4 -#define VLAN_PRI_HASH_TYPE 5 -#define E1HOV_PRI_HASH_TYPE 6 -#define DSCP_HASH_TYPE 7 +/** +* This file defines HSI constants for the ETH flow +*/ +#ifdef _EVEREST_MICROCODE +#include "Microcode\Generated\DataTypes\eth_rx_bd.h" +#include "Microcode\Generated\DataTypes\eth_tx_bd.h" +#include "Microcode\Generated\DataTypes\eth_rx_cqe.h" +#include "Microcode\Generated\DataTypes\eth_rx_sge.h" +#include "Microcode\Generated\DataTypes\eth_rx_cqe_next_page.h" +#endif /* Ethernet Ring parameters */ #define X_ETH_LOCAL_RING_SIZE 13 -#define FIRST_BD_IN_PKT 0 +#define FIRST_BD_IN_PKT 0 #define PARSE_BD_INDEX 1 #define NUM_OF_ETH_BDS_IN_PAGE ((PAGE_SIZE)/(STRUCT_SIZE(eth_tx_bd)/8)) #define U_ETH_NUM_OF_SGES_TO_FETCH 8 #define U_ETH_MAX_SGES_FOR_PACKET 3 -/*Tx params*/ -#define X_ETH_NO_VLAN 0 -#define X_ETH_OUTBAND_VLAN 1 -#define X_ETH_INBAND_VLAN 2 /* Rx ring params */ #define U_ETH_LOCAL_BD_RING_SIZE 8 #define U_ETH_LOCAL_SGE_RING_SIZE 10 @@ -311,79 +278,64 @@ #define U_ETH_BDS_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8)) #define U_ETH_SGES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8)) -#define U_ETH_BDS_PER_PAGE_MASK (U_ETH_BDS_PER_PAGE-1) -#define U_ETH_CQE_PER_PAGE_MASK (TU_ETH_CQES_PER_PAGE-1) +#define U_ETH_BDS_PER_PAGE_MASK (U_ETH_BDS_PER_PAGE-1) +#define U_ETH_CQE_PER_PAGE_MASK (TU_ETH_CQES_PER_PAGE-1) #define U_ETH_SGES_PER_PAGE_MASK (U_ETH_SGES_PER_PAGE-1) #define U_ETH_UNDEFINED_Q 0xFF -/* values of command IDs in the ramrod message */ -#define RAMROD_CMD_ID_ETH_UNUSED 0 -#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 1 -#define RAMROD_CMD_ID_ETH_UPDATE 2 -#define RAMROD_CMD_ID_ETH_HALT 3 -#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 4 -#define RAMROD_CMD_ID_ETH_ACTIVATE 5 -#define RAMROD_CMD_ID_ETH_DEACTIVATE 6 -#define RAMROD_CMD_ID_ETH_EMPTY 7 -#define RAMROD_CMD_ID_ETH_TERMINATE 8 - -/* command values for set mac command */ -#define T_ETH_MAC_COMMAND_SET 0 -#define T_ETH_MAC_COMMAND_INVALIDATE 1 - #define T_ETH_INDIRECTION_TABLE_SIZE 128 +#define T_ETH_RSS_KEY 10 +#define ETH_NUM_OF_RSS_ENGINES_E2 72 + +#define FILTER_RULES_COUNT 16 +#define MULTICAST_RULES_COUNT 16 +#define CLASSIFY_RULES_COUNT 16 /*The CRC32 seed, that is used for the hash(reduction) multicast address */ -#define T_ETH_CRC32_HASH_SEED 0x00000000 +#define ETH_CRC32_HASH_SEED 0x00000000 + +#define ETH_CRC32_HASH_BIT_SIZE (8) +#define ETH_CRC32_HASH_MASK EVAL((1<= 10G) */ -#define PORT_FEATURE_CON_SWITCH_10G_SWITCH 0x01000000 -#define PORT_FEATURE_CON_SWITCH_AUTO_DETECT 0x02000000 -#define PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT 0x03000000 - -#define PORT_FEATURE_LINK_SPEED_MASK 0x000f0000 -#define PORT_FEATURE_LINK_SPEED_SHIFT 16 -#define PORT_FEATURE_LINK_SPEED_AUTO 0x00000000 -#define PORT_FEATURE_LINK_SPEED_10M_FULL 0x00010000 -#define PORT_FEATURE_LINK_SPEED_10M_HALF 0x00020000 -#define PORT_FEATURE_LINK_SPEED_100M_HALF 0x00030000 -#define PORT_FEATURE_LINK_SPEED_100M_FULL 0x00040000 -#define PORT_FEATURE_LINK_SPEED_1G 0x00050000 -#define PORT_FEATURE_LINK_SPEED_2_5G 0x00060000 -#define PORT_FEATURE_LINK_SPEED_10G_CX4 0x00070000 -#define PORT_FEATURE_LINK_SPEED_10G_KX4 0x00080000 -#define PORT_FEATURE_LINK_SPEED_10G_KR 0x00090000 -#define PORT_FEATURE_LINK_SPEED_12G 0x000a0000 -#define PORT_FEATURE_LINK_SPEED_12_5G 0x000b0000 -#define PORT_FEATURE_LINK_SPEED_13G 0x000c0000 -#define PORT_FEATURE_LINK_SPEED_15G 0x000d0000 -#define PORT_FEATURE_LINK_SPEED_16G 0x000e0000 - -#define PORT_FEATURE_FLOW_CONTROL_MASK 0x00000700 -#define PORT_FEATURE_FLOW_CONTROL_SHIFT 8 -#define PORT_FEATURE_FLOW_CONTROL_AUTO 0x00000000 -#define PORT_FEATURE_FLOW_CONTROL_TX 0x00000100 -#define PORT_FEATURE_FLOW_CONTROL_RX 0x00000200 -#define PORT_FEATURE_FLOW_CONTROL_BOTH 0x00000300 -#define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400 + #define PORT_FEATURE_CONNECTED_SWITCH_MASK 0x03000000 + #define PORT_FEATURE_CONNECTED_SWITCH_SHIFT 24 + /* (forced) low speed switch (< 10G) */ + #define PORT_FEATURE_CON_SWITCH_1G_SWITCH 0x00000000 + /* (forced) high speed switch (>= 10G) */ + #define PORT_FEATURE_CON_SWITCH_10G_SWITCH 0x01000000 + #define PORT_FEATURE_CON_SWITCH_AUTO_DETECT 0x02000000 + #define PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT 0x03000000 + + #define PORT_FEATURE_LINK_SPEED_MASK 0x000f0000 + #define PORT_FEATURE_LINK_SPEED_SHIFT 16 + #define PORT_FEATURE_LINK_SPEED_AUTO 0x00000000 + #define PORT_FEATURE_LINK_SPEED_10M_FULL 0x00010000 + #define PORT_FEATURE_LINK_SPEED_10M_HALF 0x00020000 + #define PORT_FEATURE_LINK_SPEED_100M_HALF 0x00030000 + #define PORT_FEATURE_LINK_SPEED_100M_FULL 0x00040000 + #define PORT_FEATURE_LINK_SPEED_1G 0x00050000 + #define PORT_FEATURE_LINK_SPEED_2_5G 0x00060000 + #define PORT_FEATURE_LINK_SPEED_10G_CX4 0x00070000 + #define PORT_FEATURE_LINK_SPEED_20G 0x00080000 + + #define PORT_FEATURE_FLOW_CONTROL_MASK 0x00000700 + #define PORT_FEATURE_FLOW_CONTROL_SHIFT 8 + #define PORT_FEATURE_FLOW_CONTROL_AUTO 0x00000000 + #define PORT_FEATURE_FLOW_CONTROL_TX 0x00000100 + #define PORT_FEATURE_FLOW_CONTROL_RX 0x00000200 + #define PORT_FEATURE_FLOW_CONTROL_BOTH 0x00000300 + #define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400 /* The default for MCP link configuration, - uses the same defines as link_config */ + uses the same defines as link_config */ u32 mfw_wol_link_cfg; + /* The default for the driver of the second external phy, - uses the same defines as link_config */ - u32 link_config2; /* 0x47C */ + uses the same defines as link_config */ + u32 link_config2; /* 0x47C */ /* The default for MCP of the second external phy, - uses the same defines as link_config */ - u32 mfw_wol_link_cfg2; /* 0x480 */ + uses the same defines as link_config */ + u32 mfw_wol_link_cfg2; /* 0x480 */ - u32 Reserved2[17]; /* 0x484 */ + u32 Reserved2[17]; /* 0x484 */ }; /**************************************************************************** - * Device Information * + * Device Information * ****************************************************************************/ -struct shm_dev_info { /* size */ +struct shm_dev_info { /* size */ u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */ - struct shared_hw_cfg shared_hw_config; /* 40 */ + struct shared_hw_cfg shared_hw_config; /* 40 */ - struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */ + struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */ - struct shared_feat_cfg shared_feature_config; /* 4 */ + struct shared_feat_cfg shared_feature_config; /* 4 */ - struct port_feat_cfg port_feature_config[PORT_MAX];/* 116*2=232 */ + struct port_feat_cfg port_feature_config[PORT_MAX];/* 116*2=232 */ }; -#define FUNC_0 0 -#define FUNC_1 1 -#define FUNC_2 2 -#define FUNC_3 3 -#define FUNC_4 4 -#define FUNC_5 5 -#define FUNC_6 6 -#define FUNC_7 7 -#define E1_FUNC_MAX 2 -#define E1H_FUNC_MAX 8 -#define E2_FUNC_MAX 4 /* per path */ - -#define VN_0 0 -#define VN_1 1 -#define VN_2 2 -#define VN_3 3 -#define E1VN_MAX 1 -#define E1HVN_MAX 4 +#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) + #error "Missing either LITTLE_ENDIAN or BIG_ENDIAN definition." +#endif -#define E2_VF_MAX 64 +#define FUNC_0 0 +#define FUNC_1 1 +#define FUNC_2 2 +#define FUNC_3 3 +#define FUNC_4 4 +#define FUNC_5 5 +#define FUNC_6 6 +#define FUNC_7 7 +#define E1_FUNC_MAX 2 +#define E1H_FUNC_MAX 8 +#define E2_FUNC_MAX 4 /* per path */ + +#define VN_0 0 +#define VN_1 1 +#define VN_2 2 +#define VN_3 3 +#define E1VN_MAX 1 +#define E1HVN_MAX 4 + +#define E2_VF_MAX 64 /* HC_REG_VF_CONFIGURATION_SIZE */ /* This value (in milliseconds) determines the frequency of the driver * issuing the PULSE message code. The firmware monitors this periodic * pulse to determine when to switch to an OS-absent mode. */ -#define DRV_PULSE_PERIOD_MS 250 +#define DRV_PULSE_PERIOD_MS 250 /* This value (in milliseconds) determines how long the driver should * wait for an acknowledgement from the firmware before timing out. Once * the firmware has timed out, the driver will assume there is no firmware * running and there won't be any firmware-driver synchronization during a * driver reset. */ -#define FW_ACK_TIME_OUT_MS 5000 +#define FW_ACK_TIME_OUT_MS 5000 -#define FW_ACK_POLL_TIME_MS 1 +#define FW_ACK_POLL_TIME_MS 1 -#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS) +#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS) /* LED Blink rate that will achieve ~15.9Hz */ -#define LED_BLINK_RATE_VAL 480 +#define LED_BLINK_RATE_VAL 480 /**************************************************************************** - * Driver <-> FW Mailbox * + * Driver <-> FW Mailbox * ****************************************************************************/ struct drv_port_mb { u32 link_status; /* Driver should update this field on any link change event */ -#define LINK_STATUS_LINK_FLAG_MASK 0x00000001 -#define LINK_STATUS_LINK_UP 0x00000001 -#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E -#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1) - -#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020 -#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 - -#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 -#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080 -#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 - -#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 -#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 -#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800 -#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000 -#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000 -#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000 -#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000 - -#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000 -#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000 - -#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000 -#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000 - -#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 -#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18) -#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18) -#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18) -#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18) - -#define LINK_STATUS_SERDES_LINK 0x00100000 - -#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000 -#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000 -#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 -#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000 -#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000 -#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000 -#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000 -#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000 + #define LINK_STATUS_LINK_FLAG_MASK 0x00000001 + #define LINK_STATUS_LINK_UP 0x00000001 + #define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E + #define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_20GTFD (11<<1) + #define LINK_STATUS_SPEED_AND_DUPLEX_20GXFD (11<<1) + + #define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020 + #define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 + + #define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 + #define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080 + #define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 + + #define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 + #define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 + #define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800 + #define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000 + #define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000 + #define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000 + #define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000 + + #define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000 + #define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000 + + #define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000 + #define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000 + + #define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 + #define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18) + #define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18) + #define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18) + #define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18) + + #define LINK_STATUS_SERDES_LINK 0x00100000 + + #define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000 + #define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000 + #define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 + #define LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE 0x10000000 u32 port_stx; @@ -903,138 +1209,158 @@ struct drv_port_mb { struct drv_func_mb { u32 drv_mb_header; -#define DRV_MSG_CODE_MASK 0xffff0000 -#define DRV_MSG_CODE_LOAD_REQ 0x10000000 -#define DRV_MSG_CODE_LOAD_DONE 0x11000000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000 -#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000 -#define DRV_MSG_CODE_DCC_OK 0x30000000 -#define DRV_MSG_CODE_DCC_FAILURE 0x31000000 -#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000 -#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000 -#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000 -#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000 -#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000 -#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 -#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 + #define DRV_MSG_CODE_MASK 0xffff0000 + #define DRV_MSG_CODE_LOAD_REQ 0x10000000 + #define DRV_MSG_CODE_LOAD_DONE 0x11000000 + #define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000 + #define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000 + #define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000 + #define DRV_MSG_CODE_UNLOAD_DONE 0x21000000 + #define DRV_MSG_CODE_DCC_OK 0x30000000 + #define DRV_MSG_CODE_DCC_FAILURE 0x31000000 + #define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000 + #define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000 + #define DRV_MSG_CODE_VALIDATE_KEY 0x70000000 + #define DRV_MSG_CODE_GET_CURR_KEY 0x80000000 + #define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000 + #define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 + #define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 /* - * The optic module verification commands require bootcode - * v5.0.6 or later + * The optic module verification command requires bootcode + * v5.0.6 or later, te specific optic module verification command + * requires bootcode v5.2.12 or later */ -#define DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL 0xa0000000 -#define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006 - /* - * The specific optic module verification command requires bootcode - * v5.2.12 or later - */ -#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 -#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 + #define DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL 0xa0000000 + #define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006 + #define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 + #define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 + + #define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 + #define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 + + #define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000 -#define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 -#define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 -#define DRV_MSG_CODE_SET_MF_BW 0xe0000000 -#define REQ_BC_VER_4_SET_MF_BW 0x00060202 -#define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 -#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 -#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 -#define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 -#define BIOS_MSG_CODE_VIRT_MAC_ISCSI 0xff040000 + #define DRV_MSG_CODE_SET_MF_BW 0xe0000000 + #define REQ_BC_VER_4_SET_MF_BW 0x00060202 + #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 -#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff + #define DRV_MSG_CODE_LINK_STATUS_CHANGED 0x01000000 + + #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 + #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 + #define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 + #define BIOS_MSG_CODE_VIRT_MAC_ISCSI 0xff040000 + + #define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff u32 drv_mb_param; + #define DRV_MSG_CODE_SET_MF_BW_MIN_MASK 0x00ff0000 + #define DRV_MSG_CODE_SET_MF_BW_MAX_MASK 0xff000000 u32 fw_mb_header; -#define FW_MSG_CODE_MASK 0xffff0000 -#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000 -#define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000 -#define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000 - /* Load common chip is supported from bc 6.0.0 */ -#define REQ_BC_VER_4_DRV_LOAD_COMMON_CHIP 0x00060000 -#define FW_MSG_CODE_DRV_LOAD_COMMON_CHIP 0x10130000 -#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000 -#define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000 -#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000 -#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x20110000 -#define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 0x20120000 -#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x21100000 -#define FW_MSG_CODE_DCC_DONE 0x30100000 -#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50100000 -#define FW_MSG_CODE_DIAG_REFUSE 0x50200000 -#define FW_MSG_CODE_DIAG_EXIT_DONE 0x60100000 -#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70100000 -#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x70200000 -#define FW_MSG_CODE_GET_KEY_DONE 0x80100000 -#define FW_MSG_CODE_NO_KEY 0x80f00000 -#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x80f80000 -#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90100000 -#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x90210000 -#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000 -#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000 -#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000 -#define FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS 0xa0100000 -#define FW_MSG_CODE_VRFY_OPT_MDL_INVLD_IMG 0xa0200000 -#define FW_MSG_CODE_VRFY_OPT_MDL_UNAPPROVED 0xa0300000 - -#define FW_MSG_CODE_LIC_CHALLENGE 0xff010000 -#define FW_MSG_CODE_LIC_RESPONSE 0xff020000 -#define FW_MSG_CODE_VIRT_MAC_PRIM 0xff030000 -#define FW_MSG_CODE_VIRT_MAC_ISCSI 0xff040000 - -#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff + #define FW_MSG_CODE_MASK 0xffff0000 + #define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000 + #define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000 + #define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000 + /* Load common chip is supported from bc 6.0.0 */ + #define REQ_BC_VER_4_DRV_LOAD_COMMON_CHIP 0x00060000 + #define FW_MSG_CODE_DRV_LOAD_COMMON_CHIP 0x10130000 + + #define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000 + #define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000 + #define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000 + #define FW_MSG_CODE_DRV_UNLOAD_PORT 0x20110000 + #define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 0x20120000 + #define FW_MSG_CODE_DRV_UNLOAD_DONE 0x21100000 + #define FW_MSG_CODE_DCC_DONE 0x30100000 + #define FW_MSG_CODE_LLDP_DONE 0x40100000 + #define FW_MSG_CODE_DIAG_ENTER_DONE 0x50100000 + #define FW_MSG_CODE_DIAG_REFUSE 0x50200000 + #define FW_MSG_CODE_DIAG_EXIT_DONE 0x60100000 + #define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70100000 + #define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x70200000 + #define FW_MSG_CODE_GET_KEY_DONE 0x80100000 + #define FW_MSG_CODE_NO_KEY 0x80f00000 + #define FW_MSG_CODE_LIC_INFO_NOT_READY 0x80f80000 + #define FW_MSG_CODE_L2B_PRAM_LOADED 0x90100000 + #define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x90210000 + #define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000 + #define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000 + #define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000 + #define FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS 0xa0100000 + #define FW_MSG_CODE_VRFY_OPT_MDL_INVLD_IMG 0xa0200000 + #define FW_MSG_CODE_VRFY_OPT_MDL_UNAPPROVED 0xa0300000 + #define FW_MSG_CODE_VF_DISABLED_DONE 0xb0000000 + + #define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000 + #define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000 + + #define FW_MSG_CODE_LINK_CHANGED_ACK 0x01100000 + + #define FW_MSG_CODE_LIC_CHALLENGE 0xff010000 + #define FW_MSG_CODE_LIC_RESPONSE 0xff020000 + #define FW_MSG_CODE_VIRT_MAC_PRIM 0xff030000 + #define FW_MSG_CODE_VIRT_MAC_ISCSI 0xff040000 + + #define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff u32 fw_mb_param; u32 drv_pulse_mb; -#define DRV_PULSE_SEQ_MASK 0x00007fff -#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 - /* The system time is in the format of - * (year-2001)*12*32 + month*32 + day. */ -#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 - /* Indicate to the firmware not to go into the + #define DRV_PULSE_SEQ_MASK 0x00007fff + #define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 + /* + * The system time is in the format of + * (year-2001)*12*32 + month*32 + day. + */ + #define DRV_PULSE_ALWAYS_ALIVE 0x00008000 + /* + * Indicate to the firmware not to go into the * OS-absent when it is not getting driver pulse. - * This is used for debugging as well for PXE(MBA). */ + * This is used for debugging as well for PXE(MBA). + */ u32 mcp_pulse_mb; -#define MCP_PULSE_SEQ_MASK 0x00007fff -#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 + #define MCP_PULSE_SEQ_MASK 0x00007fff + #define MCP_PULSE_ALWAYS_ALIVE 0x00008000 /* Indicates to the driver not to assert due to lack * of MCP response */ -#define MCP_EVENT_MASK 0xffff0000 -#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 + #define MCP_EVENT_MASK 0xffff0000 + #define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 u32 iscsi_boot_signature; u32 iscsi_boot_block_offset; u32 drv_status; -#define DRV_STATUS_PMF 0x00000001 -#define DRV_STATUS_SET_MF_BW 0x00000004 - -#define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00 -#define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100 -#define DRV_STATUS_DCC_BANDWIDTH_ALLOCATION 0x00000200 -#define DRV_STATUS_DCC_CHANGE_MAC_ADDRESS 0x00000400 -#define DRV_STATUS_DCC_RESERVED1 0x00000800 -#define DRV_STATUS_DCC_SET_PROTOCOL 0x00001000 -#define DRV_STATUS_DCC_SET_PRIORITY 0x00002000 -#define DRV_STATUS_DCBX_EVENT_MASK 0x000f0000 -#define DRV_STATUS_DCBX_NEGOTIATION_RESULTS 0x00010000 + #define DRV_STATUS_PMF 0x00000001 + #define DRV_STATUS_VF_DISABLED 0x00000002 + #define DRV_STATUS_SET_MF_BW 0x00000004 + #define DRV_STATUS_LINK_EVENT 0x00000008 + + #define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00 + #define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100 + #define DRV_STATUS_DCC_BANDWIDTH_ALLOCATION 0x00000200 + #define DRV_STATUS_DCC_CHANGE_MAC_ADDRESS 0x00000400 + #define DRV_STATUS_DCC_RESERVED1 0x00000800 + #define DRV_STATUS_DCC_SET_PROTOCOL 0x00001000 + #define DRV_STATUS_DCC_SET_PRIORITY 0x00002000 + + #define DRV_STATUS_DCBX_EVENT_MASK 0x000f0000 + #define DRV_STATUS_DCBX_NEGOTIATION_RESULTS 0x00010000 u32 virt_mac_upper; -#define VIRT_MAC_SIGN_MASK 0xffff0000 -#define VIRT_MAC_SIGNATURE 0x564d0000 + #define VIRT_MAC_SIGN_MASK 0xffff0000 + #define VIRT_MAC_SIGNATURE 0x564d0000 u32 virt_mac_lower; }; /**************************************************************************** - * Management firmware state * + * Management firmware state * ****************************************************************************/ /* Allocate 440 bytes for management firmware */ -#define MGMTFW_STATE_WORD_SIZE 110 +#define MGMTFW_STATE_WORD_SIZE 110 struct mgmtfw_state { u32 opaque[MGMTFW_STATE_WORD_SIZE]; @@ -1042,25 +1368,25 @@ struct mgmtfw_state { /**************************************************************************** - * Multi-Function configuration * + * Multi-Function configuration * ****************************************************************************/ struct shared_mf_cfg { u32 clp_mb; -#define SHARED_MF_CLP_SET_DEFAULT 0x00000000 + #define SHARED_MF_CLP_SET_DEFAULT 0x00000000 /* set by CLP */ -#define SHARED_MF_CLP_EXIT 0x00000001 + #define SHARED_MF_CLP_EXIT 0x00000001 /* set by MCP */ -#define SHARED_MF_CLP_EXIT_DONE 0x00010000 + #define SHARED_MF_CLP_EXIT_DONE 0x00010000 }; struct port_mf_cfg { - u32 dynamic_cfg; /* device control channel */ -#define PORT_MF_CFG_E1HOV_TAG_MASK 0x0000ffff -#define PORT_MF_CFG_E1HOV_TAG_SHIFT 0 -#define PORT_MF_CFG_E1HOV_TAG_DEFAULT PORT_MF_CFG_E1HOV_TAG_MASK + u32 dynamic_cfg; /* device control channel */ + #define PORT_MF_CFG_E1HOV_TAG_MASK 0x0000ffff + #define PORT_MF_CFG_E1HOV_TAG_SHIFT 0 + #define PORT_MF_CFG_E1HOV_TAG_DEFAULT PORT_MF_CFG_E1HOV_TAG_MASK u32 reserved[3]; @@ -1071,57 +1397,58 @@ struct func_mf_cfg { u32 config; /* E/R/I/D */ /* function 0 of each port cannot be hidden */ -#define FUNC_MF_CFG_FUNC_HIDE 0x00000001 + #define FUNC_MF_CFG_FUNC_HIDE 0x00000001 -#define FUNC_MF_CFG_PROTOCOL_MASK 0x00000007 -#define FUNC_MF_CFG_PROTOCOL_ETHERNET 0x00000002 -#define FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA 0x00000004 -#define FUNC_MF_CFG_PROTOCOL_ISCSI 0x00000006 -#define FUNC_MF_CFG_PROTOCOL_DEFAULT\ - FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA + #define FUNC_MF_CFG_PROTOCOL_MASK 0x00000006 + #define FUNC_MF_CFG_PROTOCOL_FCOE 0x00000000 + #define FUNC_MF_CFG_PROTOCOL_ETHERNET 0x00000002 + #define FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA 0x00000004 + #define FUNC_MF_CFG_PROTOCOL_ISCSI 0x00000006 + #define FUNC_MF_CFG_PROTOCOL_DEFAULT \ + FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA -#define FUNC_MF_CFG_FUNC_DISABLED 0x00000008 + #define FUNC_MF_CFG_FUNC_DISABLED 0x00000008 + #define FUNC_MF_CFG_FUNC_DELETED 0x00000010 /* PRI */ /* 0 - low priority, 3 - high priority */ -#define FUNC_MF_CFG_TRANSMIT_PRIORITY_MASK 0x00000300 -#define FUNC_MF_CFG_TRANSMIT_PRIORITY_SHIFT 8 -#define FUNC_MF_CFG_TRANSMIT_PRIORITY_DEFAULT 0x00000000 + #define FUNC_MF_CFG_TRANSMIT_PRIORITY_MASK 0x00000300 + #define FUNC_MF_CFG_TRANSMIT_PRIORITY_SHIFT 8 + #define FUNC_MF_CFG_TRANSMIT_PRIORITY_DEFAULT 0x00000000 /* MINBW, MAXBW */ /* value range - 0..100, increments in 100Mbps */ -#define FUNC_MF_CFG_MIN_BW_MASK 0x00ff0000 -#define FUNC_MF_CFG_MIN_BW_SHIFT 16 -#define FUNC_MF_CFG_MIN_BW_DEFAULT 0x00000000 -#define FUNC_MF_CFG_MAX_BW_MASK 0xff000000 -#define FUNC_MF_CFG_MAX_BW_SHIFT 24 -#define FUNC_MF_CFG_MAX_BW_DEFAULT 0x64000000 - - u32 mac_upper; /* MAC */ -#define FUNC_MF_CFG_UPPERMAC_MASK 0x0000ffff -#define FUNC_MF_CFG_UPPERMAC_SHIFT 0 -#define FUNC_MF_CFG_UPPERMAC_DEFAULT FUNC_MF_CFG_UPPERMAC_MASK + #define FUNC_MF_CFG_MIN_BW_MASK 0x00ff0000 + #define FUNC_MF_CFG_MIN_BW_SHIFT 16 + #define FUNC_MF_CFG_MIN_BW_DEFAULT 0x00000000 + #define FUNC_MF_CFG_MAX_BW_MASK 0xff000000 + #define FUNC_MF_CFG_MAX_BW_SHIFT 24 + #define FUNC_MF_CFG_MAX_BW_DEFAULT 0x64000000 + + u32 mac_upper; /* MAC */ + #define FUNC_MF_CFG_UPPERMAC_MASK 0x0000ffff + #define FUNC_MF_CFG_UPPERMAC_SHIFT 0 + #define FUNC_MF_CFG_UPPERMAC_DEFAULT FUNC_MF_CFG_UPPERMAC_MASK u32 mac_lower; -#define FUNC_MF_CFG_LOWERMAC_DEFAULT 0xffffffff + #define FUNC_MF_CFG_LOWERMAC_DEFAULT 0xffffffff u32 e1hov_tag; /* VNI */ -#define FUNC_MF_CFG_E1HOV_TAG_MASK 0x0000ffff -#define FUNC_MF_CFG_E1HOV_TAG_SHIFT 0 -#define FUNC_MF_CFG_E1HOV_TAG_DEFAULT FUNC_MF_CFG_E1HOV_TAG_MASK + #define FUNC_MF_CFG_E1HOV_TAG_MASK 0x0000ffff + #define FUNC_MF_CFG_E1HOV_TAG_SHIFT 0 + #define FUNC_MF_CFG_E1HOV_TAG_DEFAULT FUNC_MF_CFG_E1HOV_TAG_MASK u32 reserved[2]; - }; /* This structure is not applicable and should not be accessed on 57711 */ struct func_ext_cfg { u32 func_cfg; -#define MACP_FUNC_CFG_FLAGS_MASK 0x000000FF -#define MACP_FUNC_CFG_FLAGS_SHIFT 0 -#define MACP_FUNC_CFG_FLAGS_ENABLED 0x00000001 -#define MACP_FUNC_CFG_FLAGS_ETHERNET 0x00000002 -#define MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD 0x00000004 -#define MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD 0x00000008 + #define MACP_FUNC_CFG_FLAGS_MASK 0x000000FF + #define MACP_FUNC_CFG_FLAGS_SHIFT 0 + #define MACP_FUNC_CFG_FLAGS_ENABLED 0x00000001 + #define MACP_FUNC_CFG_FLAGS_ETHERNET 0x00000002 + #define MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD 0x00000004 + #define MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD 0x00000008 u32 iscsi_mac_addr_upper; u32 iscsi_mac_addr_lower; @@ -1136,73 +1463,99 @@ struct func_ext_cfg { u32 fcoe_wwn_node_name_lower; u32 preserve_data; -#define MF_FUNC_CFG_PRESERVE_L2_MAC (1<<0) -#define MF_FUNC_CFG_PRESERVE_ISCSI_MAC (1<<1) -#define MF_FUNC_CFG_PRESERVE_FCOE_MAC (1<<2) -#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_P (1<<3) -#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_N (1<<4) + #define MF_FUNC_CFG_PRESERVE_L2_MAC (1<<0) + #define MF_FUNC_CFG_PRESERVE_ISCSI_MAC (1<<1) + #define MF_FUNC_CFG_PRESERVE_FCOE_MAC (1<<2) + #define MF_FUNC_CFG_PRESERVE_FCOE_WWN_P (1<<3) + #define MF_FUNC_CFG_PRESERVE_FCOE_WWN_N (1<<4) + #define MF_FUNC_CFG_PRESERVE_TX_BW (1<<5) }; struct mf_cfg { - struct shared_mf_cfg shared_mf_config; - struct port_mf_cfg port_mf_config[PORT_MAX]; - struct func_mf_cfg func_mf_config[E1H_FUNC_MAX]; - - struct func_ext_cfg func_ext_config[E1H_FUNC_MAX]; -}; - + struct shared_mf_cfg shared_mf_config; /* 0x4 */ + struct port_mf_cfg port_mf_config[PORT_MAX]; /* 0x10 * 2 = 0x20 */ + /* for all chips, there are 8 mf functions */ + struct func_mf_cfg func_mf_config[E1H_FUNC_MAX]; /* 0x18 * 8 = 0xc0 */ + /* + * Extended configuration per function - this array does not exist and + * should not be accessed on 57711 + */ + struct func_ext_cfg func_ext_config[E1H_FUNC_MAX]; /* 0x28 * 8 = 0x140*/ +}; /* 0x224 */ /**************************************************************************** - * Shared Memory Region * + * Shared Memory Region * ****************************************************************************/ -struct shmem_region { /* SharedMem Offset (size) */ +struct shmem_region { /* SharedMem Offset (size) */ - u32 validity_map[PORT_MAX]; /* 0x0 (4*2 = 0x8) */ -#define SHR_MEM_FORMAT_REV_ID ('A'<<24) -#define SHR_MEM_FORMAT_REV_MASK 0xff000000 + u32 validity_map[PORT_MAX]; /* 0x0 (4*2 = 0x8) */ + #define SHR_MEM_FORMAT_REV_MASK 0xff000000 + #define SHR_MEM_FORMAT_REV_ID ('A'<<24) /* validity bits */ -#define SHR_MEM_VALIDITY_PCI_CFG 0x00100000 -#define SHR_MEM_VALIDITY_MB 0x00200000 -#define SHR_MEM_VALIDITY_DEV_INFO 0x00400000 -#define SHR_MEM_VALIDITY_RESERVED 0x00000007 + #define SHR_MEM_VALIDITY_PCI_CFG 0x00100000 + #define SHR_MEM_VALIDITY_MB 0x00200000 + #define SHR_MEM_VALIDITY_DEV_INFO 0x00400000 + #define SHR_MEM_VALIDITY_RESERVED 0x00000007 /* One licensing bit should be set */ -#define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038 -#define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008 -#define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010 -#define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020 + #define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038 + #define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008 + #define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010 + #define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020 /* Active MFW */ -#define SHR_MEM_VALIDITY_ACTIVE_MFW_UNKNOWN 0x00000000 -#define SHR_MEM_VALIDITY_ACTIVE_MFW_IPMI 0x00000040 -#define SHR_MEM_VALIDITY_ACTIVE_MFW_UMP 0x00000080 -#define SHR_MEM_VALIDITY_ACTIVE_MFW_NCSI 0x000000c0 -#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0 -#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0 + #define SHR_MEM_VALIDITY_ACTIVE_MFW_UNKNOWN 0x00000000 + #define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0 + #define SHR_MEM_VALIDITY_ACTIVE_MFW_IPMI 0x00000040 + #define SHR_MEM_VALIDITY_ACTIVE_MFW_UMP 0x00000080 + #define SHR_MEM_VALIDITY_ACTIVE_MFW_NCSI 0x000000c0 + #define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0 - struct shm_dev_info dev_info; /* 0x8 (0x438) */ + struct shm_dev_info dev_info; /* 0x8 (0x438) */ - struct license_key drv_lic_key[PORT_MAX]; /* 0x440 (52*2=0x68) */ + struct license_key drv_lic_key[PORT_MAX]; /* 0x440 (52*2=0x68) */ /* FW information (for internal FW use) */ - u32 fw_info_fio_offset; /* 0x4a8 (0x4) */ - struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */ + u32 fw_info_fio_offset; /* 0x4a8 (0x4) */ + struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */ - struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */ - struct drv_func_mb func_mb[]; /* 0x684 - (44*2/4/8=0x58/0xb0/0x160) */ + struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */ + +#ifdef BMAPI + /* This is a variable length array */ + /* the number of function depends on the chip type */ + struct drv_func_mb func_mb[1]; /* 0x684 (44*2/4/8=0x58/0xb0/0x160) */ +#else + /* the number of function depends on the chip type */ + struct drv_func_mb func_mb[]; /* 0x684 (44*2/4/8=0x58/0xb0/0x160) */ +#endif /* BMAPI */ }; /* 57710 = 0x6dc | 57711 = 0x7E4 | 57712 = 0x734 */ +/**************************************************************************** + * Shared Memory 2 Region * + ****************************************************************************/ +/* The fw_flr_ack is actually built in the following way: */ +/* 8 bit: PF ack */ +/* 64 bit: VF ack */ +/* 8 bit: ios_dis_ack */ +/* In order to maintain endianity in the mailbox hsi, we want to keep using */ +/* u32. The fw must have the VF right after the PF since this is how it */ +/* access arrays(it expects always the VF to reside after the PF, and that */ +/* makes the calculation much easier for it. ) */ +/* In order to answer both limitations, and keep the struct small, the code */ +/* will abuse the structure defined here to achieve the actual partition */ +/* above */ +/****************************************************************************/ struct fw_flr_ack { - u32 pf_ack; - u32 vf_ack[1]; - u32 iov_dis_ack; + u32 pf_ack; + u32 vf_ack[1]; + u32 iov_dis_ack; }; struct fw_flr_mb { - u32 aggint; - u32 opgen_addr; - struct fw_flr_ack ack; + u32 aggint; + u32 opgen_addr; + struct fw_flr_ack ack; }; /**** SUPPORT FOR SHMEM ARRRAYS *** @@ -1226,36 +1579,36 @@ struct fw_flr_mb { * * SHMEM_ARRAY_BITPOS(i, 4, 4) defines the stadard ordering: * - * | | | | - * 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | - * | | | | + * | | | | + * 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | + * | | | | * * SHMEM_ARRAY_BITPOS(i, 4, 8) defines a flip ordering per byte: * - * | | | | - * 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 | - * | | | | + * | | | | + * 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 | + * | | | | * * SHMEM_ARRAY_BITPOS(i, 4, 16) defines a flip ordering per word: * - * | | | | - * 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | - * | | | | + * | | | | + * 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | + * | | | | */ #define SHMEM_ARRAY_BITPOS(i, eb, fb) \ ((((32/(fb)) - 1 - ((i)/((fb)/(eb))) % (32/(fb))) * (fb)) + \ (((i)%((fb)/(eb))) * (eb))) -#define SHMEM_ARRAY_GET(a, i, eb, fb) \ +#define SHMEM_ARRAY_GET(a, i, eb, fb) \ ((a[SHMEM_ARRAY_ENTRY(i, eb)] >> SHMEM_ARRAY_BITPOS(i, eb, fb)) & \ SHMEM_ARRAY_MASK(eb)) -#define SHMEM_ARRAY_SET(a, i, eb, fb, val) \ +#define SHMEM_ARRAY_SET(a, i, eb, fb, val) \ do { \ a[SHMEM_ARRAY_ENTRY(i, eb)] &= ~(SHMEM_ARRAY_MASK(eb) << \ - SHMEM_ARRAY_BITPOS(i, eb, fb)); \ + SHMEM_ARRAY_BITPOS(i, eb, fb)); \ a[SHMEM_ARRAY_ENTRY(i, eb)] |= (((val) & SHMEM_ARRAY_MASK(eb)) << \ - SHMEM_ARRAY_BITPOS(i, eb, fb)); \ + SHMEM_ARRAY_BITPOS(i, eb, fb)); \ } while (0) @@ -1279,23 +1632,30 @@ do { \ #define ISCSI_APP_IDX 1 #define PREDEFINED_APP_IDX_MAX 2 + +/* Big/Little endian have the same representation. */ struct dcbx_ets_feature { + /* + * For Admin MIB - is this feature supported by the + * driver | For Local MIB - should this feature be enabled. + */ u32 enabled; u32 pg_bw_tbl[2]; u32 pri_pg_tbl[1]; }; +/* Driver structure in LE */ struct dcbx_pfc_feature { #ifdef __BIG_ENDIAN u8 pri_en_bitmap; -#define DCBX_PFC_PRI_0 0x01 -#define DCBX_PFC_PRI_1 0x02 -#define DCBX_PFC_PRI_2 0x04 -#define DCBX_PFC_PRI_3 0x08 -#define DCBX_PFC_PRI_4 0x10 -#define DCBX_PFC_PRI_5 0x20 -#define DCBX_PFC_PRI_6 0x40 -#define DCBX_PFC_PRI_7 0x80 + #define DCBX_PFC_PRI_0 0x01 + #define DCBX_PFC_PRI_1 0x02 + #define DCBX_PFC_PRI_2 0x04 + #define DCBX_PFC_PRI_3 0x08 + #define DCBX_PFC_PRI_4 0x10 + #define DCBX_PFC_PRI_5 0x20 + #define DCBX_PFC_PRI_6 0x40 + #define DCBX_PFC_PRI_7 0x80 u8 pfc_caps; u8 reserved; u8 enabled; @@ -1304,39 +1664,41 @@ struct dcbx_pfc_feature { u8 reserved; u8 pfc_caps; u8 pri_en_bitmap; -#define DCBX_PFC_PRI_0 0x01 -#define DCBX_PFC_PRI_1 0x02 -#define DCBX_PFC_PRI_2 0x04 -#define DCBX_PFC_PRI_3 0x08 -#define DCBX_PFC_PRI_4 0x10 -#define DCBX_PFC_PRI_5 0x20 -#define DCBX_PFC_PRI_6 0x40 -#define DCBX_PFC_PRI_7 0x80 + #define DCBX_PFC_PRI_0 0x01 + #define DCBX_PFC_PRI_1 0x02 + #define DCBX_PFC_PRI_2 0x04 + #define DCBX_PFC_PRI_3 0x08 + #define DCBX_PFC_PRI_4 0x10 + #define DCBX_PFC_PRI_5 0x20 + #define DCBX_PFC_PRI_6 0x40 + #define DCBX_PFC_PRI_7 0x80 #endif }; struct dcbx_app_priority_entry { #ifdef __BIG_ENDIAN - u16 app_id; - u8 pri_bitmap; - u8 appBitfield; -#define DCBX_APP_ENTRY_VALID 0x01 -#define DCBX_APP_ENTRY_SF_MASK 0x30 -#define DCBX_APP_ENTRY_SF_SHIFT 4 -#define DCBX_APP_SF_ETH_TYPE 0x10 -#define DCBX_APP_SF_PORT 0x20 + u16 app_id; + u8 pri_bitmap; + u8 appBitfield; + #define DCBX_APP_ENTRY_VALID 0x01 + #define DCBX_APP_ENTRY_SF_MASK 0x30 + #define DCBX_APP_ENTRY_SF_SHIFT 4 + #define DCBX_APP_SF_ETH_TYPE 0x10 + #define DCBX_APP_SF_PORT 0x20 #elif defined(__LITTLE_ENDIAN) u8 appBitfield; -#define DCBX_APP_ENTRY_VALID 0x01 -#define DCBX_APP_ENTRY_SF_MASK 0x30 -#define DCBX_APP_ENTRY_SF_SHIFT 4 -#define DCBX_APP_SF_ETH_TYPE 0x10 -#define DCBX_APP_SF_PORT 0x20 - u8 pri_bitmap; - u16 app_id; + #define DCBX_APP_ENTRY_VALID 0x01 + #define DCBX_APP_ENTRY_SF_MASK 0x30 + #define DCBX_APP_ENTRY_SF_SHIFT 4 + #define DCBX_APP_SF_ETH_TYPE 0x10 + #define DCBX_APP_SF_PORT 0x20 + u8 pri_bitmap; + u16 app_id; #endif }; + +/* FW structure in BE */ struct dcbx_app_priority_feature { #ifdef __BIG_ENDIAN u8 reserved; @@ -1352,302 +1714,402 @@ struct dcbx_app_priority_feature { struct dcbx_app_priority_entry app_pri_tbl[DCBX_MAX_APP_PROTOCOL]; }; +/* FW structure in BE */ struct dcbx_features { + /* PG feature */ struct dcbx_ets_feature ets; + /* PFC feature */ struct dcbx_pfc_feature pfc; + /* APP feature */ struct dcbx_app_priority_feature app; }; +/* LLDP protocol parameters */ +/* FW structure in BE */ struct lldp_params { #ifdef __BIG_ENDIAN - u8 msg_fast_tx_interval; - u8 msg_tx_hold; - u8 msg_tx_interval; - u8 admin_status; -#define LLDP_TX_ONLY 0x01 -#define LLDP_RX_ONLY 0x02 -#define LLDP_TX_RX 0x03 -#define LLDP_DISABLED 0x04 - u8 reserved1; - u8 tx_fast; - u8 tx_crd_max; - u8 tx_crd; + u8 msg_fast_tx_interval; + u8 msg_tx_hold; + u8 msg_tx_interval; + u8 admin_status; + #define LLDP_TX_ONLY 0x01 + #define LLDP_RX_ONLY 0x02 + #define LLDP_TX_RX 0x03 + #define LLDP_DISABLED 0x04 + u8 reserved1; + u8 tx_fast; + u8 tx_crd_max; + u8 tx_crd; #elif defined(__LITTLE_ENDIAN) - u8 admin_status; -#define LLDP_TX_ONLY 0x01 -#define LLDP_RX_ONLY 0x02 -#define LLDP_TX_RX 0x03 -#define LLDP_DISABLED 0x04 - u8 msg_tx_interval; - u8 msg_tx_hold; - u8 msg_fast_tx_interval; - u8 tx_crd; - u8 tx_crd_max; - u8 tx_fast; - u8 reserved1; + u8 admin_status; + #define LLDP_TX_ONLY 0x01 + #define LLDP_RX_ONLY 0x02 + #define LLDP_TX_RX 0x03 + #define LLDP_DISABLED 0x04 + u8 msg_tx_interval; + u8 msg_tx_hold; + u8 msg_fast_tx_interval; + u8 tx_crd; + u8 tx_crd_max; + u8 tx_fast; + u8 reserved1; #endif -#define REM_CHASSIS_ID_STAT_LEN 4 -#define REM_PORT_ID_STAT_LEN 4 + #define REM_CHASSIS_ID_STAT_LEN 4 + #define REM_PORT_ID_STAT_LEN 4 + /* Holds remote Chassis ID TLV header, subtype and 9B of payload. */ u32 peer_chassis_id[REM_CHASSIS_ID_STAT_LEN]; + /* Holds remote Port ID TLV header, subtype and 9B of payload. */ u32 peer_port_id[REM_PORT_ID_STAT_LEN]; }; struct lldp_dcbx_stat { -#define LOCAL_CHASSIS_ID_STAT_LEN 2 -#define LOCAL_PORT_ID_STAT_LEN 2 + #define LOCAL_CHASSIS_ID_STAT_LEN 2 + #define LOCAL_PORT_ID_STAT_LEN 2 + /* Holds local Chassis ID 8B payload of constant subtype 4. */ u32 local_chassis_id[LOCAL_CHASSIS_ID_STAT_LEN]; + /* Holds local Port ID 8B payload of constant subtype 3. */ u32 local_port_id[LOCAL_PORT_ID_STAT_LEN]; + /* Number of DCBX frames transmitted. */ u32 num_tx_dcbx_pkts; + /* Number of DCBX frames received. */ u32 num_rx_dcbx_pkts; }; +/* ADMIN MIB - DCBX local machine default configuration. */ struct lldp_admin_mib { - u32 ver_cfg_flags; -#define DCBX_ETS_CONFIG_TX_ENABLED 0x00000001 -#define DCBX_PFC_CONFIG_TX_ENABLED 0x00000002 -#define DCBX_APP_CONFIG_TX_ENABLED 0x00000004 -#define DCBX_ETS_RECO_TX_ENABLED 0x00000008 -#define DCBX_ETS_RECO_VALID 0x00000010 -#define DCBX_ETS_WILLING 0x00000020 -#define DCBX_PFC_WILLING 0x00000040 -#define DCBX_APP_WILLING 0x00000080 -#define DCBX_VERSION_CEE 0x00000100 -#define DCBX_VERSION_IEEE 0x00000200 -#define DCBX_DCBX_ENABLED 0x00000400 -#define DCBX_CEE_VERSION_MASK 0x0000f000 -#define DCBX_CEE_VERSION_SHIFT 12 -#define DCBX_CEE_MAX_VERSION_MASK 0x000f0000 -#define DCBX_CEE_MAX_VERSION_SHIFT 16 - struct dcbx_features features; -}; - + u32 ver_cfg_flags; + #define DCBX_ETS_CONFIG_TX_ENABLED 0x00000001 + #define DCBX_PFC_CONFIG_TX_ENABLED 0x00000002 + #define DCBX_APP_CONFIG_TX_ENABLED 0x00000004 + #define DCBX_ETS_RECO_TX_ENABLED 0x00000008 + #define DCBX_ETS_RECO_VALID 0x00000010 + #define DCBX_ETS_WILLING 0x00000020 + #define DCBX_PFC_WILLING 0x00000040 + #define DCBX_APP_WILLING 0x00000080 + #define DCBX_VERSION_CEE 0x00000100 + #define DCBX_VERSION_IEEE 0x00000200 + #define DCBX_DCBX_ENABLED 0x00000400 + #define DCBX_CEE_VERSION_MASK 0x0000f000 + #define DCBX_CEE_VERSION_SHIFT 12 + #define DCBX_CEE_MAX_VERSION_MASK 0x000f0000 + #define DCBX_CEE_MAX_VERSION_SHIFT 16 + struct dcbx_features features; +}; + +/* REMOTE MIB - remote machine DCBX configuration. */ struct lldp_remote_mib { u32 prefix_seq_num; u32 flags; -#define DCBX_ETS_TLV_RX 0x00000001 -#define DCBX_PFC_TLV_RX 0x00000002 -#define DCBX_APP_TLV_RX 0x00000004 -#define DCBX_ETS_RX_ERROR 0x00000010 -#define DCBX_PFC_RX_ERROR 0x00000020 -#define DCBX_APP_RX_ERROR 0x00000040 -#define DCBX_ETS_REM_WILLING 0x00000100 -#define DCBX_PFC_REM_WILLING 0x00000200 -#define DCBX_APP_REM_WILLING 0x00000400 -#define DCBX_REMOTE_ETS_RECO_VALID 0x00001000 + #define DCBX_ETS_TLV_RX 0x00000001 + #define DCBX_PFC_TLV_RX 0x00000002 + #define DCBX_APP_TLV_RX 0x00000004 + #define DCBX_ETS_RX_ERROR 0x00000010 + #define DCBX_PFC_RX_ERROR 0x00000020 + #define DCBX_APP_RX_ERROR 0x00000040 + #define DCBX_ETS_REM_WILLING 0x00000100 + #define DCBX_PFC_REM_WILLING 0x00000200 + #define DCBX_APP_REM_WILLING 0x00000400 + #define DCBX_REMOTE_ETS_RECO_VALID 0x00001000 + #define DCBX_REMOTE_MIB_VALID 0x00002000 struct dcbx_features features; u32 suffix_seq_num; }; +/* LOCAL MIB - operational DCBX configuration - transmitted on Tx LLDPDU. */ struct lldp_local_mib { u32 prefix_seq_num; + /* Indicates if there is mismatch with negotiation results. */ u32 error; -#define DCBX_LOCAL_ETS_ERROR 0x00000001 -#define DCBX_LOCAL_PFC_ERROR 0x00000002 -#define DCBX_LOCAL_APP_ERROR 0x00000004 -#define DCBX_LOCAL_PFC_MISMATCH 0x00000010 -#define DCBX_LOCAL_APP_MISMATCH 0x00000020 + #define DCBX_LOCAL_ETS_ERROR 0x00000001 + #define DCBX_LOCAL_PFC_ERROR 0x00000002 + #define DCBX_LOCAL_APP_ERROR 0x00000004 + #define DCBX_LOCAL_PFC_MISMATCH 0x00000010 + #define DCBX_LOCAL_APP_MISMATCH 0x00000020 struct dcbx_features features; u32 suffix_seq_num; }; /***END OF DCBX STRUCTURES DECLARATIONS***/ +struct ncsi_oem_fcoe_features { + u32 fcoe_features1; + #define FCOE_FEATURES1_IOS_PER_CONNECTION_MASK 0x0000FFFF + #define FCOE_FEATURES1_IOS_PER_CONNECTION_OFFSET 0 + + #define FCOE_FEATURES1_LOGINS_PER_PORT_MASK 0xFFFF0000 + #define FCOE_FEATURES1_LOGINS_PER_PORT_OFFSET 16 + + u32 fcoe_features2; + #define FCOE_FEATURES2_EXCHANGES_MASK 0x0000FFFF + #define FCOE_FEATURES2_EXCHANGES_OFFSET 0 + + #define FCOE_FEATURES2_NPIV_WWN_PER_PORT_MASK 0xFFFF0000 + #define FCOE_FEATURES2_NPIV_WWN_PER_PORT_OFFSET 16 + + u32 fcoe_features3; + #define FCOE_FEATURES3_TARGETS_SUPPORTED_MASK 0x0000FFFF + #define FCOE_FEATURES3_TARGETS_SUPPORTED_OFFSET 0 + + #define FCOE_FEATURES3_OUTSTANDING_COMMANDS_MASK 0xFFFF0000 + #define FCOE_FEATURES3_OUTSTANDING_COMMANDS_OFFSET 16 + + u32 fcoe_features4; + #define FCOE_FEATURES4_FEATURE_SETTINGS_MASK 0x0000000F + #define FCOE_FEATURES4_FEATURE_SETTINGS_OFFSET 0 +}; + +struct ncsi_oem_data { + u32 driver_version[4]; + struct ncsi_oem_fcoe_features ncsi_oem_fcoe_features; +}; + struct shmem2_region { - u32 size; - - u32 dcc_support; -#define SHMEM_DCC_SUPPORT_NONE 0x00000000 -#define SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV 0x00000001 -#define SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV 0x00000004 -#define SHMEM_DCC_SUPPORT_CHANGE_MAC_ADDRESS_TLV 0x00000008 -#define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV 0x00000040 -#define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV 0x00000080 -#define SHMEM_DCC_SUPPORT_DEFAULT SHMEM_DCC_SUPPORT_NONE - u32 ext_phy_fw_version2[PORT_MAX]; + u32 size; /* 0x0000 */ + + u32 dcc_support; /* 0x0004 */ + #define SHMEM_DCC_SUPPORT_NONE 0x00000000 + #define SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV 0x00000001 + #define SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV 0x00000004 + #define SHMEM_DCC_SUPPORT_CHANGE_MAC_ADDRESS_TLV 0x00000008 + #define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV 0x00000040 + #define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV 0x00000080 + + u32 ext_phy_fw_version2[PORT_MAX]; /* 0x0008 */ /* * For backwards compatibility, if the mf_cfg_addr does not exist * (the size filed is smaller than 0xc) the mf_cfg resides at the * end of struct shmem_region - */ - u32 mf_cfg_addr; -#define SHMEM_MF_CFG_ADDR_NONE 0x00000000 - - struct fw_flr_mb flr_mb; - u32 dcbx_lldp_params_offset; -#define SHMEM_LLDP_DCBX_PARAMS_NONE 0x00000000 - u32 dcbx_neg_res_offset; -#define SHMEM_DCBX_NEG_RES_NONE 0x00000000 - u32 dcbx_remote_mib_offset; -#define SHMEM_DCBX_REMOTE_MIB_NONE 0x00000000 + */ + u32 mf_cfg_addr; /* 0x0010 */ + #define SHMEM_MF_CFG_ADDR_NONE 0x00000000 + + struct fw_flr_mb flr_mb; /* 0x0014 */ + u32 dcbx_lldp_params_offset; /* 0x0028 */ + #define SHMEM_LLDP_DCBX_PARAMS_NONE 0x00000000 + u32 dcbx_neg_res_offset; /* 0x002c */ + #define SHMEM_DCBX_NEG_RES_NONE 0x00000000 + u32 dcbx_remote_mib_offset; /* 0x0030 */ + #define SHMEM_DCBX_REMOTE_MIB_NONE 0x00000000 /* * The other shmemX_base_addr holds the other path's shmem address * required for example in case of common phy init, or for path1 to know * the address of mcp debug trace which is located in offset from shmem * of path0 */ - u32 other_shmem_base_addr; - u32 other_shmem2_base_addr; - u32 reserved1[E2_VF_MAX / 32]; - u32 reserved2[E2_FUNC_MAX][E2_VF_MAX / 32]; - u32 dcbx_lldp_dcbx_stat_offset; -#define SHMEM_LLDP_DCBX_STAT_NONE 0x00000000 + u32 other_shmem_base_addr; /* 0x0034 */ + u32 other_shmem2_base_addr; /* 0x0038 */ + /* + * mcp_vf_disabled is set by the MCP to indicate the driver about VFs + * which were disabled/flred + */ + u32 mcp_vf_disabled[E2_VF_MAX / 32]; /* 0x003c */ + + /* + * drv_ack_vf_disabled is set by the PF driver to ack handled disabled + * VFs + */ + u32 drv_ack_vf_disabled[E2_FUNC_MAX][E2_VF_MAX / 32]; /* 0x0044 */ + + u32 dcbx_lldp_dcbx_stat_offset; /* 0x0064 */ + #define SHMEM_LLDP_DCBX_STAT_NONE 0x00000000 + + /* + * edebug_driver_if field is used to transfer messages between edebug + * app to the driver through shmem2. + * + * message format: + * bits 0-2 - function number / instance of driver to perform request + * bits 3-5 - op code / is_ack? + * bits 6-63 - data + */ + u32 edebug_driver_if[2]; /* 0x0068 */ + #define EDEBUG_DRIVER_IF_OP_CODE_GET_PHYS_ADDR 1 + #define EDEBUG_DRIVER_IF_OP_CODE_GET_BUS_ADDR 2 + #define EDEBUG_DRIVER_IF_OP_CODE_DISABLE_STAT 3 + + u32 nvm_retain_bitmap_addr; /* 0x0070 */ + + u32 reserved1; /* 0x0074 */ + + u32 reserved2[E2_FUNC_MAX]; + + u32 reserved3[E2_FUNC_MAX];/* 0x0088 */ + u32 reserved4[E2_FUNC_MAX];/* 0x0098 */ + + u32 swim_base_addr; /* 0x0108 */ + u32 swim_funcs; + u32 swim_main_cb; + + u32 reserved5[2]; + + /* generic flags controlled by the driver */ + u32 drv_flags; + #define DRV_FLAGS_DCB_CONFIGURED 0x1 + + /* pointer to extended dev_info shared data copied from nvm image */ + u32 extended_dev_info_shared_addr; + u32 ncsi_oem_data_addr; + + u32 ocsd_host_addr; + u32 ocbb_host_addr; + u32 ocsd_req_update_interval; }; struct emac_stats { - u32 rx_stat_ifhcinoctets; - u32 rx_stat_ifhcinbadoctets; - u32 rx_stat_etherstatsfragments; - u32 rx_stat_ifhcinucastpkts; - u32 rx_stat_ifhcinmulticastpkts; - u32 rx_stat_ifhcinbroadcastpkts; - u32 rx_stat_dot3statsfcserrors; - u32 rx_stat_dot3statsalignmenterrors; - u32 rx_stat_dot3statscarriersenseerrors; - u32 rx_stat_xonpauseframesreceived; - u32 rx_stat_xoffpauseframesreceived; - u32 rx_stat_maccontrolframesreceived; - u32 rx_stat_xoffstateentered; - u32 rx_stat_dot3statsframestoolong; - u32 rx_stat_etherstatsjabbers; - u32 rx_stat_etherstatsundersizepkts; - u32 rx_stat_etherstatspkts64octets; - u32 rx_stat_etherstatspkts65octetsto127octets; - u32 rx_stat_etherstatspkts128octetsto255octets; - u32 rx_stat_etherstatspkts256octetsto511octets; - u32 rx_stat_etherstatspkts512octetsto1023octets; - u32 rx_stat_etherstatspkts1024octetsto1522octets; - u32 rx_stat_etherstatspktsover1522octets; - - u32 rx_stat_falsecarriererrors; - - u32 tx_stat_ifhcoutoctets; - u32 tx_stat_ifhcoutbadoctets; - u32 tx_stat_etherstatscollisions; - u32 tx_stat_outxonsent; - u32 tx_stat_outxoffsent; - u32 tx_stat_flowcontroldone; - u32 tx_stat_dot3statssinglecollisionframes; - u32 tx_stat_dot3statsmultiplecollisionframes; - u32 tx_stat_dot3statsdeferredtransmissions; - u32 tx_stat_dot3statsexcessivecollisions; - u32 tx_stat_dot3statslatecollisions; - u32 tx_stat_ifhcoutucastpkts; - u32 tx_stat_ifhcoutmulticastpkts; - u32 tx_stat_ifhcoutbroadcastpkts; - u32 tx_stat_etherstatspkts64octets; - u32 tx_stat_etherstatspkts65octetsto127octets; - u32 tx_stat_etherstatspkts128octetsto255octets; - u32 tx_stat_etherstatspkts256octetsto511octets; - u32 tx_stat_etherstatspkts512octetsto1023octets; - u32 tx_stat_etherstatspkts1024octetsto1522octets; - u32 tx_stat_etherstatspktsover1522octets; - u32 tx_stat_dot3statsinternalmactransmiterrors; + u32 rx_stat_ifhcinoctets; + u32 rx_stat_ifhcinbadoctets; + u32 rx_stat_etherstatsfragments; + u32 rx_stat_ifhcinucastpkts; + u32 rx_stat_ifhcinmulticastpkts; + u32 rx_stat_ifhcinbroadcastpkts; + u32 rx_stat_dot3statsfcserrors; + u32 rx_stat_dot3statsalignmenterrors; + u32 rx_stat_dot3statscarriersenseerrors; + u32 rx_stat_xonpauseframesreceived; + u32 rx_stat_xoffpauseframesreceived; + u32 rx_stat_maccontrolframesreceived; + u32 rx_stat_xoffstateentered; + u32 rx_stat_dot3statsframestoolong; + u32 rx_stat_etherstatsjabbers; + u32 rx_stat_etherstatsundersizepkts; + u32 rx_stat_etherstatspkts64octets; + u32 rx_stat_etherstatspkts65octetsto127octets; + u32 rx_stat_etherstatspkts128octetsto255octets; + u32 rx_stat_etherstatspkts256octetsto511octets; + u32 rx_stat_etherstatspkts512octetsto1023octets; + u32 rx_stat_etherstatspkts1024octetsto1522octets; + u32 rx_stat_etherstatspktsover1522octets; + + u32 rx_stat_falsecarriererrors; + + u32 tx_stat_ifhcoutoctets; + u32 tx_stat_ifhcoutbadoctets; + u32 tx_stat_etherstatscollisions; + u32 tx_stat_outxonsent; + u32 tx_stat_outxoffsent; + u32 tx_stat_flowcontroldone; + u32 tx_stat_dot3statssinglecollisionframes; + u32 tx_stat_dot3statsmultiplecollisionframes; + u32 tx_stat_dot3statsdeferredtransmissions; + u32 tx_stat_dot3statsexcessivecollisions; + u32 tx_stat_dot3statslatecollisions; + u32 tx_stat_ifhcoutucastpkts; + u32 tx_stat_ifhcoutmulticastpkts; + u32 tx_stat_ifhcoutbroadcastpkts; + u32 tx_stat_etherstatspkts64octets; + u32 tx_stat_etherstatspkts65octetsto127octets; + u32 tx_stat_etherstatspkts128octetsto255octets; + u32 tx_stat_etherstatspkts256octetsto511octets; + u32 tx_stat_etherstatspkts512octetsto1023octets; + u32 tx_stat_etherstatspkts1024octetsto1522octets; + u32 tx_stat_etherstatspktsover1522octets; + u32 tx_stat_dot3statsinternalmactransmiterrors; }; struct bmac1_stats { - u32 tx_stat_gtpkt_lo; - u32 tx_stat_gtpkt_hi; - u32 tx_stat_gtxpf_lo; - u32 tx_stat_gtxpf_hi; - u32 tx_stat_gtfcs_lo; - u32 tx_stat_gtfcs_hi; - u32 tx_stat_gtmca_lo; - u32 tx_stat_gtmca_hi; - u32 tx_stat_gtbca_lo; - u32 tx_stat_gtbca_hi; - u32 tx_stat_gtfrg_lo; - u32 tx_stat_gtfrg_hi; - u32 tx_stat_gtovr_lo; - u32 tx_stat_gtovr_hi; - u32 tx_stat_gt64_lo; - u32 tx_stat_gt64_hi; - u32 tx_stat_gt127_lo; - u32 tx_stat_gt127_hi; - u32 tx_stat_gt255_lo; - u32 tx_stat_gt255_hi; - u32 tx_stat_gt511_lo; - u32 tx_stat_gt511_hi; - u32 tx_stat_gt1023_lo; - u32 tx_stat_gt1023_hi; - u32 tx_stat_gt1518_lo; - u32 tx_stat_gt1518_hi; - u32 tx_stat_gt2047_lo; - u32 tx_stat_gt2047_hi; - u32 tx_stat_gt4095_lo; - u32 tx_stat_gt4095_hi; - u32 tx_stat_gt9216_lo; - u32 tx_stat_gt9216_hi; - u32 tx_stat_gt16383_lo; - u32 tx_stat_gt16383_hi; - u32 tx_stat_gtmax_lo; - u32 tx_stat_gtmax_hi; - u32 tx_stat_gtufl_lo; - u32 tx_stat_gtufl_hi; - u32 tx_stat_gterr_lo; - u32 tx_stat_gterr_hi; - u32 tx_stat_gtbyt_lo; - u32 tx_stat_gtbyt_hi; - - u32 rx_stat_gr64_lo; - u32 rx_stat_gr64_hi; - u32 rx_stat_gr127_lo; - u32 rx_stat_gr127_hi; - u32 rx_stat_gr255_lo; - u32 rx_stat_gr255_hi; - u32 rx_stat_gr511_lo; - u32 rx_stat_gr511_hi; - u32 rx_stat_gr1023_lo; - u32 rx_stat_gr1023_hi; - u32 rx_stat_gr1518_lo; - u32 rx_stat_gr1518_hi; - u32 rx_stat_gr2047_lo; - u32 rx_stat_gr2047_hi; - u32 rx_stat_gr4095_lo; - u32 rx_stat_gr4095_hi; - u32 rx_stat_gr9216_lo; - u32 rx_stat_gr9216_hi; - u32 rx_stat_gr16383_lo; - u32 rx_stat_gr16383_hi; - u32 rx_stat_grmax_lo; - u32 rx_stat_grmax_hi; - u32 rx_stat_grpkt_lo; - u32 rx_stat_grpkt_hi; - u32 rx_stat_grfcs_lo; - u32 rx_stat_grfcs_hi; - u32 rx_stat_grmca_lo; - u32 rx_stat_grmca_hi; - u32 rx_stat_grbca_lo; - u32 rx_stat_grbca_hi; - u32 rx_stat_grxcf_lo; - u32 rx_stat_grxcf_hi; - u32 rx_stat_grxpf_lo; - u32 rx_stat_grxpf_hi; - u32 rx_stat_grxuo_lo; - u32 rx_stat_grxuo_hi; - u32 rx_stat_grjbr_lo; - u32 rx_stat_grjbr_hi; - u32 rx_stat_grovr_lo; - u32 rx_stat_grovr_hi; - u32 rx_stat_grflr_lo; - u32 rx_stat_grflr_hi; - u32 rx_stat_grmeg_lo; - u32 rx_stat_grmeg_hi; - u32 rx_stat_grmeb_lo; - u32 rx_stat_grmeb_hi; - u32 rx_stat_grbyt_lo; - u32 rx_stat_grbyt_hi; - u32 rx_stat_grund_lo; - u32 rx_stat_grund_hi; - u32 rx_stat_grfrg_lo; - u32 rx_stat_grfrg_hi; - u32 rx_stat_grerb_lo; - u32 rx_stat_grerb_hi; - u32 rx_stat_grfre_lo; - u32 rx_stat_grfre_hi; - u32 rx_stat_gripj_lo; - u32 rx_stat_gripj_hi; + u32 tx_stat_gtpkt_lo; + u32 tx_stat_gtpkt_hi; + u32 tx_stat_gtxpf_lo; + u32 tx_stat_gtxpf_hi; + u32 tx_stat_gtfcs_lo; + u32 tx_stat_gtfcs_hi; + u32 tx_stat_gtmca_lo; + u32 tx_stat_gtmca_hi; + u32 tx_stat_gtbca_lo; + u32 tx_stat_gtbca_hi; + u32 tx_stat_gtfrg_lo; + u32 tx_stat_gtfrg_hi; + u32 tx_stat_gtovr_lo; + u32 tx_stat_gtovr_hi; + u32 tx_stat_gt64_lo; + u32 tx_stat_gt64_hi; + u32 tx_stat_gt127_lo; + u32 tx_stat_gt127_hi; + u32 tx_stat_gt255_lo; + u32 tx_stat_gt255_hi; + u32 tx_stat_gt511_lo; + u32 tx_stat_gt511_hi; + u32 tx_stat_gt1023_lo; + u32 tx_stat_gt1023_hi; + u32 tx_stat_gt1518_lo; + u32 tx_stat_gt1518_hi; + u32 tx_stat_gt2047_lo; + u32 tx_stat_gt2047_hi; + u32 tx_stat_gt4095_lo; + u32 tx_stat_gt4095_hi; + u32 tx_stat_gt9216_lo; + u32 tx_stat_gt9216_hi; + u32 tx_stat_gt16383_lo; + u32 tx_stat_gt16383_hi; + u32 tx_stat_gtmax_lo; + u32 tx_stat_gtmax_hi; + u32 tx_stat_gtufl_lo; + u32 tx_stat_gtufl_hi; + u32 tx_stat_gterr_lo; + u32 tx_stat_gterr_hi; + u32 tx_stat_gtbyt_lo; + u32 tx_stat_gtbyt_hi; + + u32 rx_stat_gr64_lo; + u32 rx_stat_gr64_hi; + u32 rx_stat_gr127_lo; + u32 rx_stat_gr127_hi; + u32 rx_stat_gr255_lo; + u32 rx_stat_gr255_hi; + u32 rx_stat_gr511_lo; + u32 rx_stat_gr511_hi; + u32 rx_stat_gr1023_lo; + u32 rx_stat_gr1023_hi; + u32 rx_stat_gr1518_lo; + u32 rx_stat_gr1518_hi; + u32 rx_stat_gr2047_lo; + u32 rx_stat_gr2047_hi; + u32 rx_stat_gr4095_lo; + u32 rx_stat_gr4095_hi; + u32 rx_stat_gr9216_lo; + u32 rx_stat_gr9216_hi; + u32 rx_stat_gr16383_lo; + u32 rx_stat_gr16383_hi; + u32 rx_stat_grmax_lo; + u32 rx_stat_grmax_hi; + u32 rx_stat_grpkt_lo; + u32 rx_stat_grpkt_hi; + u32 rx_stat_grfcs_lo; + u32 rx_stat_grfcs_hi; + u32 rx_stat_grmca_lo; + u32 rx_stat_grmca_hi; + u32 rx_stat_grbca_lo; + u32 rx_stat_grbca_hi; + u32 rx_stat_grxcf_lo; + u32 rx_stat_grxcf_hi; + u32 rx_stat_grxpf_lo; + u32 rx_stat_grxpf_hi; + u32 rx_stat_grxuo_lo; + u32 rx_stat_grxuo_hi; + u32 rx_stat_grjbr_lo; + u32 rx_stat_grjbr_hi; + u32 rx_stat_grovr_lo; + u32 rx_stat_grovr_hi; + u32 rx_stat_grflr_lo; + u32 rx_stat_grflr_hi; + u32 rx_stat_grmeg_lo; + u32 rx_stat_grmeg_hi; + u32 rx_stat_grmeb_lo; + u32 rx_stat_grmeb_hi; + u32 rx_stat_grbyt_lo; + u32 rx_stat_grbyt_hi; + u32 rx_stat_grund_lo; + u32 rx_stat_grund_hi; + u32 rx_stat_grfrg_lo; + u32 rx_stat_grfrg_hi; + u32 rx_stat_grerb_lo; + u32 rx_stat_grerb_hi; + u32 rx_stat_grfre_lo; + u32 rx_stat_grfre_hi; + u32 rx_stat_gripj_lo; + u32 rx_stat_gripj_hi; }; struct bmac2_stats { @@ -1766,187 +2228,316 @@ struct bmac2_stats { u32 rx_stat_gripj_hi; }; +struct mstat_stats { + struct { + /* OTE MSTAT on E3 has a bug where this register's contents are + * actually tx_gtxpok + tx_gtxpf + (possibly)tx_gtxpp + */ + u32 tx_gtxpok_lo; + u32 tx_gtxpok_hi; + u32 tx_gtxpf_lo; + u32 tx_gtxpf_hi; + u32 tx_gtxpp_lo; + u32 tx_gtxpp_hi; + u32 tx_gtfcs_lo; + u32 tx_gtfcs_hi; + u32 tx_gtuca_lo; + u32 tx_gtuca_hi; + u32 tx_gtmca_lo; + u32 tx_gtmca_hi; + u32 tx_gtgca_lo; + u32 tx_gtgca_hi; + u32 tx_gtpkt_lo; + u32 tx_gtpkt_hi; + u32 tx_gt64_lo; + u32 tx_gt64_hi; + u32 tx_gt127_lo; + u32 tx_gt127_hi; + u32 tx_gt255_lo; + u32 tx_gt255_hi; + u32 tx_gt511_lo; + u32 tx_gt511_hi; + u32 tx_gt1023_lo; + u32 tx_gt1023_hi; + u32 tx_gt1518_lo; + u32 tx_gt1518_hi; + u32 tx_gt2047_lo; + u32 tx_gt2047_hi; + u32 tx_gt4095_lo; + u32 tx_gt4095_hi; + u32 tx_gt9216_lo; + u32 tx_gt9216_hi; + u32 tx_gt16383_lo; + u32 tx_gt16383_hi; + u32 tx_gtufl_lo; + u32 tx_gtufl_hi; + u32 tx_gterr_lo; + u32 tx_gterr_hi; + u32 tx_gtbyt_lo; + u32 tx_gtbyt_hi; + u32 tx_collisions_lo; + u32 tx_collisions_hi; + u32 tx_singlecollision_lo; + u32 tx_singlecollision_hi; + u32 tx_multiplecollisions_lo; + u32 tx_multiplecollisions_hi; + u32 tx_deferred_lo; + u32 tx_deferred_hi; + u32 tx_excessivecollisions_lo; + u32 tx_excessivecollisions_hi; + u32 tx_latecollisions_lo; + u32 tx_latecollisions_hi; + } stats_tx; + + struct { + u32 rx_gr64_lo; + u32 rx_gr64_hi; + u32 rx_gr127_lo; + u32 rx_gr127_hi; + u32 rx_gr255_lo; + u32 rx_gr255_hi; + u32 rx_gr511_lo; + u32 rx_gr511_hi; + u32 rx_gr1023_lo; + u32 rx_gr1023_hi; + u32 rx_gr1518_lo; + u32 rx_gr1518_hi; + u32 rx_gr2047_lo; + u32 rx_gr2047_hi; + u32 rx_gr4095_lo; + u32 rx_gr4095_hi; + u32 rx_gr9216_lo; + u32 rx_gr9216_hi; + u32 rx_gr16383_lo; + u32 rx_gr16383_hi; + u32 rx_grpkt_lo; + u32 rx_grpkt_hi; + u32 rx_grfcs_lo; + u32 rx_grfcs_hi; + u32 rx_gruca_lo; + u32 rx_gruca_hi; + u32 rx_grmca_lo; + u32 rx_grmca_hi; + u32 rx_grbca_lo; + u32 rx_grbca_hi; + u32 rx_grxpf_lo; + u32 rx_grxpf_hi; + u32 rx_grxpp_lo; + u32 rx_grxpp_hi; + u32 rx_grxuo_lo; + u32 rx_grxuo_hi; + u32 rx_grovr_lo; + u32 rx_grovr_hi; + u32 rx_grxcf_lo; + u32 rx_grxcf_hi; + u32 rx_grflr_lo; + u32 rx_grflr_hi; + u32 rx_grpok_lo; + u32 rx_grpok_hi; + u32 rx_grbyt_lo; + u32 rx_grbyt_hi; + u32 rx_grund_lo; + u32 rx_grund_hi; + u32 rx_grfrg_lo; + u32 rx_grfrg_hi; + u32 rx_grerb_lo; + u32 rx_grerb_hi; + u32 rx_grfre_lo; + u32 rx_grfre_hi; + + u32 rx_alignmenterrors_lo; + u32 rx_alignmenterrors_hi; + u32 rx_falsecarrier_lo; + u32 rx_falsecarrier_hi; + u32 rx_llfcmsgcnt_lo; + u32 rx_llfcmsgcnt_hi; + } stats_rx; +}; + union mac_stats { - struct emac_stats emac_stats; - struct bmac1_stats bmac1_stats; - struct bmac2_stats bmac2_stats; + struct emac_stats emac_stats; + struct bmac1_stats bmac1_stats; + struct bmac2_stats bmac2_stats; + struct mstat_stats mstat_stats; }; struct mac_stx { - /* in_bad_octets */ - u32 rx_stat_ifhcinbadoctets_hi; - u32 rx_stat_ifhcinbadoctets_lo; - - /* out_bad_octets */ - u32 tx_stat_ifhcoutbadoctets_hi; - u32 tx_stat_ifhcoutbadoctets_lo; - - /* crc_receive_errors */ - u32 rx_stat_dot3statsfcserrors_hi; - u32 rx_stat_dot3statsfcserrors_lo; - /* alignment_errors */ - u32 rx_stat_dot3statsalignmenterrors_hi; - u32 rx_stat_dot3statsalignmenterrors_lo; - /* carrier_sense_errors */ - u32 rx_stat_dot3statscarriersenseerrors_hi; - u32 rx_stat_dot3statscarriersenseerrors_lo; - /* false_carrier_detections */ - u32 rx_stat_falsecarriererrors_hi; - u32 rx_stat_falsecarriererrors_lo; - - /* runt_packets_received */ - u32 rx_stat_etherstatsundersizepkts_hi; - u32 rx_stat_etherstatsundersizepkts_lo; - /* jabber_packets_received */ - u32 rx_stat_dot3statsframestoolong_hi; - u32 rx_stat_dot3statsframestoolong_lo; - - /* error_runt_packets_received */ - u32 rx_stat_etherstatsfragments_hi; - u32 rx_stat_etherstatsfragments_lo; - /* error_jabber_packets_received */ - u32 rx_stat_etherstatsjabbers_hi; - u32 rx_stat_etherstatsjabbers_lo; - - /* control_frames_received */ - u32 rx_stat_maccontrolframesreceived_hi; - u32 rx_stat_maccontrolframesreceived_lo; - u32 rx_stat_bmac_xpf_hi; - u32 rx_stat_bmac_xpf_lo; - u32 rx_stat_bmac_xcf_hi; - u32 rx_stat_bmac_xcf_lo; - - /* xoff_state_entered */ - u32 rx_stat_xoffstateentered_hi; - u32 rx_stat_xoffstateentered_lo; - /* pause_xon_frames_received */ - u32 rx_stat_xonpauseframesreceived_hi; - u32 rx_stat_xonpauseframesreceived_lo; - /* pause_xoff_frames_received */ - u32 rx_stat_xoffpauseframesreceived_hi; - u32 rx_stat_xoffpauseframesreceived_lo; - /* pause_xon_frames_transmitted */ - u32 tx_stat_outxonsent_hi; - u32 tx_stat_outxonsent_lo; - /* pause_xoff_frames_transmitted */ - u32 tx_stat_outxoffsent_hi; - u32 tx_stat_outxoffsent_lo; - /* flow_control_done */ - u32 tx_stat_flowcontroldone_hi; - u32 tx_stat_flowcontroldone_lo; - - /* ether_stats_collisions */ - u32 tx_stat_etherstatscollisions_hi; - u32 tx_stat_etherstatscollisions_lo; - /* single_collision_transmit_frames */ - u32 tx_stat_dot3statssinglecollisionframes_hi; - u32 tx_stat_dot3statssinglecollisionframes_lo; - /* multiple_collision_transmit_frames */ - u32 tx_stat_dot3statsmultiplecollisionframes_hi; - u32 tx_stat_dot3statsmultiplecollisionframes_lo; - /* deferred_transmissions */ - u32 tx_stat_dot3statsdeferredtransmissions_hi; - u32 tx_stat_dot3statsdeferredtransmissions_lo; - /* excessive_collision_frames */ - u32 tx_stat_dot3statsexcessivecollisions_hi; - u32 tx_stat_dot3statsexcessivecollisions_lo; - /* late_collision_frames */ - u32 tx_stat_dot3statslatecollisions_hi; - u32 tx_stat_dot3statslatecollisions_lo; - - /* frames_transmitted_64_bytes */ - u32 tx_stat_etherstatspkts64octets_hi; - u32 tx_stat_etherstatspkts64octets_lo; - /* frames_transmitted_65_127_bytes */ - u32 tx_stat_etherstatspkts65octetsto127octets_hi; - u32 tx_stat_etherstatspkts65octetsto127octets_lo; - /* frames_transmitted_128_255_bytes */ - u32 tx_stat_etherstatspkts128octetsto255octets_hi; - u32 tx_stat_etherstatspkts128octetsto255octets_lo; - /* frames_transmitted_256_511_bytes */ - u32 tx_stat_etherstatspkts256octetsto511octets_hi; - u32 tx_stat_etherstatspkts256octetsto511octets_lo; - /* frames_transmitted_512_1023_bytes */ - u32 tx_stat_etherstatspkts512octetsto1023octets_hi; - u32 tx_stat_etherstatspkts512octetsto1023octets_lo; - /* frames_transmitted_1024_1522_bytes */ - u32 tx_stat_etherstatspkts1024octetsto1522octets_hi; - u32 tx_stat_etherstatspkts1024octetsto1522octets_lo; - /* frames_transmitted_1523_9022_bytes */ - u32 tx_stat_etherstatspktsover1522octets_hi; - u32 tx_stat_etherstatspktsover1522octets_lo; - u32 tx_stat_bmac_2047_hi; - u32 tx_stat_bmac_2047_lo; - u32 tx_stat_bmac_4095_hi; - u32 tx_stat_bmac_4095_lo; - u32 tx_stat_bmac_9216_hi; - u32 tx_stat_bmac_9216_lo; - u32 tx_stat_bmac_16383_hi; - u32 tx_stat_bmac_16383_lo; - - /* internal_mac_transmit_errors */ - u32 tx_stat_dot3statsinternalmactransmiterrors_hi; - u32 tx_stat_dot3statsinternalmactransmiterrors_lo; - - /* if_out_discards */ - u32 tx_stat_bmac_ufl_hi; - u32 tx_stat_bmac_ufl_lo; -}; - - -#define MAC_STX_IDX_MAX 2 + /* in_bad_octets */ + u32 rx_stat_ifhcinbadoctets_hi; + u32 rx_stat_ifhcinbadoctets_lo; + + /* out_bad_octets */ + u32 tx_stat_ifhcoutbadoctets_hi; + u32 tx_stat_ifhcoutbadoctets_lo; + + /* crc_receive_errors */ + u32 rx_stat_dot3statsfcserrors_hi; + u32 rx_stat_dot3statsfcserrors_lo; + /* alignment_errors */ + u32 rx_stat_dot3statsalignmenterrors_hi; + u32 rx_stat_dot3statsalignmenterrors_lo; + /* carrier_sense_errors */ + u32 rx_stat_dot3statscarriersenseerrors_hi; + u32 rx_stat_dot3statscarriersenseerrors_lo; + /* false_carrier_detections */ + u32 rx_stat_falsecarriererrors_hi; + u32 rx_stat_falsecarriererrors_lo; + + /* runt_packets_received */ + u32 rx_stat_etherstatsundersizepkts_hi; + u32 rx_stat_etherstatsundersizepkts_lo; + /* jabber_packets_received */ + u32 rx_stat_dot3statsframestoolong_hi; + u32 rx_stat_dot3statsframestoolong_lo; + + /* error_runt_packets_received */ + u32 rx_stat_etherstatsfragments_hi; + u32 rx_stat_etherstatsfragments_lo; + /* error_jabber_packets_received */ + u32 rx_stat_etherstatsjabbers_hi; + u32 rx_stat_etherstatsjabbers_lo; + + /* control_frames_received */ + u32 rx_stat_maccontrolframesreceived_hi; + u32 rx_stat_maccontrolframesreceived_lo; + u32 rx_stat_mac_xpf_hi; + u32 rx_stat_mac_xpf_lo; + u32 rx_stat_mac_xcf_hi; + u32 rx_stat_mac_xcf_lo; + + /* xoff_state_entered */ + u32 rx_stat_xoffstateentered_hi; + u32 rx_stat_xoffstateentered_lo; + /* pause_xon_frames_received */ + u32 rx_stat_xonpauseframesreceived_hi; + u32 rx_stat_xonpauseframesreceived_lo; + /* pause_xoff_frames_received */ + u32 rx_stat_xoffpauseframesreceived_hi; + u32 rx_stat_xoffpauseframesreceived_lo; + /* pause_xon_frames_transmitted */ + u32 tx_stat_outxonsent_hi; + u32 tx_stat_outxonsent_lo; + /* pause_xoff_frames_transmitted */ + u32 tx_stat_outxoffsent_hi; + u32 tx_stat_outxoffsent_lo; + /* flow_control_done */ + u32 tx_stat_flowcontroldone_hi; + u32 tx_stat_flowcontroldone_lo; + + /* ether_stats_collisions */ + u32 tx_stat_etherstatscollisions_hi; + u32 tx_stat_etherstatscollisions_lo; + /* single_collision_transmit_frames */ + u32 tx_stat_dot3statssinglecollisionframes_hi; + u32 tx_stat_dot3statssinglecollisionframes_lo; + /* multiple_collision_transmit_frames */ + u32 tx_stat_dot3statsmultiplecollisionframes_hi; + u32 tx_stat_dot3statsmultiplecollisionframes_lo; + /* deferred_transmissions */ + u32 tx_stat_dot3statsdeferredtransmissions_hi; + u32 tx_stat_dot3statsdeferredtransmissions_lo; + /* excessive_collision_frames */ + u32 tx_stat_dot3statsexcessivecollisions_hi; + u32 tx_stat_dot3statsexcessivecollisions_lo; + /* late_collision_frames */ + u32 tx_stat_dot3statslatecollisions_hi; + u32 tx_stat_dot3statslatecollisions_lo; + + /* frames_transmitted_64_bytes */ + u32 tx_stat_etherstatspkts64octets_hi; + u32 tx_stat_etherstatspkts64octets_lo; + /* frames_transmitted_65_127_bytes */ + u32 tx_stat_etherstatspkts65octetsto127octets_hi; + u32 tx_stat_etherstatspkts65octetsto127octets_lo; + /* frames_transmitted_128_255_bytes */ + u32 tx_stat_etherstatspkts128octetsto255octets_hi; + u32 tx_stat_etherstatspkts128octetsto255octets_lo; + /* frames_transmitted_256_511_bytes */ + u32 tx_stat_etherstatspkts256octetsto511octets_hi; + u32 tx_stat_etherstatspkts256octetsto511octets_lo; + /* frames_transmitted_512_1023_bytes */ + u32 tx_stat_etherstatspkts512octetsto1023octets_hi; + u32 tx_stat_etherstatspkts512octetsto1023octets_lo; + /* frames_transmitted_1024_1522_bytes */ + u32 tx_stat_etherstatspkts1024octetsto1522octets_hi; + u32 tx_stat_etherstatspkts1024octetsto1522octets_lo; + /* frames_transmitted_1523_9022_bytes */ + u32 tx_stat_etherstatspktsover1522octets_hi; + u32 tx_stat_etherstatspktsover1522octets_lo; + u32 tx_stat_mac_2047_hi; + u32 tx_stat_mac_2047_lo; + u32 tx_stat_mac_4095_hi; + u32 tx_stat_mac_4095_lo; + u32 tx_stat_mac_9216_hi; + u32 tx_stat_mac_9216_lo; + u32 tx_stat_mac_16383_hi; + u32 tx_stat_mac_16383_lo; + + /* internal_mac_transmit_errors */ + u32 tx_stat_dot3statsinternalmactransmiterrors_hi; + u32 tx_stat_dot3statsinternalmactransmiterrors_lo; + + /* if_out_discards */ + u32 tx_stat_mac_ufl_hi; + u32 tx_stat_mac_ufl_lo; +}; + + +#define MAC_STX_IDX_MAX 2 struct host_port_stats { - u32 host_port_stats_start; + u32 host_port_stats_start; - struct mac_stx mac_stx[MAC_STX_IDX_MAX]; + struct mac_stx mac_stx[MAC_STX_IDX_MAX]; - u32 brb_drop_hi; - u32 brb_drop_lo; + u32 brb_drop_hi; + u32 brb_drop_lo; - u32 host_port_stats_end; + u32 host_port_stats_end; }; struct host_func_stats { - u32 host_func_stats_start; + u32 host_func_stats_start; - u32 total_bytes_received_hi; - u32 total_bytes_received_lo; + u32 total_bytes_received_hi; + u32 total_bytes_received_lo; - u32 total_bytes_transmitted_hi; - u32 total_bytes_transmitted_lo; + u32 total_bytes_transmitted_hi; + u32 total_bytes_transmitted_lo; - u32 total_unicast_packets_received_hi; - u32 total_unicast_packets_received_lo; + u32 total_unicast_packets_received_hi; + u32 total_unicast_packets_received_lo; - u32 total_multicast_packets_received_hi; - u32 total_multicast_packets_received_lo; + u32 total_multicast_packets_received_hi; + u32 total_multicast_packets_received_lo; - u32 total_broadcast_packets_received_hi; - u32 total_broadcast_packets_received_lo; + u32 total_broadcast_packets_received_hi; + u32 total_broadcast_packets_received_lo; - u32 total_unicast_packets_transmitted_hi; - u32 total_unicast_packets_transmitted_lo; + u32 total_unicast_packets_transmitted_hi; + u32 total_unicast_packets_transmitted_lo; - u32 total_multicast_packets_transmitted_hi; - u32 total_multicast_packets_transmitted_lo; + u32 total_multicast_packets_transmitted_hi; + u32 total_multicast_packets_transmitted_lo; - u32 total_broadcast_packets_transmitted_hi; - u32 total_broadcast_packets_transmitted_lo; + u32 total_broadcast_packets_transmitted_hi; + u32 total_broadcast_packets_transmitted_lo; - u32 valid_bytes_received_hi; - u32 valid_bytes_received_lo; + u32 valid_bytes_received_hi; + u32 valid_bytes_received_lo; - u32 host_func_stats_end; + u32 host_func_stats_end; }; +/* VIC definitions */ +#define VICSTATST_UIF_INDEX 2 -#define BCM_5710_FW_MAJOR_VERSION 6 -#define BCM_5710_FW_MINOR_VERSION 2 -#define BCM_5710_FW_REVISION_VERSION 9 -#define BCM_5710_FW_ENGINEERING_VERSION 0 +#define BCM_5710_FW_MAJOR_VERSION 7 +#define BCM_5710_FW_MINOR_VERSION 0 +#define BCM_5710_FW_REVISION_VERSION 20 +#define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 @@ -1964,48 +2555,153 @@ struct atten_sp_status_block { /* - * common data for all protocols + * The eth aggregative context of Cstorm */ -struct doorbell_hdr { - u8 header; -#define DOORBELL_HDR_RX (0x1<<0) -#define DOORBELL_HDR_RX_SHIFT 0 -#define DOORBELL_HDR_DB_TYPE (0x1<<1) -#define DOORBELL_HDR_DB_TYPE_SHIFT 1 -#define DOORBELL_HDR_DPM_SIZE (0x3<<2) -#define DOORBELL_HDR_DPM_SIZE_SHIFT 2 -#define DOORBELL_HDR_CONN_TYPE (0xF<<4) -#define DOORBELL_HDR_CONN_TYPE_SHIFT 4 +struct cstorm_eth_ag_context { + u32 __reserved0[10]; }; + /* - * doorbell message sent to the chip + * dmae command structure */ -struct doorbell { +struct dmae_command { + u32 opcode; +#define DMAE_COMMAND_SRC (0x1<<0) +#define DMAE_COMMAND_SRC_SHIFT 0 +#define DMAE_COMMAND_DST (0x3<<1) +#define DMAE_COMMAND_DST_SHIFT 1 +#define DMAE_COMMAND_C_DST (0x1<<3) +#define DMAE_COMMAND_C_DST_SHIFT 3 +#define DMAE_COMMAND_C_TYPE_ENABLE (0x1<<4) +#define DMAE_COMMAND_C_TYPE_ENABLE_SHIFT 4 +#define DMAE_COMMAND_C_TYPE_CRC_ENABLE (0x1<<5) +#define DMAE_COMMAND_C_TYPE_CRC_ENABLE_SHIFT 5 +#define DMAE_COMMAND_C_TYPE_CRC_OFFSET (0x7<<6) +#define DMAE_COMMAND_C_TYPE_CRC_OFFSET_SHIFT 6 +#define DMAE_COMMAND_ENDIANITY (0x3<<9) +#define DMAE_COMMAND_ENDIANITY_SHIFT 9 +#define DMAE_COMMAND_PORT (0x1<<11) +#define DMAE_COMMAND_PORT_SHIFT 11 +#define DMAE_COMMAND_CRC_RESET (0x1<<12) +#define DMAE_COMMAND_CRC_RESET_SHIFT 12 +#define DMAE_COMMAND_SRC_RESET (0x1<<13) +#define DMAE_COMMAND_SRC_RESET_SHIFT 13 +#define DMAE_COMMAND_DST_RESET (0x1<<14) +#define DMAE_COMMAND_DST_RESET_SHIFT 14 +#define DMAE_COMMAND_E1HVN (0x3<<15) +#define DMAE_COMMAND_E1HVN_SHIFT 15 +#define DMAE_COMMAND_DST_VN (0x3<<17) +#define DMAE_COMMAND_DST_VN_SHIFT 17 +#define DMAE_COMMAND_C_FUNC (0x1<<19) +#define DMAE_COMMAND_C_FUNC_SHIFT 19 +#define DMAE_COMMAND_ERR_POLICY (0x3<<20) +#define DMAE_COMMAND_ERR_POLICY_SHIFT 20 +#define DMAE_COMMAND_RESERVED0 (0x3FF<<22) +#define DMAE_COMMAND_RESERVED0_SHIFT 22 + u32 src_addr_lo; + u32 src_addr_hi; + u32 dst_addr_lo; + u32 dst_addr_hi; #if defined(__BIG_ENDIAN) - u16 zero_fill2; - u8 zero_fill1; - struct doorbell_hdr header; + u16 opcode_iov; +#define DMAE_COMMAND_SRC_VFID (0x3F<<0) +#define DMAE_COMMAND_SRC_VFID_SHIFT 0 +#define DMAE_COMMAND_SRC_VFPF (0x1<<6) +#define DMAE_COMMAND_SRC_VFPF_SHIFT 6 +#define DMAE_COMMAND_RESERVED1 (0x1<<7) +#define DMAE_COMMAND_RESERVED1_SHIFT 7 +#define DMAE_COMMAND_DST_VFID (0x3F<<8) +#define DMAE_COMMAND_DST_VFID_SHIFT 8 +#define DMAE_COMMAND_DST_VFPF (0x1<<14) +#define DMAE_COMMAND_DST_VFPF_SHIFT 14 +#define DMAE_COMMAND_RESERVED2 (0x1<<15) +#define DMAE_COMMAND_RESERVED2_SHIFT 15 + u16 len; #elif defined(__LITTLE_ENDIAN) - struct doorbell_hdr header; - u8 zero_fill1; - u16 zero_fill2; + u16 len; + u16 opcode_iov; +#define DMAE_COMMAND_SRC_VFID (0x3F<<0) +#define DMAE_COMMAND_SRC_VFID_SHIFT 0 +#define DMAE_COMMAND_SRC_VFPF (0x1<<6) +#define DMAE_COMMAND_SRC_VFPF_SHIFT 6 +#define DMAE_COMMAND_RESERVED1 (0x1<<7) +#define DMAE_COMMAND_RESERVED1_SHIFT 7 +#define DMAE_COMMAND_DST_VFID (0x3F<<8) +#define DMAE_COMMAND_DST_VFID_SHIFT 8 +#define DMAE_COMMAND_DST_VFPF (0x1<<14) +#define DMAE_COMMAND_DST_VFPF_SHIFT 14 +#define DMAE_COMMAND_RESERVED2 (0x1<<15) +#define DMAE_COMMAND_RESERVED2_SHIFT 15 #endif -}; - - + u32 comp_addr_lo; + u32 comp_addr_hi; + u32 comp_val; + u32 crc32; + u32 crc32_c; +#if defined(__BIG_ENDIAN) + u16 crc16_c; + u16 crc16; +#elif defined(__LITTLE_ENDIAN) + u16 crc16; + u16 crc16_c; +#endif +#if defined(__BIG_ENDIAN) + u16 reserved3; + u16 crc_t10; +#elif defined(__LITTLE_ENDIAN) + u16 crc_t10; + u16 reserved3; +#endif +#if defined(__BIG_ENDIAN) + u16 xsum8; + u16 xsum16; +#elif defined(__LITTLE_ENDIAN) + u16 xsum16; + u16 xsum8; +#endif +}; + + /* - * doorbell message sent to the chip + * common data for all protocols */ -struct doorbell_set_prod { +struct doorbell_hdr { + u8 header; +#define DOORBELL_HDR_RX (0x1<<0) +#define DOORBELL_HDR_RX_SHIFT 0 +#define DOORBELL_HDR_DB_TYPE (0x1<<1) +#define DOORBELL_HDR_DB_TYPE_SHIFT 1 +#define DOORBELL_HDR_DPM_SIZE (0x3<<2) +#define DOORBELL_HDR_DPM_SIZE_SHIFT 2 +#define DOORBELL_HDR_CONN_TYPE (0xF<<4) +#define DOORBELL_HDR_CONN_TYPE_SHIFT 4 +}; + +/* + * Ethernet doorbell + */ +struct eth_tx_doorbell { #if defined(__BIG_ENDIAN) - u16 prod; - u8 zero_fill1; - struct doorbell_hdr header; + u16 npackets; + u8 params; +#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0) +#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0 +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6) +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6 +#define ETH_TX_DOORBELL_SPARE (0x1<<7) +#define ETH_TX_DOORBELL_SPARE_SHIFT 7 + struct doorbell_hdr hdr; #elif defined(__LITTLE_ENDIAN) - struct doorbell_hdr header; - u8 zero_fill1; - u16 prod; + struct doorbell_hdr hdr; + u8 params; +#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0) +#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0 +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6) +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6 +#define ETH_TX_DOORBELL_SPARE (0x1<<7) +#define ETH_TX_DOORBELL_SPARE_SHIFT 7 + u16 npackets; #endif }; @@ -2016,7 +2712,7 @@ struct doorbell_set_prod { struct hc_status_block_e1x { __le16 index_values[HC_SB_MAX_INDICES_E1X]; __le16 running_index[HC_SB_MAX_SM]; - u32 rsrv; + __le32 rsrv[11]; }; /* @@ -2033,7 +2729,7 @@ struct host_hc_status_block_e1x { struct hc_status_block_e2 { __le16 index_values[HC_SB_MAX_INDICES_E2]; __le16 running_index[HC_SB_MAX_SM]; - u32 reserved; + __le32 reserved[11]; }; /* @@ -2153,6 +2849,16 @@ union igu_consprod_reg { }; +/* + * Igu control commands + */ +enum igu_ctrl_cmd { + IGU_CTRL_CMD_TYPE_RD, + IGU_CTRL_CMD_TYPE_WR, + MAX_IGU_CTRL_CMD +}; + + /* * Control register for the IGU command register */ @@ -2171,6 +2877,29 @@ struct igu_ctrl_reg { }; +/* + * Igu interrupt command + */ +enum igu_int_cmd { + IGU_INT_ENABLE, + IGU_INT_DISABLE, + IGU_INT_NOP, + IGU_INT_NOP2, + MAX_IGU_INT_CMD +}; + + +/* + * Igu segments + */ +enum igu_seg_access { + IGU_SEG_ACCESS_NORM, + IGU_SEG_ACCESS_DEF, + IGU_SEG_ACCESS_ATTN, + MAX_IGU_SEG_ACCESS +}; + + /* * Parser parsing flags field */ @@ -2205,94 +2934,46 @@ struct parsing_flags { }; -struct regpair { - __le32 lo; - __le32 hi; +/* + * Parsing flags for TCP ACK type + */ +enum prs_flags_ack_type { + PRS_FLAG_PUREACK_PIGGY, + PRS_FLAG_PUREACK_PURE, + MAX_PRS_FLAGS_ACK_TYPE }; /* - * dmae command structure + * Parsing flags for Ethernet address type */ -struct dmae_command { - u32 opcode; -#define DMAE_COMMAND_SRC (0x1<<0) -#define DMAE_COMMAND_SRC_SHIFT 0 -#define DMAE_COMMAND_DST (0x3<<1) -#define DMAE_COMMAND_DST_SHIFT 1 -#define DMAE_COMMAND_C_DST (0x1<<3) -#define DMAE_COMMAND_C_DST_SHIFT 3 -#define DMAE_COMMAND_C_TYPE_ENABLE (0x1<<4) -#define DMAE_COMMAND_C_TYPE_ENABLE_SHIFT 4 -#define DMAE_COMMAND_C_TYPE_CRC_ENABLE (0x1<<5) -#define DMAE_COMMAND_C_TYPE_CRC_ENABLE_SHIFT 5 -#define DMAE_COMMAND_C_TYPE_CRC_OFFSET (0x7<<6) -#define DMAE_COMMAND_C_TYPE_CRC_OFFSET_SHIFT 6 -#define DMAE_COMMAND_ENDIANITY (0x3<<9) -#define DMAE_COMMAND_ENDIANITY_SHIFT 9 -#define DMAE_COMMAND_PORT (0x1<<11) -#define DMAE_COMMAND_PORT_SHIFT 11 -#define DMAE_COMMAND_CRC_RESET (0x1<<12) -#define DMAE_COMMAND_CRC_RESET_SHIFT 12 -#define DMAE_COMMAND_SRC_RESET (0x1<<13) -#define DMAE_COMMAND_SRC_RESET_SHIFT 13 -#define DMAE_COMMAND_DST_RESET (0x1<<14) -#define DMAE_COMMAND_DST_RESET_SHIFT 14 -#define DMAE_COMMAND_E1HVN (0x3<<15) -#define DMAE_COMMAND_E1HVN_SHIFT 15 -#define DMAE_COMMAND_DST_VN (0x3<<17) -#define DMAE_COMMAND_DST_VN_SHIFT 17 -#define DMAE_COMMAND_C_FUNC (0x1<<19) -#define DMAE_COMMAND_C_FUNC_SHIFT 19 -#define DMAE_COMMAND_ERR_POLICY (0x3<<20) -#define DMAE_COMMAND_ERR_POLICY_SHIFT 20 -#define DMAE_COMMAND_RESERVED0 (0x3FF<<22) -#define DMAE_COMMAND_RESERVED0_SHIFT 22 - u32 src_addr_lo; - u32 src_addr_hi; - u32 dst_addr_lo; - u32 dst_addr_hi; -#if defined(__BIG_ENDIAN) - u16 reserved1; - u16 len; -#elif defined(__LITTLE_ENDIAN) - u16 len; - u16 reserved1; -#endif - u32 comp_addr_lo; - u32 comp_addr_hi; - u32 comp_val; - u32 crc32; - u32 crc32_c; -#if defined(__BIG_ENDIAN) - u16 crc16_c; - u16 crc16; -#elif defined(__LITTLE_ENDIAN) - u16 crc16; - u16 crc16_c; -#endif -#if defined(__BIG_ENDIAN) - u16 reserved3; - u16 crc_t10; -#elif defined(__LITTLE_ENDIAN) - u16 crc_t10; - u16 reserved3; -#endif -#if defined(__BIG_ENDIAN) - u16 xsum8; - u16 xsum16; -#elif defined(__LITTLE_ENDIAN) - u16 xsum16; - u16 xsum8; -#endif +enum prs_flags_eth_addr_type { + PRS_FLAG_ETHTYPE_NON_UNICAST, + PRS_FLAG_ETHTYPE_UNICAST, + MAX_PRS_FLAGS_ETH_ADDR_TYPE }; -struct double_regpair { - u32 regpair0_lo; - u32 regpair0_hi; - u32 regpair1_lo; - u32 regpair1_hi; +/* + * Parsing flags for over-ethernet protocol + */ +enum prs_flags_over_eth { + PRS_FLAG_OVERETH_UNKNOWN, + PRS_FLAG_OVERETH_IPV4, + PRS_FLAG_OVERETH_IPV6, + PRS_FLAG_OVERETH_LLCSNAP_UNKNOWN, + MAX_PRS_FLAGS_OVER_ETH +}; + + +/* + * Parsing flags for over-IP protocol + */ +enum prs_flags_over_ip { + PRS_FLAG_OVERIP_UNKNOWN, + PRS_FLAG_OVERIP_TCP, + PRS_FLAG_OVERIP_UDP, + MAX_PRS_FLAGS_OVER_IP }; @@ -2313,38 +2994,50 @@ struct sdm_op_gen { #define SDM_OP_GEN_RESERVED_SHIFT 17 }; -/* - * The eth Rx Buffer Descriptor - */ -struct eth_rx_bd { - __le32 addr_lo; - __le32 addr_hi; -}; /* - * The eth Rx SGE Descriptor + * Timers connection context */ -struct eth_rx_sge { - __le32 addr_lo; - __le32 addr_hi; +struct timers_block_context { + u32 __reserved_0; + u32 __reserved_1; + u32 __reserved_2; + u32 flags; +#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0) +#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0 +#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2) +#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2 +#define __TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3) +#define __TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3 }; - /* - * The eth storm context of Ustorm + * The eth aggregative context of Tstorm */ -struct ustorm_eth_st_context { - u32 reserved0[48]; +struct tstorm_eth_ag_context { + u32 __reserved0[14]; }; + /* - * The eth storm context of Tstorm + * The eth aggregative context of Ustorm */ -struct tstorm_eth_st_context { - u32 __reserved0[28]; +struct ustorm_eth_ag_context { + u32 __reserved0; +#if defined(__BIG_ENDIAN) + u8 cdu_usage; + u8 __reserved2; + u16 __reserved1; +#elif defined(__LITTLE_ENDIAN) + u16 __reserved1; + u8 __reserved2; + u8 cdu_usage; +#endif + u32 __reserved3[6]; }; + /* * The eth aggregative context of Xstorm */ @@ -2362,343 +3055,373 @@ struct xstorm_eth_ag_context { u32 reserved3[30]; }; -/* - * The eth aggregative context of Tstorm - */ -struct tstorm_eth_ag_context { - u32 __reserved0[14]; -}; - /* - * The eth aggregative context of Cstorm + * doorbell message sent to the chip */ -struct cstorm_eth_ag_context { - u32 __reserved0[10]; +struct doorbell { +#if defined(__BIG_ENDIAN) + u16 zero_fill2; + u8 zero_fill1; + struct doorbell_hdr header; +#elif defined(__LITTLE_ENDIAN) + struct doorbell_hdr header; + u8 zero_fill1; + u16 zero_fill2; +#endif }; /* - * The eth aggregative context of Ustorm + * doorbell message sent to the chip */ -struct ustorm_eth_ag_context { - u32 __reserved0; +struct doorbell_set_prod { #if defined(__BIG_ENDIAN) - u8 cdu_usage; - u8 __reserved2; - u16 __reserved1; + u16 prod; + u8 zero_fill1; + struct doorbell_hdr header; #elif defined(__LITTLE_ENDIAN) - u16 __reserved1; - u8 __reserved2; - u8 cdu_usage; + struct doorbell_hdr header; + u8 zero_fill1; + u16 prod; #endif - u32 __reserved3[6]; }; + +struct regpair { + __le32 lo; + __le32 hi; +}; + + /* - * Timers connection context + * Classify rule opcodes in E2/E3 */ -struct timers_block_context { - u32 __reserved_0; - u32 __reserved_1; - u32 __reserved_2; - u32 flags; -#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0) -#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0 -#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2) -#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2 -#define __TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3) -#define __TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3 +enum classify_rule { + CLASSIFY_RULE_OPCODE_MAC, + CLASSIFY_RULE_OPCODE_VLAN, + CLASSIFY_RULE_OPCODE_PAIR, + MAX_CLASSIFY_RULE }; + /* - * structure for easy accessibility to assembler + * Classify rule types in E2/E3 */ -struct eth_tx_bd_flags { - u8 as_bitfield; -#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<0) -#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 0 -#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<1) -#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 1 -#define ETH_TX_BD_FLAGS_VLAN_MODE (0x3<<2) -#define ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT 2 -#define ETH_TX_BD_FLAGS_START_BD (0x1<<4) -#define ETH_TX_BD_FLAGS_START_BD_SHIFT 4 -#define ETH_TX_BD_FLAGS_IS_UDP (0x1<<5) -#define ETH_TX_BD_FLAGS_IS_UDP_SHIFT 5 -#define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6) -#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6 -#define ETH_TX_BD_FLAGS_IPV6 (0x1<<7) -#define ETH_TX_BD_FLAGS_IPV6_SHIFT 7 +enum classify_rule_action_type { + CLASSIFY_RULE_REMOVE, + CLASSIFY_RULE_ADD, + MAX_CLASSIFY_RULE_ACTION_TYPE }; + /* - * The eth Tx Buffer Descriptor + * client init ramrod data */ -struct eth_tx_start_bd { - __le32 addr_lo; - __le32 addr_hi; - __le16 nbd; - __le16 nbytes; - __le16 vlan_or_ethertype; - struct eth_tx_bd_flags bd_flags; - u8 general_data; -#define ETH_TX_START_BD_HDR_NBDS (0x3F<<0) -#define ETH_TX_START_BD_HDR_NBDS_SHIFT 0 -#define ETH_TX_START_BD_ETH_ADDR_TYPE (0x3<<6) -#define ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT 6 +struct client_init_general_data { + u8 client_id; + u8 statistics_counter_id; + u8 statistics_en_flg; + u8 is_fcoe_flg; + u8 activate_flg; + u8 sp_client_id; + __le16 mtu; + u8 statistics_zero_flg; + u8 func_id; + u8 cos; + u8 traffic_type; + u32 reserved0; }; + /* - * Tx regular BD structure + * client init rx data */ -struct eth_tx_bd { - __le32 addr_lo; - __le32 addr_hi; - __le16 total_pkt_bytes; - __le16 nbytes; - u8 reserved[4]; +struct client_init_rx_data { + u8 tpa_en; +#define CLIENT_INIT_RX_DATA_TPA_EN_IPV4 (0x1<<0) +#define CLIENT_INIT_RX_DATA_TPA_EN_IPV4_SHIFT 0 +#define CLIENT_INIT_RX_DATA_TPA_EN_IPV6 (0x1<<1) +#define CLIENT_INIT_RX_DATA_TPA_EN_IPV6_SHIFT 1 +#define CLIENT_INIT_RX_DATA_RESERVED5 (0x3F<<2) +#define CLIENT_INIT_RX_DATA_RESERVED5_SHIFT 2 + u8 vmqueue_mode_en_flg; + u8 extra_data_over_sgl_en_flg; + u8 cache_line_alignment_log_size; + u8 enable_dynamic_hc; + u8 max_sges_for_packet; + u8 client_qzone_id; + u8 drop_ip_cs_err_flg; + u8 drop_tcp_cs_err_flg; + u8 drop_ttl0_flg; + u8 drop_udp_cs_err_flg; + u8 inner_vlan_removal_enable_flg; + u8 outer_vlan_removal_enable_flg; + u8 status_block_id; + u8 rx_sb_index_number; + u8 reserved0; + u8 max_tpa_queues; + u8 silent_vlan_removal_flg; + __le16 max_bytes_on_bd; + __le16 sge_buff_size; + u8 approx_mcast_engine_id; + u8 rss_engine_id; + struct regpair bd_page_base; + struct regpair sge_page_base; + struct regpair cqe_page_base; + u8 is_leading_rss; + u8 is_approx_mcast; + __le16 max_agg_size; + __le16 state; +#define CLIENT_INIT_RX_DATA_UCAST_DROP_ALL (0x1<<0) +#define CLIENT_INIT_RX_DATA_UCAST_DROP_ALL_SHIFT 0 +#define CLIENT_INIT_RX_DATA_UCAST_ACCEPT_ALL (0x1<<1) +#define CLIENT_INIT_RX_DATA_UCAST_ACCEPT_ALL_SHIFT 1 +#define CLIENT_INIT_RX_DATA_UCAST_ACCEPT_UNMATCHED (0x1<<2) +#define CLIENT_INIT_RX_DATA_UCAST_ACCEPT_UNMATCHED_SHIFT 2 +#define CLIENT_INIT_RX_DATA_MCAST_DROP_ALL (0x1<<3) +#define CLIENT_INIT_RX_DATA_MCAST_DROP_ALL_SHIFT 3 +#define CLIENT_INIT_RX_DATA_MCAST_ACCEPT_ALL (0x1<<4) +#define CLIENT_INIT_RX_DATA_MCAST_ACCEPT_ALL_SHIFT 4 +#define CLIENT_INIT_RX_DATA_BCAST_ACCEPT_ALL (0x1<<5) +#define CLIENT_INIT_RX_DATA_BCAST_ACCEPT_ALL_SHIFT 5 +#define CLIENT_INIT_RX_DATA_ACCEPT_ANY_VLAN (0x1<<6) +#define CLIENT_INIT_RX_DATA_ACCEPT_ANY_VLAN_SHIFT 6 +#define CLIENT_INIT_RX_DATA_RESERVED2 (0x1FF<<7) +#define CLIENT_INIT_RX_DATA_RESERVED2_SHIFT 7 + __le16 cqe_pause_thr_low; + __le16 cqe_pause_thr_high; + __le16 bd_pause_thr_low; + __le16 bd_pause_thr_high; + __le16 sge_pause_thr_low; + __le16 sge_pause_thr_high; + __le16 rx_cos_mask; + __le16 silent_vlan_value; + __le16 silent_vlan_mask; + __le32 reserved6[2]; }; /* - * Tx parsing BD structure for ETH E1/E1h + * client init tx data */ -struct eth_tx_parse_bd_e1x { - u8 global_data; -#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W (0xF<<0) -#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W_SHIFT 0 -#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x1<<4) -#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 4 -#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<5) -#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 -#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<6) -#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 6 -#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 7 - u8 tcp_flags; -#define ETH_TX_PARSE_BD_E1X_FIN_FLG (0x1<<0) -#define ETH_TX_PARSE_BD_E1X_FIN_FLG_SHIFT 0 -#define ETH_TX_PARSE_BD_E1X_SYN_FLG (0x1<<1) -#define ETH_TX_PARSE_BD_E1X_SYN_FLG_SHIFT 1 -#define ETH_TX_PARSE_BD_E1X_RST_FLG (0x1<<2) -#define ETH_TX_PARSE_BD_E1X_RST_FLG_SHIFT 2 -#define ETH_TX_PARSE_BD_E1X_PSH_FLG (0x1<<3) -#define ETH_TX_PARSE_BD_E1X_PSH_FLG_SHIFT 3 -#define ETH_TX_PARSE_BD_E1X_ACK_FLG (0x1<<4) -#define ETH_TX_PARSE_BD_E1X_ACK_FLG_SHIFT 4 -#define ETH_TX_PARSE_BD_E1X_URG_FLG (0x1<<5) -#define ETH_TX_PARSE_BD_E1X_URG_FLG_SHIFT 5 -#define ETH_TX_PARSE_BD_E1X_ECE_FLG (0x1<<6) -#define ETH_TX_PARSE_BD_E1X_ECE_FLG_SHIFT 6 -#define ETH_TX_PARSE_BD_E1X_CWR_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_E1X_CWR_FLG_SHIFT 7 - u8 ip_hlen_w; - s8 reserved; - __le16 total_hlen_w; - __le16 tcp_pseudo_csum; - __le16 lso_mss; - __le16 ip_id; - __le32 tcp_send_seq; +struct client_init_tx_data { + u8 enforce_security_flg; + u8 tx_status_block_id; + u8 tx_sb_index_number; + u8 tss_leading_client_id; + u8 tx_switching_flg; + u8 anti_spoofing_flg; + __le16 default_vlan; + struct regpair tx_bd_page_base; + __le16 state; +#define CLIENT_INIT_TX_DATA_UCAST_ACCEPT_ALL (0x1<<0) +#define CLIENT_INIT_TX_DATA_UCAST_ACCEPT_ALL_SHIFT 0 +#define CLIENT_INIT_TX_DATA_MCAST_ACCEPT_ALL (0x1<<1) +#define CLIENT_INIT_TX_DATA_MCAST_ACCEPT_ALL_SHIFT 1 +#define CLIENT_INIT_TX_DATA_BCAST_ACCEPT_ALL (0x1<<2) +#define CLIENT_INIT_TX_DATA_BCAST_ACCEPT_ALL_SHIFT 2 +#define CLIENT_INIT_TX_DATA_ACCEPT_ANY_VLAN (0x1<<3) +#define CLIENT_INIT_TX_DATA_ACCEPT_ANY_VLAN_SHIFT 3 +#define CLIENT_INIT_TX_DATA_RESERVED1 (0xFFF<<4) +#define CLIENT_INIT_TX_DATA_RESERVED1_SHIFT 4 + u8 default_vlan_flg; + u8 reserved2; + __le32 reserved3; }; /* - * Tx parsing BD structure for ETH E2 + * client init ramrod data */ -struct eth_tx_parse_bd_e2 { - __le16 dst_mac_addr_lo; - __le16 dst_mac_addr_mid; - __le16 dst_mac_addr_hi; - __le16 src_mac_addr_lo; - __le16 src_mac_addr_mid; - __le16 src_mac_addr_hi; - __le32 parsing_data; -#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x1FFF<<0) -#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0 -#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<13) -#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 13 -#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<17) -#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 17 -#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<31) -#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 31 +struct client_init_ramrod_data { + struct client_init_general_data general; + struct client_init_rx_data rx; + struct client_init_tx_data tx; }; + /* - * The last BD in the BD memory will hold a pointer to the next BD memory + * client update ramrod data */ -struct eth_tx_next_bd { - __le32 addr_lo; - __le32 addr_hi; - u8 reserved[8]; +struct client_update_ramrod_data { + u8 client_id; + u8 func_id; + u8 inner_vlan_removal_enable_flg; + u8 inner_vlan_removal_change_flg; + u8 outer_vlan_removal_enable_flg; + u8 outer_vlan_removal_change_flg; + u8 anti_spoofing_enable_flg; + u8 anti_spoofing_change_flg; + u8 activate_flg; + u8 activate_change_flg; + __le16 default_vlan; + u8 default_vlan_enable_flg; + u8 default_vlan_change_flg; + __le16 silent_vlan_value; + __le16 silent_vlan_mask; + u8 silent_vlan_removal_flg; + u8 silent_vlan_change_flg; + __le32 echo; }; + /* - * union for 4 Bd types + * The eth storm context of Cstorm */ -union eth_tx_bd_types { - struct eth_tx_start_bd start_bd; - struct eth_tx_bd reg_bd; - struct eth_tx_parse_bd_e1x parse_bd_e1x; - struct eth_tx_parse_bd_e2 parse_bd_e2; - struct eth_tx_next_bd next_bd; +struct cstorm_eth_st_context { + u32 __reserved0[4]; +}; + + +struct double_regpair { + u32 regpair0_lo; + u32 regpair0_hi; + u32 regpair1_lo; + u32 regpair1_hi; }; /* - * The eth storm context of Xstorm + * Ethernet address typesm used in ethernet tx BDs */ -struct xstorm_eth_st_context { - u32 reserved0[60]; +enum eth_addr_type { + UNKNOWN_ADDRESS, + UNICAST_ADDRESS, + MULTICAST_ADDRESS, + BROADCAST_ADDRESS, + MAX_ETH_ADDR_TYPE }; + /* - * The eth storm context of Cstorm + * */ -struct cstorm_eth_st_context { - u32 __reserved0[4]; +struct eth_classify_cmd_header { + u8 cmd_general_data; +#define ETH_CLASSIFY_CMD_HEADER_RX_CMD (0x1<<0) +#define ETH_CLASSIFY_CMD_HEADER_RX_CMD_SHIFT 0 +#define ETH_CLASSIFY_CMD_HEADER_TX_CMD (0x1<<1) +#define ETH_CLASSIFY_CMD_HEADER_TX_CMD_SHIFT 1 +#define ETH_CLASSIFY_CMD_HEADER_OPCODE (0x3<<2) +#define ETH_CLASSIFY_CMD_HEADER_OPCODE_SHIFT 2 +#define ETH_CLASSIFY_CMD_HEADER_IS_ADD (0x1<<4) +#define ETH_CLASSIFY_CMD_HEADER_IS_ADD_SHIFT 4 +#define ETH_CLASSIFY_CMD_HEADER_RESERVED0 (0x7<<5) +#define ETH_CLASSIFY_CMD_HEADER_RESERVED0_SHIFT 5 + u8 func_id; + u8 client_id; + u8 reserved1; }; + /* - * Ethernet connection context + * header for eth classification config ramrod */ -struct eth_context { - struct ustorm_eth_st_context ustorm_st_context; - struct tstorm_eth_st_context tstorm_st_context; - struct xstorm_eth_ag_context xstorm_ag_context; - struct tstorm_eth_ag_context tstorm_ag_context; - struct cstorm_eth_ag_context cstorm_ag_context; - struct ustorm_eth_ag_context ustorm_ag_context; - struct timers_block_context timers_context; - struct xstorm_eth_st_context xstorm_st_context; - struct cstorm_eth_st_context cstorm_st_context; +struct eth_classify_header { + u8 rule_cnt; + u8 reserved0; + __le16 reserved1; + __le32 echo; }; /* - * Ethernet doorbell + * Command for adding/removing a MAC classification rule */ -struct eth_tx_doorbell { -#if defined(__BIG_ENDIAN) - u16 npackets; - u8 params; -#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0) -#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0 -#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6) -#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6 -#define ETH_TX_DOORBELL_SPARE (0x1<<7) -#define ETH_TX_DOORBELL_SPARE_SHIFT 7 - struct doorbell_hdr hdr; -#elif defined(__LITTLE_ENDIAN) - struct doorbell_hdr hdr; - u8 params; -#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0) -#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0 -#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6) -#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6 -#define ETH_TX_DOORBELL_SPARE (0x1<<7) -#define ETH_TX_DOORBELL_SPARE_SHIFT 7 - u16 npackets; -#endif +struct eth_classify_mac_cmd { + struct eth_classify_cmd_header header; + __le32 reserved0; + __le16 mac_lsb; + __le16 mac_mid; + __le16 mac_msb; + __le16 reserved1; +}; + + +/* + * Command for adding/removing a MAC-VLAN pair classification rule + */ +struct eth_classify_pair_cmd { + struct eth_classify_cmd_header header; + __le32 reserved0; + __le16 mac_lsb; + __le16 mac_mid; + __le16 mac_msb; + __le16 vlan; +}; + + +/* + * Command for adding/removing a VLAN classification rule + */ +struct eth_classify_vlan_cmd { + struct eth_classify_cmd_header header; + __le32 reserved0; + __le32 reserved1; + __le16 reserved2; + __le16 vlan; }; +/* + * union for eth classification rule + */ +union eth_classify_rule_cmd { + struct eth_classify_mac_cmd mac; + struct eth_classify_vlan_cmd vlan; + struct eth_classify_pair_cmd pair; +}; /* - * client init fc data + * parameters for eth classification configuration ramrod */ -struct client_init_fc_data { - __le16 cqe_pause_thr_low; - __le16 cqe_pause_thr_high; - __le16 bd_pause_thr_low; - __le16 bd_pause_thr_high; - __le16 sge_pause_thr_low; - __le16 sge_pause_thr_high; - __le16 rx_cos_mask; - u8 safc_group_num; - u8 safc_group_en_flg; - u8 traffic_type; - u8 reserved0; - __le16 reserved1; - __le32 reserved2; +struct eth_classify_rules_ramrod_data { + struct eth_classify_header header; + union eth_classify_rule_cmd rules[CLASSIFY_RULES_COUNT]; }; /* - * client init ramrod data + * The data contain client ID need to the ramrod */ -struct client_init_general_data { - u8 client_id; - u8 statistics_counter_id; - u8 statistics_en_flg; - u8 is_fcoe_flg; - u8 activate_flg; - u8 sp_client_id; - __le16 reserved0; - __le32 reserved1[2]; +struct eth_common_ramrod_data { + __le32 client_id; + __le32 reserved1; }; /* - * client init rx data + * The eth storm context of Ustorm */ -struct client_init_rx_data { - u8 tpa_en_flg; - u8 vmqueue_mode_en_flg; - u8 extra_data_over_sgl_en_flg; - u8 cache_line_alignment_log_size; - u8 enable_dynamic_hc; - u8 max_sges_for_packet; - u8 client_qzone_id; - u8 drop_ip_cs_err_flg; - u8 drop_tcp_cs_err_flg; - u8 drop_ttl0_flg; - u8 drop_udp_cs_err_flg; - u8 inner_vlan_removal_enable_flg; - u8 outer_vlan_removal_enable_flg; - u8 status_block_id; - u8 rx_sb_index_number; - u8 reserved0[3]; - __le16 bd_buff_size; - __le16 sge_buff_size; - __le16 mtu; - struct regpair bd_page_base; - struct regpair sge_page_base; - struct regpair cqe_page_base; - u8 is_leading_rss; - u8 is_approx_mcast; - __le16 max_agg_size; - __le32 reserved2[3]; +struct ustorm_eth_st_context { + u32 reserved0[52]; }; /* - * client init tx data + * The eth storm context of Tstorm */ -struct client_init_tx_data { - u8 enforce_security_flg; - u8 tx_status_block_id; - u8 tx_sb_index_number; - u8 reserved0; - __le16 mtu; - __le16 reserved1; - struct regpair tx_bd_page_base; - __le32 reserved2[2]; +struct tstorm_eth_st_context { + u32 __reserved0[28]; }; /* - * client init ramrod data + * The eth storm context of Xstorm */ -struct client_init_ramrod_data { - struct client_init_general_data general; - struct client_init_rx_data rx; - struct client_init_tx_data tx; - struct client_init_fc_data fc; +struct xstorm_eth_st_context { + u32 reserved0[60]; }; - /* - * The data contain client ID need to the ramrod + * Ethernet connection context */ -struct eth_common_ramrod_data { - u32 client_id; - u32 reserved1; +struct eth_context { + struct ustorm_eth_st_context ustorm_st_context; + struct tstorm_eth_st_context tstorm_st_context; + struct xstorm_eth_ag_context xstorm_ag_context; + struct tstorm_eth_ag_context tstorm_ag_context; + struct cstorm_eth_ag_context cstorm_ag_context; + struct ustorm_eth_ag_context ustorm_ag_context; + struct timers_block_context timers_context; + struct xstorm_eth_st_context xstorm_st_context; + struct cstorm_eth_st_context cstorm_st_context; }; @@ -2710,25 +3433,48 @@ union eth_sgl_or_raw_data { u32 raw_data[4]; }; +/* + * eth FP end aggregation CQE parameters struct + */ +struct eth_end_agg_rx_cqe { + u8 type_error_flags; +#define ETH_END_AGG_RX_CQE_TYPE (0x3<<0) +#define ETH_END_AGG_RX_CQE_TYPE_SHIFT 0 +#define ETH_END_AGG_RX_CQE_SGL_RAW_SEL (0x1<<2) +#define ETH_END_AGG_RX_CQE_SGL_RAW_SEL_SHIFT 2 +#define ETH_END_AGG_RX_CQE_RESERVED0 (0x1F<<3) +#define ETH_END_AGG_RX_CQE_RESERVED0_SHIFT 3 + u8 reserved1; + u8 queue_index; + u8 reserved2; + __le32 timestamp_delta; + __le16 num_of_coalesced_segs; + __le16 pkt_len; + u8 pure_ack_count; + u8 reserved3; + __le16 reserved4; + union eth_sgl_or_raw_data sgl_or_raw_data; + __le32 reserved5[8]; +}; + + /* * regular eth FP CQE parameters struct */ struct eth_fast_path_rx_cqe { u8 type_error_flags; -#define ETH_FAST_PATH_RX_CQE_TYPE (0x1<<0) +#define ETH_FAST_PATH_RX_CQE_TYPE (0x3<<0) #define ETH_FAST_PATH_RX_CQE_TYPE_SHIFT 0 -#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<1) -#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 1 -#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<2) -#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 2 -#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<3) -#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 3 -#define ETH_FAST_PATH_RX_CQE_START_FLG (0x1<<4) -#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4 -#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5) -#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5 -#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL (0x3<<6) -#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL_SHIFT 6 +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL (0x1<<2) +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL_SHIFT 2 +#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<3) +#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 3 +#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<4) +#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 4 +#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<5) +#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 5 +#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6) +#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6 u8 status_flags; #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 @@ -2742,39 +3488,108 @@ struct eth_fast_path_rx_cqe { #define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG_SHIFT 6 #define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG (0x1<<7) #define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7 - u8 placement_offset; u8 queue_index; + u8 placement_offset; __le32 rss_hash_result; __le16 vlan_tag; __le16 pkt_len; __le16 len_on_bd; struct parsing_flags pars_flags; union eth_sgl_or_raw_data sgl_or_raw_data; + __le32 reserved1[8]; +}; + + +/* + * Command for setting classification flags for a client + */ +struct eth_filter_rules_cmd { + u8 cmd_general_data; +#define ETH_FILTER_RULES_CMD_RX_CMD (0x1<<0) +#define ETH_FILTER_RULES_CMD_RX_CMD_SHIFT 0 +#define ETH_FILTER_RULES_CMD_TX_CMD (0x1<<1) +#define ETH_FILTER_RULES_CMD_TX_CMD_SHIFT 1 +#define ETH_FILTER_RULES_CMD_RESERVED0 (0x3F<<2) +#define ETH_FILTER_RULES_CMD_RESERVED0_SHIFT 2 + u8 func_id; + u8 client_id; + u8 reserved1; + __le16 state; +#define ETH_FILTER_RULES_CMD_UCAST_DROP_ALL (0x1<<0) +#define ETH_FILTER_RULES_CMD_UCAST_DROP_ALL_SHIFT 0 +#define ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL (0x1<<1) +#define ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL_SHIFT 1 +#define ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED (0x1<<2) +#define ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED_SHIFT 2 +#define ETH_FILTER_RULES_CMD_MCAST_DROP_ALL (0x1<<3) +#define ETH_FILTER_RULES_CMD_MCAST_DROP_ALL_SHIFT 3 +#define ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL (0x1<<4) +#define ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL_SHIFT 4 +#define ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL (0x1<<5) +#define ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL_SHIFT 5 +#define ETH_FILTER_RULES_CMD_ACCEPT_ANY_VLAN (0x1<<6) +#define ETH_FILTER_RULES_CMD_ACCEPT_ANY_VLAN_SHIFT 6 +#define ETH_FILTER_RULES_CMD_RESERVED2 (0x1FF<<7) +#define ETH_FILTER_RULES_CMD_RESERVED2_SHIFT 7 + __le16 reserved3; + struct regpair reserved4; +}; + + +/* + * parameters for eth classification filters ramrod + */ +struct eth_filter_rules_ramrod_data { + struct eth_classify_header header; + struct eth_filter_rules_cmd rules[FILTER_RULES_COUNT]; +}; + + +/* + * parameters for eth classification configuration ramrod + */ +struct eth_general_rules_ramrod_data { + struct eth_classify_header header; + union eth_classify_rule_cmd rules[CLASSIFY_RULES_COUNT]; }; /* - * The data for RSS setup ramrod + * The data for Halt ramrod */ struct eth_halt_ramrod_data { - u32 client_id; - u32 reserved0; + __le32 client_id; + __le32 reserved0; }; + /* - * The data for statistics query ramrod + * Command for setting multicast classification for a client */ -struct common_query_ramrod_data { -#if defined(__BIG_ENDIAN) - u8 reserved0; - u8 collect_port; - u16 drv_counter; -#elif defined(__LITTLE_ENDIAN) - u16 drv_counter; - u8 collect_port; - u8 reserved0; -#endif - u32 ctr_id_vector; +struct eth_multicast_rules_cmd { + u8 cmd_general_data; +#define ETH_MULTICAST_RULES_CMD_RX_CMD (0x1<<0) +#define ETH_MULTICAST_RULES_CMD_RX_CMD_SHIFT 0 +#define ETH_MULTICAST_RULES_CMD_TX_CMD (0x1<<1) +#define ETH_MULTICAST_RULES_CMD_TX_CMD_SHIFT 1 +#define ETH_MULTICAST_RULES_CMD_IS_ADD (0x1<<2) +#define ETH_MULTICAST_RULES_CMD_IS_ADD_SHIFT 2 +#define ETH_MULTICAST_RULES_CMD_RESERVED0 (0x1F<<3) +#define ETH_MULTICAST_RULES_CMD_RESERVED0_SHIFT 3 + u8 func_id; + u8 bin_id; + u8 engine_id; + __le32 reserved2; + struct regpair reserved3; +}; + + +/* + * parameters for multicast classification ramrod + */ +struct eth_multicast_rules_ramrod_data { + struct eth_classify_header header; + struct eth_multicast_rules_cmd rules[MULTICAST_RULES_COUNT]; }; @@ -2794,17 +3609,87 @@ union eth_ramrod_data { }; +/* + * RSS toeplitz hash type, as reported in CQE + */ +enum eth_rss_hash_type { + DEFAULT_HASH_TYPE, + IPV4_HASH_TYPE, + TCP_IPV4_HASH_TYPE, + IPV6_HASH_TYPE, + TCP_IPV6_HASH_TYPE, + VLAN_PRI_HASH_TYPE, + E1HOV_PRI_HASH_TYPE, + DSCP_HASH_TYPE, + MAX_ETH_RSS_HASH_TYPE +}; + + +/* + * Ethernet RSS mode + */ +enum eth_rss_mode { + ETH_RSS_MODE_DISABLED, + ETH_RSS_MODE_REGULAR, + ETH_RSS_MODE_VLAN_PRI, + ETH_RSS_MODE_E1HOV_PRI, + ETH_RSS_MODE_IP_DSCP, + MAX_ETH_RSS_MODE +}; + + +/* + * parameters for RSS update ramrod (E2) + */ +struct eth_rss_update_ramrod_data { + u8 rss_engine_id; + u8 capabilities; +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV4_CAPABILITY (0x1<<0) +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV4_CAPABILITY_SHIFT 0 +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV4_TCP_CAPABILITY (0x1<<1) +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV4_TCP_CAPABILITY_SHIFT 1 +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV4_UDP_CAPABILITY (0x1<<2) +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV4_UDP_CAPABILITY_SHIFT 2 +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_CAPABILITY (0x1<<3) +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_CAPABILITY_SHIFT 3 +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY (0x1<<4) +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY_SHIFT 4 +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY (0x1<<5) +#define ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY_SHIFT 5 +#define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY (0x1<<6) +#define ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY_SHIFT 6 +#define __ETH_RSS_UPDATE_RAMROD_DATA_RESERVED0 (0x1<<7) +#define __ETH_RSS_UPDATE_RAMROD_DATA_RESERVED0_SHIFT 7 + u8 rss_result_mask; + u8 rss_mode; + __le32 __reserved2; + u8 indirection_table[T_ETH_INDIRECTION_TABLE_SIZE]; + __le32 rss_key[T_ETH_RSS_KEY]; + __le32 echo; + __le32 reserved3; +}; + + +/* + * The eth Rx Buffer Descriptor + */ +struct eth_rx_bd { + __le32 addr_lo; + __le32 addr_hi; +}; + + /* * Eth Rx Cqe structure- general structure for ramrods */ struct common_ramrod_eth_rx_cqe { u8 ramrod_type; -#define COMMON_RAMROD_ETH_RX_CQE_TYPE (0x1<<0) +#define COMMON_RAMROD_ETH_RX_CQE_TYPE (0x3<<0) #define COMMON_RAMROD_ETH_RX_CQE_TYPE_SHIFT 0 -#define COMMON_RAMROD_ETH_RX_CQE_ERROR (0x1<<1) -#define COMMON_RAMROD_ETH_RX_CQE_ERROR_SHIFT 1 -#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x3F<<2) -#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 2 +#define COMMON_RAMROD_ETH_RX_CQE_ERROR (0x1<<2) +#define COMMON_RAMROD_ETH_RX_CQE_ERROR_SHIFT 2 +#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x1F<<3) +#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 3 u8 conn_type; __le16 reserved1; __le32 conn_and_cmd_data; @@ -2813,65 +3698,271 @@ struct common_ramrod_eth_rx_cqe { #define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24) #define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24 struct ramrod_data protocol_data; - __le32 reserved2[4]; + __le32 echo; + __le32 reserved2[11]; +}; + +/* + * Rx Last CQE in page (in ETH) + */ +struct eth_rx_cqe_next_page { + __le32 addr_lo; + __le32 addr_hi; + __le32 reserved[14]; +}; + +/* + * union for all eth rx cqe types (fix their sizes) + */ +union eth_rx_cqe { + struct eth_fast_path_rx_cqe fast_path_cqe; + struct common_ramrod_eth_rx_cqe ramrod_cqe; + struct eth_rx_cqe_next_page next_page_cqe; + struct eth_end_agg_rx_cqe end_agg_cqe; +}; + + +/* + * Values for RX ETH CQE type field + */ +enum eth_rx_cqe_type { + RX_ETH_CQE_TYPE_ETH_FASTPATH, + RX_ETH_CQE_TYPE_ETH_RAMROD, + RX_ETH_CQE_TYPE_ETH_START_AGG, + RX_ETH_CQE_TYPE_ETH_STOP_AGG, + MAX_ETH_RX_CQE_TYPE +}; + + +/* + * Type of SGL/Raw field in ETH RX fast path CQE + */ +enum eth_rx_fp_sel { + ETH_FP_CQE_REGULAR, + ETH_FP_CQE_RAW, + MAX_ETH_RX_FP_SEL +}; + + +/* + * The eth Rx SGE Descriptor + */ +struct eth_rx_sge { + __le32 addr_lo; + __le32 addr_hi; +}; + + +/* + * common data for all protocols + */ +struct spe_hdr { + __le32 conn_and_cmd_data; +#define SPE_HDR_CID (0xFFFFFF<<0) +#define SPE_HDR_CID_SHIFT 0 +#define SPE_HDR_CMD_ID (0xFF<<24) +#define SPE_HDR_CMD_ID_SHIFT 24 + __le16 type; +#define SPE_HDR_CONN_TYPE (0xFF<<0) +#define SPE_HDR_CONN_TYPE_SHIFT 0 +#define SPE_HDR_FUNCTION_ID (0xFF<<8) +#define SPE_HDR_FUNCTION_ID_SHIFT 8 + __le16 reserved1; +}; + +/* + * specific data for ethernet slow path element + */ +union eth_specific_data { + u8 protocol_data[8]; + struct regpair client_update_ramrod_data; + struct regpair client_init_ramrod_init_data; + struct eth_halt_ramrod_data halt_ramrod_data; + struct regpair update_data_addr; + struct eth_common_ramrod_data common_ramrod_data; + struct regpair classify_cfg_addr; + struct regpair filter_cfg_addr; + struct regpair mcast_cfg_addr; +}; + +/* + * Ethernet slow path element + */ +struct eth_spe { + struct spe_hdr hdr; + union eth_specific_data data; +}; + + +/* + * Ethernet command ID for slow path elements + */ +enum eth_spqe_cmd_id { + RAMROD_CMD_ID_ETH_UNUSED, + RAMROD_CMD_ID_ETH_CLIENT_SETUP, + RAMROD_CMD_ID_ETH_HALT, + RAMROD_CMD_ID_ETH_FORWARD_SETUP, + RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP, + RAMROD_CMD_ID_ETH_CLIENT_UPDATE, + RAMROD_CMD_ID_ETH_EMPTY, + RAMROD_CMD_ID_ETH_TERMINATE, + RAMROD_CMD_ID_ETH_TPA_UPDATE, + RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES, + RAMROD_CMD_ID_ETH_FILTER_RULES, + RAMROD_CMD_ID_ETH_MULTICAST_RULES, + RAMROD_CMD_ID_ETH_RSS_UPDATE, + RAMROD_CMD_ID_ETH_SET_MAC, + MAX_ETH_SPQE_CMD_ID +}; + + +/* + * eth tpa update command + */ +enum eth_tpa_update_command { + TPA_UPDATE_NONE_COMMAND, + TPA_UPDATE_ENABLE_COMMAND, + TPA_UPDATE_DISABLE_COMMAND, + MAX_ETH_TPA_UPDATE_COMMAND +}; + + +/* + * Tx regular BD structure + */ +struct eth_tx_bd { + __le32 addr_lo; + __le32 addr_hi; + __le16 total_pkt_bytes; + __le16 nbytes; + u8 reserved[4]; +}; + + +/* + * structure for easy accessibility to assembler + */ +struct eth_tx_bd_flags { + u8 as_bitfield; +#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<0) +#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 0 +#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<1) +#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 1 +#define ETH_TX_BD_FLAGS_VLAN_MODE (0x3<<2) +#define ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT 2 +#define ETH_TX_BD_FLAGS_START_BD (0x1<<4) +#define ETH_TX_BD_FLAGS_START_BD_SHIFT 4 +#define ETH_TX_BD_FLAGS_IS_UDP (0x1<<5) +#define ETH_TX_BD_FLAGS_IS_UDP_SHIFT 5 +#define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6) +#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6 +#define ETH_TX_BD_FLAGS_IPV6 (0x1<<7) +#define ETH_TX_BD_FLAGS_IPV6_SHIFT 7 }; /* - * Rx Last CQE in page (in ETH) + * The eth Tx Buffer Descriptor */ -struct eth_rx_cqe_next_page { +struct eth_tx_start_bd { __le32 addr_lo; __le32 addr_hi; - __le32 reserved[6]; + __le16 nbd; + __le16 nbytes; + __le16 vlan_or_ethertype; + struct eth_tx_bd_flags bd_flags; + u8 general_data; +#define ETH_TX_START_BD_HDR_NBDS (0xF<<0) +#define ETH_TX_START_BD_HDR_NBDS_SHIFT 0 +#define ETH_TX_START_BD_FORCE_VLAN_MODE (0x1<<4) +#define ETH_TX_START_BD_FORCE_VLAN_MODE_SHIFT 4 +#define ETH_TX_START_BD_RESREVED (0x1<<5) +#define ETH_TX_START_BD_RESREVED_SHIFT 5 +#define ETH_TX_START_BD_ETH_ADDR_TYPE (0x3<<6) +#define ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT 6 }; /* - * union for all eth rx cqe types (fix their sizes) + * Tx parsing BD structure for ETH E1/E1h */ -union eth_rx_cqe { - struct eth_fast_path_rx_cqe fast_path_cqe; - struct common_ramrod_eth_rx_cqe ramrod_cqe; - struct eth_rx_cqe_next_page next_page_cqe; +struct eth_tx_parse_bd_e1x { + u8 global_data; +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W (0xF<<0) +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 7 + u8 tcp_flags; +#define ETH_TX_PARSE_BD_E1X_FIN_FLG (0x1<<0) +#define ETH_TX_PARSE_BD_E1X_FIN_FLG_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_SYN_FLG (0x1<<1) +#define ETH_TX_PARSE_BD_E1X_SYN_FLG_SHIFT 1 +#define ETH_TX_PARSE_BD_E1X_RST_FLG (0x1<<2) +#define ETH_TX_PARSE_BD_E1X_RST_FLG_SHIFT 2 +#define ETH_TX_PARSE_BD_E1X_PSH_FLG (0x1<<3) +#define ETH_TX_PARSE_BD_E1X_PSH_FLG_SHIFT 3 +#define ETH_TX_PARSE_BD_E1X_ACK_FLG (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_ACK_FLG_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_URG_FLG (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_URG_FLG_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_ECE_FLG (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_ECE_FLG_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_CWR_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_CWR_FLG_SHIFT 7 + u8 ip_hlen_w; + s8 reserved; + __le16 total_hlen_w; + __le16 tcp_pseudo_csum; + __le16 lso_mss; + __le16 ip_id; + __le32 tcp_send_seq; }; - /* - * common data for all protocols + * Tx parsing BD structure for ETH E2 */ -struct spe_hdr { - __le32 conn_and_cmd_data; -#define SPE_HDR_CID (0xFFFFFF<<0) -#define SPE_HDR_CID_SHIFT 0 -#define SPE_HDR_CMD_ID (0xFF<<24) -#define SPE_HDR_CMD_ID_SHIFT 24 - __le16 type; -#define SPE_HDR_CONN_TYPE (0xFF<<0) -#define SPE_HDR_CONN_TYPE_SHIFT 0 -#define SPE_HDR_FUNCTION_ID (0xFF<<8) -#define SPE_HDR_FUNCTION_ID_SHIFT 8 - __le16 reserved1; +struct eth_tx_parse_bd_e2 { + __le16 dst_mac_addr_lo; + __le16 dst_mac_addr_mid; + __le16 dst_mac_addr_hi; + __le16 src_mac_addr_lo; + __le16 src_mac_addr_mid; + __le16 src_mac_addr_hi; + __le32 parsing_data; +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x1FFF<<0) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<13) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 13 +#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<17) +#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 17 +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<31) +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 31 }; /* - * Ethernet slow path element + * The last BD in the BD memory will hold a pointer to the next BD memory */ -union eth_specific_data { - u8 protocol_data[8]; - struct regpair client_init_ramrod_init_data; - struct eth_halt_ramrod_data halt_ramrod_data; - struct regpair update_data_addr; - struct eth_common_ramrod_data common_ramrod_data; +struct eth_tx_next_bd { + __le32 addr_lo; + __le32 addr_hi; + u8 reserved[8]; }; /* - * Ethernet slow path element + * union for 4 Bd types */ -struct eth_spe { - struct spe_hdr hdr; - union eth_specific_data data; +union eth_tx_bd_types { + struct eth_tx_start_bd start_bd; + struct eth_tx_bd reg_bd; + struct eth_tx_parse_bd_e1x parse_bd_e1x; + struct eth_tx_parse_bd_e2 parse_bd_e2; + struct eth_tx_next_bd next_bd; }; - /* * array of 13 bds as appears in the eth xstorm context */ @@ -2881,86 +3972,25 @@ struct eth_tx_bds_array { /* - * Common configuration parameters per function in Tstorm + * VLAN mode on TX BDs */ -struct tstorm_eth_function_common_config { -#if defined(__BIG_ENDIAN) - u8 reserved1; - u8 rss_result_mask; - u16 config_flags; -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 -#elif defined(__LITTLE_ENDIAN) - u16 config_flags; -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 - u8 rss_result_mask; - u8 reserved1; -#endif - u16 vlan_id[2]; +enum eth_tx_vlan_type { + X_ETH_NO_VLAN, + X_ETH_OUTBAND_VLAN, + X_ETH_INBAND_VLAN, + X_ETH_FW_ADDED_VLAN, + MAX_ETH_TX_VLAN_TYPE }; -/* - * RSS idirection table update configuration - */ -struct rss_update_config { -#if defined(__BIG_ENDIAN) - u16 toe_rss_bitmap; - u16 flags; -#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE (0x1<<0) -#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE_SHIFT 0 -#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE (0x1<<1) -#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE_SHIFT 1 -#define __RSS_UPDATE_CONFIG_RESERVED0 (0x3FFF<<2) -#define __RSS_UPDATE_CONFIG_RESERVED0_SHIFT 2 -#elif defined(__LITTLE_ENDIAN) - u16 flags; -#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE (0x1<<0) -#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE_SHIFT 0 -#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE (0x1<<1) -#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE_SHIFT 1 -#define __RSS_UPDATE_CONFIG_RESERVED0 (0x3FFF<<2) -#define __RSS_UPDATE_CONFIG_RESERVED0_SHIFT 2 - u16 toe_rss_bitmap; -#endif - u32 reserved1; -}; /* - * parameters for eth update ramrod + * Ethernet VLAN filtering mode in E1x */ -struct eth_update_ramrod_data { - struct tstorm_eth_function_common_config func_config; - u8 indirectionTable[128]; - struct rss_update_config rss_config; +enum eth_vlan_filter_mode { + ETH_VLAN_FILTER_ANY_VLAN, + ETH_VLAN_FILTER_SPECIFIC_VLAN, + ETH_VLAN_FILTER_CLASSIFY, + MAX_ETH_VLAN_FILTER_MODE }; @@ -2970,9 +4000,8 @@ struct eth_update_ramrod_data { struct mac_configuration_hdr { u8 length; u8 offset; - u16 client_id; - u16 echo; - u16 reserved1; + __le16 client_id; + __le32 echo; }; /* @@ -2997,8 +4026,8 @@ struct mac_configuration_entry { #define MAC_CONFIGURATION_ENTRY_BROADCAST_SHIFT 5 #define MAC_CONFIGURATION_ENTRY_RESERVED1 (0x3<<6) #define MAC_CONFIGURATION_ENTRY_RESERVED1_SHIFT 6 - u16 reserved0; - u32 clients_bit_vector; + __le16 reserved0; + __le32 clients_bit_vector; }; /* @@ -3010,6 +4039,36 @@ struct mac_configuration_cmd { }; +/* + * Set-MAC command type (in E1x) + */ +enum set_mac_action_type { + T_ETH_MAC_COMMAND_INVALIDATE, + T_ETH_MAC_COMMAND_SET, + MAX_SET_MAC_ACTION_TYPE +}; + + +/* + * tpa update ramrod data + */ +struct tpa_update_ramrod_data { + u8 update_ipv4; + u8 update_ipv6; + u8 client_id; + u8 max_tpa_queues; + u8 max_sges_for_packet; + u8 complete_on_both_clients; + __le16 reserved1; + __le16 sge_buff_size; + __le16 max_agg_size; + __le32 sge_page_base_lo; + __le32 sge_page_base_hi; + __le16 sge_pause_thr_low; + __le16 sge_pause_thr_high; +}; + + /* * approximate-match multicast filtering for E1H per function in Tstorm */ @@ -3018,36 +4077,51 @@ struct tstorm_eth_approximate_match_multicast_filtering { }; +/* + * Common configuration parameters per function in Tstorm + */ +struct tstorm_eth_function_common_config { + __le16 config_flags; +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<7) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 7 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0xFF<<8) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 8 + u8 rss_result_mask; + u8 reserved1; + __le16 vlan_id[2]; +}; + + /* * MAC filtering configuration parameters per port in Tstorm */ struct tstorm_eth_mac_filter_config { - u32 ucast_drop_all; - u32 ucast_accept_all; - u32 mcast_drop_all; - u32 mcast_accept_all; - u32 bcast_drop_all; - u32 bcast_accept_all; - u32 vlan_filter[2]; - u32 unmatched_unicast; - u32 reserved; + __le32 ucast_drop_all; + __le32 ucast_accept_all; + __le32 mcast_drop_all; + __le32 mcast_accept_all; + __le32 bcast_accept_all; + __le32 vlan_filter[2]; + __le32 unmatched_unicast; }; /* - * common flag to indicate existence of TPA. + * tx only queue init ramrod data */ -struct tstorm_eth_tpa_exist { -#if defined(__BIG_ENDIAN) - u16 reserved1; - u8 reserved0; - u8 tpa_exist; -#elif defined(__LITTLE_ENDIAN) - u8 tpa_exist; - u8 reserved0; - u16 reserved1; -#endif - u32 reserved2; +struct tx_queue_init_ramrod_data { + struct client_init_general_data general; + struct client_init_tx_data tx; }; @@ -3077,10 +4151,8 @@ struct ustorm_eth_rx_producers { */ struct cfc_del_event_data { u32 cid; - u8 error; - u8 reserved0; - u16 reserved1; - u32 reserved2; + u32 reserved0; + u32 reserved1; }; @@ -3088,22 +4160,18 @@ struct cfc_del_event_data { * per-port SAFC demo variables */ struct cmng_flags_per_port { - u8 con_number[NUM_OF_PROTOCOLS]; u32 cmng_enables; #define CMNG_FLAGS_PER_PORT_FAIRNESS_VN (0x1<<0) #define CMNG_FLAGS_PER_PORT_FAIRNESS_VN_SHIFT 0 #define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN (0x1<<1) #define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN_SHIFT 1 -#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL (0x1<<2) -#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL_SHIFT 2 -#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL (0x1<<3) -#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3 -#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4) -#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4 -#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE (0x1<<5) -#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE_SHIFT 5 -#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x3FFFFFF<<6) -#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 6 +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<2) +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 2 +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE (0x1<<3) +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE_SHIFT 3 +#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0xFFFFFFF<<4) +#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 4 + u32 __reserved1; }; @@ -3122,6 +4190,7 @@ struct fairness_vars_per_port { u32 upper_bound; u32 fair_threshold; u32 fairness_timeout; + u32 reserved0; }; /* @@ -3138,42 +4207,9 @@ struct safc_struct_per_port { u16 __reserved1; #endif u8 cos_to_traffic_types[MAX_COS_NUMBER]; - u32 __reserved2; u16 cos_to_pause_mask[NUM_OF_SAFC_BITS]; }; -/* - * per-port PFC variables - */ -struct pfc_struct_per_port { - u8 priority_to_traffic_types[MAX_PFC_PRIORITIES]; -#if defined(__BIG_ENDIAN) - u16 pfc_pause_quanta_in_nanosec; - u8 __reserved0; - u8 priority_non_pausable_mask; -#elif defined(__LITTLE_ENDIAN) - u8 priority_non_pausable_mask; - u8 __reserved0; - u16 pfc_pause_quanta_in_nanosec; -#endif -}; - -/* - * Priority and cos - */ -struct priority_cos { -#if defined(__BIG_ENDIAN) - u16 reserved1; - u8 cos; - u8 priority; -#elif defined(__LITTLE_ENDIAN) - u8 priority; - u8 cos; - u16 reserved1; -#endif - u32 reserved2; -}; - /* * Per-port congestion management variables */ @@ -3181,22 +4217,55 @@ struct cmng_struct_per_port { struct rate_shaping_vars_per_port rs_vars; struct fairness_vars_per_port fair_vars; struct safc_struct_per_port safc_vars; - struct pfc_struct_per_port pfc_vars; -#if defined(__BIG_ENDIAN) - u16 __reserved1; - u8 dcb_enabled; - u8 llfc_mode; -#elif defined(__LITTLE_ENDIAN) - u8 llfc_mode; - u8 dcb_enabled; - u16 __reserved1; -#endif - struct priority_cos - traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES]; struct cmng_flags_per_port flags; }; +/* + * Protocol-common command ID for slow path elements + */ +enum common_spqe_cmd_id { + RAMROD_CMD_ID_COMMON_UNUSED, + RAMROD_CMD_ID_COMMON_FUNCTION_START, + RAMROD_CMD_ID_COMMON_FUNCTION_STOP, + RAMROD_CMD_ID_COMMON_CFC_DEL, + RAMROD_CMD_ID_COMMON_CFC_DEL_WB, + RAMROD_CMD_ID_COMMON_STAT_QUERY, + RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, + RAMROD_CMD_ID_COMMON_START_TRAFFIC, + RAMROD_CMD_ID_COMMON_RESERVED1, + RAMROD_CMD_ID_COMMON_RESERVED2, + MAX_COMMON_SPQE_CMD_ID +}; + + +/* + * Per-protocol connection types + */ +enum connection_type { + ETH_CONNECTION_TYPE, + TOE_CONNECTION_TYPE, + RDMA_CONNECTION_TYPE, + ISCSI_CONNECTION_TYPE, + FCOE_CONNECTION_TYPE, + RESERVED_CONNECTION_TYPE_0, + RESERVED_CONNECTION_TYPE_1, + RESERVED_CONNECTION_TYPE_2, + NONE_CONNECTION_TYPE, + MAX_CONNECTION_TYPE +}; + + +/* + * Cos modes + */ +enum cos_mode { + OVERRIDE_COS, + STATIC_COS, + FW_WRR, + MAX_COS_MODE +}; + /* * Dynamic HC counters set by the driver @@ -3213,126 +4282,174 @@ struct cstorm_queue_zone_data { struct regpair reserved[2]; }; + /* - * Dynamic host coalescing init parameters + * Vf-PF channel data in cstorm ram (non-triggered zone) */ -struct dynamic_hc_config { - u32 threshold[3]; - u8 shift_per_protocol[HC_SB_MAX_DYNAMIC_INDICES]; - u8 hc_timeout0[HC_SB_MAX_DYNAMIC_INDICES]; - u8 hc_timeout1[HC_SB_MAX_DYNAMIC_INDICES]; - u8 hc_timeout2[HC_SB_MAX_DYNAMIC_INDICES]; - u8 hc_timeout3[HC_SB_MAX_DYNAMIC_INDICES]; +struct vf_pf_channel_zone_data { + u32 msg_addr_lo; + u32 msg_addr_hi; }; - /* - * Protocol-common statistics collected by the Xstorm (per client) + * zone for VF non-triggered data */ -struct xstorm_per_client_stats { - __le32 reserved0; - __le32 unicast_pkts_sent; - struct regpair unicast_bytes_sent; - struct regpair multicast_bytes_sent; - __le32 multicast_pkts_sent; - __le32 broadcast_pkts_sent; - struct regpair broadcast_bytes_sent; - __le16 stats_counter; - __le16 reserved1; - __le32 reserved2; +struct non_trigger_vf_zone { + struct vf_pf_channel_zone_data vf_pf_channel; }; /* - * Common statistics collected by the Xstorm (per port) + * Vf-PF channel trigger zone in cstorm ram */ -struct xstorm_common_stats { - struct xstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; +struct vf_pf_channel_zone_trigger { + u8 addr_valid; }; /* - * Protocol-common statistics collected by the Tstorm (per port) + * zone that triggers the in-bound interrupt */ -struct tstorm_per_port_stats { - __le32 mac_filter_discard; - __le32 xxoverflow_discard; - __le32 brb_truncate_discard; - __le32 mac_discard; +struct trigger_vf_zone { +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 reserved0; + struct vf_pf_channel_zone_trigger vf_pf_channel; +#elif defined(__LITTLE_ENDIAN) + struct vf_pf_channel_zone_trigger vf_pf_channel; + u8 reserved0; + u16 reserved1; +#endif + u32 reserved2; }; /* - * Protocol-common statistics collected by the Tstorm (per client) + * zone B per-VF data */ -struct tstorm_per_client_stats { - struct regpair rcv_unicast_bytes; - struct regpair rcv_broadcast_bytes; - struct regpair rcv_multicast_bytes; - struct regpair rcv_error_bytes; - __le32 checksum_discard; - __le32 packets_too_big_discard; - __le32 rcv_unicast_pkts; - __le32 rcv_broadcast_pkts; - __le32 rcv_multicast_pkts; - __le32 no_buff_discard; - __le32 ttl0_discard; - __le16 stats_counter; - __le16 reserved0; +struct cstorm_vf_zone_data { + struct non_trigger_vf_zone non_trigger; + struct trigger_vf_zone trigger; }; + /* - * Protocol-common statistics collected by the Tstorm + * Dynamic host coalescing init parameters, per state machine */ -struct tstorm_common_stats { - struct tstorm_per_port_stats port_statistics; - struct tstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; +struct dynamic_hc_sm_config { + u32 threshold[3]; + u8 shift_per_protocol[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout0[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout1[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout2[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout3[HC_SB_MAX_DYNAMIC_INDICES]; }; /* - * Protocol-common statistics collected by the Ustorm (per client) + * Dynamic host coalescing init parameters */ -struct ustorm_per_client_stats { - struct regpair ucast_no_buff_bytes; - struct regpair mcast_no_buff_bytes; - struct regpair bcast_no_buff_bytes; - __le32 ucast_no_buff_pkts; - __le32 mcast_no_buff_pkts; - __le32 bcast_no_buff_pkts; - __le16 stats_counter; - __le16 reserved0; +struct dynamic_hc_config { + struct dynamic_hc_sm_config sm_config[HC_SB_MAX_SM]; +}; + + +struct e2_integ_data { +#if defined(__BIG_ENDIAN) + u8 flags; +#define E2_INTEG_DATA_TESTING_EN (0x1<<0) +#define E2_INTEG_DATA_TESTING_EN_SHIFT 0 +#define E2_INTEG_DATA_LB_TX (0x1<<1) +#define E2_INTEG_DATA_LB_TX_SHIFT 1 +#define E2_INTEG_DATA_COS_TX (0x1<<2) +#define E2_INTEG_DATA_COS_TX_SHIFT 2 +#define E2_INTEG_DATA_OPPORTUNISTICQM (0x1<<3) +#define E2_INTEG_DATA_OPPORTUNISTICQM_SHIFT 3 +#define E2_INTEG_DATA_DPMTESTRELEASEDQ (0x1<<4) +#define E2_INTEG_DATA_DPMTESTRELEASEDQ_SHIFT 4 +#define E2_INTEG_DATA_RESERVED (0x7<<5) +#define E2_INTEG_DATA_RESERVED_SHIFT 5 + u8 cos; + u8 voq; + u8 pbf_queue; +#elif defined(__LITTLE_ENDIAN) + u8 pbf_queue; + u8 voq; + u8 cos; + u8 flags; +#define E2_INTEG_DATA_TESTING_EN (0x1<<0) +#define E2_INTEG_DATA_TESTING_EN_SHIFT 0 +#define E2_INTEG_DATA_LB_TX (0x1<<1) +#define E2_INTEG_DATA_LB_TX_SHIFT 1 +#define E2_INTEG_DATA_COS_TX (0x1<<2) +#define E2_INTEG_DATA_COS_TX_SHIFT 2 +#define E2_INTEG_DATA_OPPORTUNISTICQM (0x1<<3) +#define E2_INTEG_DATA_OPPORTUNISTICQM_SHIFT 3 +#define E2_INTEG_DATA_DPMTESTRELEASEDQ (0x1<<4) +#define E2_INTEG_DATA_DPMTESTRELEASEDQ_SHIFT 4 +#define E2_INTEG_DATA_RESERVED (0x7<<5) +#define E2_INTEG_DATA_RESERVED_SHIFT 5 +#endif +#if defined(__BIG_ENDIAN) + u16 reserved3; + u8 reserved2; + u8 ramEn; +#elif defined(__LITTLE_ENDIAN) + u8 ramEn; + u8 reserved2; + u16 reserved3; +#endif }; + /* - * Protocol-common statistics collected by the Ustorm + * set mac event data */ -struct ustorm_common_stats { - struct ustorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; +struct eth_event_data { + u32 echo; + u32 reserved0; + u32 reserved1; }; + /* - * Eth statistics query structure for the eth_stats_query ramrod + * pf-vf event data */ -struct eth_stats_query { - struct xstorm_common_stats xstorm_common; - struct tstorm_common_stats tstorm_common; - struct ustorm_common_stats ustorm_common; +struct vf_pf_event_data { + u8 vf_id; + u8 reserved0; + u16 reserved1; + u32 msg_addr_lo; + u32 msg_addr_hi; }; +/* + * VF FLR event data + */ +struct vf_flr_event_data { + u8 vf_id; + u8 reserved0; + u16 reserved1; + u32 reserved2; + u32 reserved3; +}; /* - * set mac event data + * malicious VF event data */ -struct set_mac_event_data { - u16 echo; - u16 reserved0; - u32 reserved1; +struct malicious_vf_event_data { + u8 vf_id; + u8 reserved0; + u16 reserved1; u32 reserved2; + u32 reserved3; }; /* * union for all event ring message types */ union event_data { - struct set_mac_event_data set_mac_event; + struct vf_pf_event_data vf_pf_event; + struct eth_event_data eth_event; struct cfc_del_event_data cfc_del_event; + struct vf_flr_event_data vf_flr_event; + struct malicious_vf_event_data malicious_vf_event; }; @@ -3359,7 +4476,7 @@ struct event_ring_data { */ struct event_ring_msg { u8 opcode; - u8 reserved0; + u8 error; u16 reserved1; union event_data data; }; @@ -3381,33 +4498,83 @@ union event_ring_elem { }; +/* + * Common event ring opcodes + */ +enum event_ring_opcode { + EVENT_RING_OPCODE_VF_PF_CHANNEL, + EVENT_RING_OPCODE_FUNCTION_START, + EVENT_RING_OPCODE_FUNCTION_STOP, + EVENT_RING_OPCODE_CFC_DEL, + EVENT_RING_OPCODE_CFC_DEL_WB, + EVENT_RING_OPCODE_STAT_QUERY, + EVENT_RING_OPCODE_STOP_TRAFFIC, + EVENT_RING_OPCODE_START_TRAFFIC, + EVENT_RING_OPCODE_VF_FLR, + EVENT_RING_OPCODE_MALICIOUS_VF, + EVENT_RING_OPCODE_FORWARD_SETUP, + EVENT_RING_OPCODE_RSS_UPDATE_RULES, + EVENT_RING_OPCODE_RESERVED1, + EVENT_RING_OPCODE_RESERVED2, + EVENT_RING_OPCODE_SET_MAC, + EVENT_RING_OPCODE_CLASSIFICATION_RULES, + EVENT_RING_OPCODE_FILTERS_RULES, + EVENT_RING_OPCODE_MULTICAST_RULES, + MAX_EVENT_RING_OPCODE +}; + + +/* + * Modes for fairness algorithm + */ +enum fairness_mode { + FAIRNESS_COS_WRR_MODE, + FAIRNESS_COS_ETS_MODE, + MAX_FAIRNESS_MODE +}; + + /* * per-vnic fairness variables */ struct fairness_vars_per_vn { u32 cos_credit_delta[MAX_COS_NUMBER]; - u32 protocol_credit_delta[NUM_OF_PROTOCOLS]; u32 vn_credit_delta; u32 __reserved0; }; +/* + * Priority and cos + */ +struct priority_cos { + u8 priority; + u8 cos; + __le16 reserved1; +}; + /* * The data for flow control configuration */ struct flow_control_configuration { - struct priority_cos - traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES]; -#if defined(__BIG_ENDIAN) - u16 reserved1; - u8 dcb_version; - u8 dcb_enabled; -#elif defined(__LITTLE_ENDIAN) + struct priority_cos traffic_type_to_priority_cos[MAX_TRAFFIC_TYPES]; u8 dcb_enabled; u8 dcb_version; - u16 reserved1; -#endif - u32 reserved2; + u8 dont_add_pri_0_en; + u8 reserved1; + __le32 reserved2; +}; + + +/* + * + */ +struct function_start_data { + __le16 function_mode; + __le16 sd_vlan_tag; + u16 reserved; + u8 path_id; + u8 network_cos_mode; }; @@ -3520,32 +4687,44 @@ struct hc_sb_data { struct pci_entity p_func; #if defined(__BIG_ENDIAN) u8 rsrv0; + u8 state; u8 dhc_qzone_id; - u8 __dynamic_hc_level; u8 same_igu_sb_1b; #elif defined(__LITTLE_ENDIAN) u8 same_igu_sb_1b; - u8 __dynamic_hc_level; u8 dhc_qzone_id; + u8 state; u8 rsrv0; #endif struct regpair rsrv1[2]; }; +/* + * Segment types for host coaslescing + */ +enum hc_segment { + HC_REGULAR_SEGMENT, + HC_DEFAULT_SEGMENT, + MAX_HC_SEGMENT +}; + + /* * The fast-path status block meta-data */ struct hc_sp_status_block_data { struct regpair host_sb_addr; #if defined(__BIG_ENDIAN) - u16 rsrv; + u8 rsrv1; + u8 state; u8 igu_seg_id; u8 igu_sb_id; #elif defined(__LITTLE_ENDIAN) u8 igu_sb_id; u8 igu_seg_id; - u16 rsrv; + u8 state; + u8 rsrv1; #endif struct pci_entity p_func; }; @@ -3569,6 +4748,129 @@ struct hc_status_block_data_e2 { }; +/* + * IGU block operartion modes (in Everest2) + */ +enum igu_mode { + HC_IGU_BC_MODE, + HC_IGU_NBC_MODE, + MAX_IGU_MODE +}; + + +/* + * IP versions + */ +enum ip_ver { + IP_V4, + IP_V6, + MAX_IP_VER +}; + + +/* + * Multi-function modes + */ +enum mf_mode { + SINGLE_FUNCTION, + MULTI_FUNCTION_SD, + MULTI_FUNCTION_SI, + MULTI_FUNCTION_RESERVED, + MAX_MF_MODE +}; + +/* + * Protocol-common statistics collected by the Tstorm (per pf) + */ +struct tstorm_per_pf_stats { + struct regpair rcv_error_bytes; +}; + +/* + * + */ +struct per_pf_stats { + struct tstorm_per_pf_stats tstorm_pf_statistics; +}; + + +/* + * Protocol-common statistics collected by the Tstorm (per port) + */ +struct tstorm_per_port_stats { + __le32 mac_discard; + __le32 mac_filter_discard; + __le32 brb_truncate_discard; + __le32 mf_tag_discard; + __le32 packet_drop; + __le32 reserved; +}; + +/* + * + */ +struct per_port_stats { + struct tstorm_per_port_stats tstorm_port_statistics; +}; + + +/* + * Protocol-common statistics collected by the Tstorm (per client) + */ +struct tstorm_per_queue_stats { + struct regpair rcv_ucast_bytes; + __le32 rcv_ucast_pkts; + __le32 checksum_discard; + struct regpair rcv_bcast_bytes; + __le32 rcv_bcast_pkts; + __le32 pkts_too_big_discard; + struct regpair rcv_mcast_bytes; + __le32 rcv_mcast_pkts; + __le32 ttl0_discard; + __le16 no_buff_discard; + __le16 reserved0; + __le32 reserved1; +}; + +/* + * Protocol-common statistics collected by the Ustorm (per client) + */ +struct ustorm_per_queue_stats { + struct regpair ucast_no_buff_bytes; + struct regpair mcast_no_buff_bytes; + struct regpair bcast_no_buff_bytes; + __le32 ucast_no_buff_pkts; + __le32 mcast_no_buff_pkts; + __le32 bcast_no_buff_pkts; + __le32 coalesced_pkts; + struct regpair coalesced_bytes; + __le32 coalesced_events; + __le32 coalesced_aborts; +}; + +/* + * Protocol-common statistics collected by the Xstorm (per client) + */ +struct xstorm_per_queue_stats { + struct regpair ucast_bytes_sent; + struct regpair mcast_bytes_sent; + struct regpair bcast_bytes_sent; + __le32 ucast_pkts_sent; + __le32 mcast_pkts_sent; + __le32 bcast_pkts_sent; + __le32 error_drop_pkts; +}; + +/* + * + */ +struct per_queue_stats { + struct tstorm_per_queue_stats tstorm_queue_statistics; + struct ustorm_per_queue_stats ustorm_queue_statistics; + struct xstorm_per_queue_stats xstorm_queue_statistics; +}; + + /* * FW version stored in first line of pram */ @@ -3598,7 +4900,6 @@ union protocol_common_specific_data { u8 protocol_data[8]; struct regpair phy_address; struct regpair mac_config_addr; - struct common_query_ramrod_data query_ramrod_data; }; /* @@ -3629,7 +4930,6 @@ struct rate_shaping_counter { * per-vnic rate shaping variables */ struct rate_shaping_vars_per_vn { - struct rate_shaping_counter protocol_counters[NUM_OF_PROTOCOLS]; struct rate_shaping_counter vn_counter; }; @@ -3644,39 +4944,100 @@ struct slow_path_element { /* - * eth/toe flags that indicate if to query + * Protocol-common statistics counter */ -struct stats_indication_flags { - u32 collect_eth; - u32 collect_toe; +struct stats_counter { + __le16 xstats_counter; + __le16 reserved0; + __le32 reserved1; + __le16 tstats_counter; + __le16 reserved2; + __le32 reserved3; + __le16 ustats_counter; + __le16 reserved4; + __le32 reserved5; + __le16 cstats_counter; + __le16 reserved6; + __le32 reserved7; }; /* - * per-port PFC variables + * */ -struct storm_pfc_struct_per_port { -#if defined(__BIG_ENDIAN) - u16 mid_mac_addr; - u16 msb_mac_addr; -#elif defined(__LITTLE_ENDIAN) - u16 msb_mac_addr; - u16 mid_mac_addr; -#endif -#if defined(__BIG_ENDIAN) - u16 pfc_pause_quanta_in_nanosec; - u16 lsb_mac_addr; -#elif defined(__LITTLE_ENDIAN) - u16 lsb_mac_addr; - u16 pfc_pause_quanta_in_nanosec; -#endif +struct stats_query_entry { + u8 kind; + u8 index; + __le16 funcID; + __le32 reserved; + struct regpair address; }; /* - * Per-port congestion management variables + * statistic command */ -struct storm_cmng_struct_per_port { - struct storm_pfc_struct_per_port pfc_vars; +struct stats_query_cmd_group { + struct stats_query_entry query[STATS_QUERY_CMD_COUNT]; +}; + + +/* + * statistic command header + */ +struct stats_query_header { + u8 cmd_num; + u8 reserved0; + __le16 drv_stats_counter; + __le32 reserved1; + struct regpair stats_counters_addrs; +}; + + +/* + * Types of statistcis query entry + */ +enum stats_query_type { + STATS_TYPE_QUEUE, + STATS_TYPE_PORT, + STATS_TYPE_PF, + STATS_TYPE_TOE, + STATS_TYPE_FCOE, + MAX_STATS_QUERY_TYPE +}; + + +/* + * Indicate of the function status block state + */ +enum status_block_state { + SB_DISABLED, + SB_ENABLED, + SB_CLEANED, + MAX_STATUS_BLOCK_STATE +}; + + +/* + * Storm IDs (including attentions for IGU related enums) + */ +enum storm_id { + USTORM_ID, + CSTORM_ID, + XSTORM_ID, + TSTORM_ID, + ATTENTION_ID, + MAX_STORM_ID +}; + + +/* + * Taffic types used in ETS and flow control algorithms + */ +enum traffic_type { + LLFC_TRAFFIC_TYPE_NW, + LLFC_TRAFFIC_TYPE_FCOE, + LLFC_TRAFFIC_TYPE_ISCSI, + MAX_TRAFFIC_TYPE }; @@ -3730,6 +5091,16 @@ struct vf_pf_channel_data { }; +/* + * State of VF-PF channel + */ +enum vf_pf_channel_state { + VF_PF_CHANNEL_STATE_READY, + VF_PF_CHANNEL_STATE_WAITING_FOR_ACK, + MAX_VF_PF_CHANNEL_STATE +}; + + /* * zone A per-queue data */ diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index d5399206f66..8b1d6258443 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -15,98 +15,34 @@ #ifndef BNX2X_INIT_H #define BNX2X_INIT_H -/* RAM0 size in bytes */ -#define STORM_INTMEM_SIZE_E1 0x5800 -#define STORM_INTMEM_SIZE_E1H 0x10000 -#define STORM_INTMEM_SIZE(bp) ((CHIP_IS_E1(bp) ? STORM_INTMEM_SIZE_E1 : \ - STORM_INTMEM_SIZE_E1H) / 4) - - /* Init operation types and structures */ -/* Common for both E1 and E1H */ -#define OP_RD 0x1 /* read single register */ -#define OP_WR 0x2 /* write single register */ -#define OP_IW 0x3 /* write single register using mailbox */ -#define OP_SW 0x4 /* copy a string to the device */ -#define OP_SI 0x5 /* copy a string using mailbox */ -#define OP_ZR 0x6 /* clear memory */ -#define OP_ZP 0x7 /* unzip then copy with DMAE */ -#define OP_WR_64 0x8 /* write 64 bit pattern */ -#define OP_WB 0x9 /* copy a string using DMAE */ - -/* FPGA and EMUL specific operations */ -#define OP_WR_EMUL 0xa /* write single register on Emulation */ -#define OP_WR_FPGA 0xb /* write single register on FPGA */ -#define OP_WR_ASIC 0xc /* write single register on ASIC */ - -/* Init stages */ -/* Never reorder stages !!! */ -#define COMMON_STAGE 0 -#define PORT0_STAGE 1 -#define PORT1_STAGE 2 -#define FUNC0_STAGE 3 -#define FUNC1_STAGE 4 -#define FUNC2_STAGE 5 -#define FUNC3_STAGE 6 -#define FUNC4_STAGE 7 -#define FUNC5_STAGE 8 -#define FUNC6_STAGE 9 -#define FUNC7_STAGE 10 -#define STAGE_IDX_MAX 11 - -#define STAGE_START 0 -#define STAGE_END 1 - - -/* Indices of blocks */ -#define PRS_BLOCK 0 -#define SRCH_BLOCK 1 -#define TSDM_BLOCK 2 -#define TCM_BLOCK 3 -#define BRB1_BLOCK 4 -#define TSEM_BLOCK 5 -#define PXPCS_BLOCK 6 -#define EMAC0_BLOCK 7 -#define EMAC1_BLOCK 8 -#define DBU_BLOCK 9 -#define MISC_BLOCK 10 -#define DBG_BLOCK 11 -#define NIG_BLOCK 12 -#define MCP_BLOCK 13 -#define UPB_BLOCK 14 -#define CSDM_BLOCK 15 -#define USDM_BLOCK 16 -#define CCM_BLOCK 17 -#define UCM_BLOCK 18 -#define USEM_BLOCK 19 -#define CSEM_BLOCK 20 -#define XPB_BLOCK 21 -#define DQ_BLOCK 22 -#define TIMERS_BLOCK 23 -#define XSDM_BLOCK 24 -#define QM_BLOCK 25 -#define PBF_BLOCK 26 -#define XCM_BLOCK 27 -#define XSEM_BLOCK 28 -#define CDU_BLOCK 29 -#define DMAE_BLOCK 30 -#define PXP_BLOCK 31 -#define CFC_BLOCK 32 -#define HC_BLOCK 33 -#define PXP2_BLOCK 34 -#define MISC_AEU_BLOCK 35 -#define PGLUE_B_BLOCK 36 -#define IGU_BLOCK 37 -#define ATC_BLOCK 38 -#define QM_4PORT_BLOCK 39 -#define XSEM_4PORT_BLOCK 40 +enum { + OP_RD = 0x1, /* read a single register */ + OP_WR, /* write a single register */ + OP_SW, /* copy a string to the device */ + OP_ZR, /* clear memory */ + OP_ZP, /* unzip then copy with DMAE */ + OP_WR_64, /* write 64 bit pattern */ + OP_WB, /* copy a string using DMAE */ + OP_WB_ZR, /* Clear a string using DMAE or indirect-wr */ + /* Skip the following ops if all of the init modes don't match */ + OP_IF_MODE_OR, + /* Skip the following ops if any of the init modes don't match */ + OP_IF_MODE_AND, + OP_MAX +}; +enum { + STAGE_START, + STAGE_END, +}; /* Returns the index of start or end of a specific block stage in ops array*/ #define BLOCK_OPS_IDX(block, stage, end) \ - (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end)) + (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end)) +/* structs for the various opcodes */ struct raw_op { u32 op:8; u32 offset:24; @@ -116,7 +52,7 @@ struct raw_op { struct op_read { u32 op:8; u32 offset:24; - u32 pad; + u32 val; }; struct op_write { @@ -125,15 +61,15 @@ struct op_write { u32 val; }; -struct op_string_write { +struct op_arr_write { u32 op:8; u32 offset:24; -#ifdef __LITTLE_ENDIAN - u16 data_off; - u16 data_len; -#else /* __BIG_ENDIAN */ +#ifdef __BIG_ENDIAN u16 data_len; u16 data_off; +#else /* __LITTLE_ENDIAN */ + u16 data_off; + u16 data_len; #endif }; @@ -143,14 +79,210 @@ struct op_zero { u32 len; }; +struct op_if_mode { + u32 op:8; + u32 cmd_offset:24; + u32 mode_bit_map; +}; + + union init_op { struct op_read read; struct op_write write; - struct op_string_write str_wr; + struct op_arr_write arr_wr; struct op_zero zero; struct raw_op raw; + struct op_if_mode if_mode; +}; + + +/* Init Phases */ +enum { + PHASE_COMMON, + PHASE_PORT0, + PHASE_PORT1, + PHASE_PF0, + PHASE_PF1, + PHASE_PF2, + PHASE_PF3, + PHASE_PF4, + PHASE_PF5, + PHASE_PF6, + PHASE_PF7, + NUM_OF_INIT_PHASES }; +/* Init Modes */ +enum { + MODE_ASIC = 0x00000001, + MODE_FPGA = 0x00000002, + MODE_EMUL = 0x00000004, + MODE_E2 = 0x00000008, + MODE_E3 = 0x00000010, + MODE_PORT2 = 0x00000020, + MODE_PORT4 = 0x00000040, + MODE_SF = 0x00000080, + MODE_MF = 0x00000100, + MODE_MF_SD = 0x00000200, + MODE_MF_SI = 0x00000400, + MODE_MF_NIV = 0x00000800, + MODE_E3_A0 = 0x00001000, + MODE_E3_B0 = 0x00002000, + MODE_COS_BC = 0x00004000, + MODE_COS3 = 0x00008000, + MODE_COS6 = 0x00010000, + MODE_LITTLE_ENDIAN = 0x00020000, + MODE_BIG_ENDIAN = 0x00040000, +}; + +/* Init Blocks */ +enum { + BLOCK_ATC, + BLOCK_BRB1, + BLOCK_CCM, + BLOCK_CDU, + BLOCK_CFC, + BLOCK_CSDM, + BLOCK_CSEM, + BLOCK_DBG, + BLOCK_DMAE, + BLOCK_DORQ, + BLOCK_HC, + BLOCK_IGU, + BLOCK_MISC, + BLOCK_NIG, + BLOCK_PBF, + BLOCK_PGLUE_B, + BLOCK_PRS, + BLOCK_PXP2, + BLOCK_PXP, + BLOCK_QM, + BLOCK_SRC, + BLOCK_TCM, + BLOCK_TM, + BLOCK_TSDM, + BLOCK_TSEM, + BLOCK_UCM, + BLOCK_UPB, + BLOCK_USDM, + BLOCK_USEM, + BLOCK_XCM, + BLOCK_XPB, + BLOCK_XSDM, + BLOCK_XSEM, + BLOCK_MISC_AEU, + NUM_OF_INIT_BLOCKS +}; + +/* QM queue numbers */ +#define BNX2X_ETH_Q 0 +#define BNX2X_TOE_Q 3 +#define BNX2X_TOE_ACK_Q 6 +#define BNX2X_ISCSI_Q 9 +#define BNX2X_ISCSI_ACK_Q 8 +#define BNX2X_FCOE_Q 10 + +/* Vnics per mode */ +#define BNX2X_PORT2_MODE_NUM_VNICS 4 +#define BNX2X_PORT4_MODE_NUM_VNICS 2 + +/* COS offset for port1 in E3 B0 4port mode */ +#define BNX2X_E3B0_PORT1_COS_OFFSET 3 + +/* QM Register addresses */ +#define BNX2X_Q_VOQ_REG_ADDR(pf_q_num)\ + (QM_REG_QVOQIDX_0 + 4 * (pf_q_num)) +#define BNX2X_VOQ_Q_REG_ADDR(cos, pf_q_num)\ + (QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5))) +#define BNX2X_Q_CMDQ_REG_ADDR(pf_q_num)\ + (QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4)) + +/* extracts the QM queue number for the specified port and vnic */ +#define BNX2X_PF_Q_NUM(q_num, port, vnic)\ + ((((port) << 1) | (vnic)) * 16 + (q_num)) + + +/* Maps the specified queue to the specified COS */ +static inline void bnx2x_map_q_cos(struct bnx2x *bp, u32 q_num, u32 new_cos) +{ + /* find current COS mapping */ + u32 curr_cos = REG_RD(bp, QM_REG_QVOQIDX_0 + q_num * 4); + + /* check if queue->COS mapping has changed */ + if (curr_cos != new_cos) { + u32 num_vnics = BNX2X_PORT2_MODE_NUM_VNICS; + u32 reg_addr, reg_bit_map, vnic; + + /* update parameters for 4port mode */ + if (INIT_MODE_FLAGS(bp) & MODE_PORT4) { + num_vnics = BNX2X_PORT4_MODE_NUM_VNICS; + if (BP_PORT(bp)) { + curr_cos += BNX2X_E3B0_PORT1_COS_OFFSET; + new_cos += BNX2X_E3B0_PORT1_COS_OFFSET; + } + } + + /* change queue mapping for each VNIC */ + for (vnic = 0; vnic < num_vnics; vnic++) { + u32 pf_q_num = + BNX2X_PF_Q_NUM(q_num, BP_PORT(bp), vnic); + u32 q_bit_map = 1 << (pf_q_num & 0x1f); + + /* overwrite queue->VOQ mapping */ + REG_WR(bp, BNX2X_Q_VOQ_REG_ADDR(pf_q_num), new_cos); + + /* clear queue bit from current COS bit map */ + reg_addr = BNX2X_VOQ_Q_REG_ADDR(curr_cos, pf_q_num); + reg_bit_map = REG_RD(bp, reg_addr); + REG_WR(bp, reg_addr, reg_bit_map & (~q_bit_map)); + + /* set queue bit in new COS bit map */ + reg_addr = BNX2X_VOQ_Q_REG_ADDR(new_cos, pf_q_num); + reg_bit_map = REG_RD(bp, reg_addr); + REG_WR(bp, reg_addr, reg_bit_map | q_bit_map); + + /* set/clear queue bit in command-queue bit map + (E2/E3A0 only, valid COS values are 0/1) */ + if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) { + reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num); + reg_bit_map = REG_RD(bp, reg_addr); + q_bit_map = 1 << (2 * (pf_q_num & 0xf)); + reg_bit_map = new_cos ? + (reg_bit_map | q_bit_map) : + (reg_bit_map & (~q_bit_map)); + REG_WR(bp, reg_addr, reg_bit_map); + } + } + } +} + +/* Configures the QM according to the specified per-traffic-type COSes */ +static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, + struct priority_cos *traffic_cos) +{ + bnx2x_map_q_cos(bp, BNX2X_FCOE_Q, + traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos); + bnx2x_map_q_cos(bp, BNX2X_ISCSI_Q, + traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); + if (INIT_MODE_FLAGS(bp) & MODE_COS_BC) { + /* required only in backward compatible COS mode */ + bnx2x_map_q_cos(bp, BNX2X_ETH_Q, + traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); + bnx2x_map_q_cos(bp, BNX2X_TOE_Q, + traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); + bnx2x_map_q_cos(bp, BNX2X_TOE_ACK_Q, + traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); + bnx2x_map_q_cos(bp, BNX2X_ISCSI_ACK_Q, + traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); + } +} + + +/* Returns the index of start or end of a specific block stage in ops array*/ +#define BLOCK_OPS_IDX(block, stage, end) \ + (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end)) + + #define INITOP_SET 0 /* set the HW directly */ #define INITOP_CLEAR 1 /* clear the HW directly */ #define INITOP_INIT 2 /* set the init-value array */ diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index aafd0232393..7ec1724753a 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -15,13 +15,39 @@ #ifndef BNX2X_INIT_OPS_H #define BNX2X_INIT_OPS_H + +#ifndef BP_ILT +#define BP_ILT(bp) NULL +#endif + +#ifndef BP_FUNC +#define BP_FUNC(bp) 0 +#endif + +#ifndef BP_PORT +#define BP_PORT(bp) 0 +#endif + +#ifndef BNX2X_ILT_FREE +#define BNX2X_ILT_FREE(x, y, sz) +#endif + +#ifndef BNX2X_ILT_ZALLOC +#define BNX2X_ILT_ZALLOC(x, y, sz) +#endif + +#ifndef ILOG2 +#define ILOG2(x) x +#endif + static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len); static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); -static void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, - u32 addr, u32 len); +static void bnx2x_write_dmae_phys_len(struct bnx2x *bp, + dma_addr_t phys_addr, u32 addr, + u32 len); -static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, - u32 len) +static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, + const u32 *data, u32 len) { u32 i; @@ -29,24 +55,32 @@ static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, REG_WR(bp, addr + i*4, data[i]); } -static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, - u32 len) +static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, + const u32 *data, u32 len) { u32 i; for (i = 0; i < len; i++) - REG_WR_IND(bp, addr + i*4, data[i]); + bnx2x_reg_wr_ind(bp, addr + i*4, data[i]); } -static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) +static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len, + u8 wb) { if (bp->dmae_ready) bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); + else if (wb) + /* + * Wide bus registers with no dmae need to be written + * using indirect write. + */ + bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); else bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len); } -static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) +static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, + u32 len, u8 wb) { u32 buf_len = (((len*4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len*4)); u32 buf_len32 = buf_len/4; @@ -57,12 +91,20 @@ static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) for (i = 0; i < len; i += buf_len32) { u32 cur_len = min(buf_len32, len - i); - bnx2x_write_big_buf(bp, addr + i*4, cur_len); + bnx2x_write_big_buf(bp, addr + i*4, cur_len, wb); } } -static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, - u32 len64) +static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) +{ + if (bp->dmae_ready) + bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); + else + bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); +} + +static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, + const u32 *data, u32 len64) { u32 buf_len32 = FW_BUF_SIZE/4; u32 len = len64*2; @@ -82,7 +124,7 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, for (i = 0; i < len; i += buf_len32) { u32 cur_len = min(buf_len32, len - i); - bnx2x_write_big_buf(bp, addr + i*4, cur_len); + bnx2x_write_big_buf_wb(bp, addr + i*4, cur_len); } } @@ -100,7 +142,8 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, #define IF_IS_PRAM_ADDR(base, addr) \ if (((base) <= (addr)) && ((base) + 0x40000 >= (addr))) -static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data) +static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, + const u8 *data) { IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr) data = INIT_TSEM_INT_TABLE_DATA(bp); @@ -129,31 +172,17 @@ static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data) return data; } -static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) +static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, + const u32 *data, u32 len) { if (bp->dmae_ready) - bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); + VIRT_WR_DMAE_LEN(bp, data, addr, len, 0); else - bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); -} - -static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, - u32 len) -{ - const u32 *old_data = data; - - data = (const u32 *)bnx2x_sel_blob(bp, addr, (const u8 *)data); - - if (bp->dmae_ready) { - if (old_data != data) - VIRT_WR_DMAE_LEN(bp, data, addr, len, 1); - else - VIRT_WR_DMAE_LEN(bp, data, addr, len, 0); - } else bnx2x_init_ind_wr(bp, addr, data, len); } -static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, u32 val_hi) +static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, + u32 val_hi) { u32 wb_write[2]; @@ -161,8 +190,8 @@ static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, u32 val_hi) wb_write[1] = val_hi; REG_WR_DMAE_LEN(bp, reg, wb_write, 2); } - -static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off) +static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, + u32 blob_off) { const u8 *data = NULL; int rc; @@ -186,39 +215,33 @@ static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off) static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage) { u16 op_start = - INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_START)]; + INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, + STAGE_START)]; u16 op_end = - INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_END)]; + INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, + STAGE_END)]; union init_op *op; - int hw_wr; - u32 i, op_type, addr, len; + u32 op_idx, op_type, addr, len; const u32 *data, *data_base; /* If empty block */ if (op_start == op_end) return; - if (CHIP_REV_IS_FPGA(bp)) - hw_wr = OP_WR_FPGA; - else if (CHIP_REV_IS_EMUL(bp)) - hw_wr = OP_WR_EMUL; - else - hw_wr = OP_WR_ASIC; - data_base = INIT_DATA(bp); - for (i = op_start; i < op_end; i++) { - - op = (union init_op *)&(INIT_OPS(bp)[i]); + for (op_idx = op_start; op_idx < op_end; op_idx++) { - op_type = op->str_wr.op; - addr = op->str_wr.offset; - len = op->str_wr.data_len; - data = data_base + op->str_wr.data_off; - - /* HW/EMUL specific */ - if ((op_type > OP_WB) && (op_type == hw_wr)) - op_type = OP_WR; + op = (union init_op *)&(INIT_OPS(bp)[op_idx]); + /* Get generic data */ + op_type = op->raw.op; + addr = op->raw.offset; + /* Get data that's used for OP_SW, OP_WB, OP_FW, OP_ZP and + * OP_WR64 (we assume that op_arr_write and op_write have the + * same structure). + */ + len = op->arr_wr.data_len; + data = data_base + op->arr_wr.data_off; switch (op_type) { case OP_RD: @@ -233,21 +256,39 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage) case OP_WB: bnx2x_init_wr_wb(bp, addr, data, len); break; - case OP_SI: - bnx2x_init_ind_wr(bp, addr, data, len); - break; case OP_ZR: - bnx2x_init_fill(bp, addr, 0, op->zero.len); + bnx2x_init_fill(bp, addr, 0, op->zero.len, 0); + break; + case OP_WB_ZR: + bnx2x_init_fill(bp, addr, 0, op->zero.len, 1); break; case OP_ZP: bnx2x_init_wr_zp(bp, addr, len, - op->str_wr.data_off); + op->arr_wr.data_off); break; case OP_WR_64: bnx2x_init_wr_64(bp, addr, data, len); break; + case OP_IF_MODE_AND: + /* if any of the flags doesn't match, skip the + * conditional block. + */ + if ((INIT_MODE_FLAGS(bp) & + op->if_mode.mode_bit_map) != + op->if_mode.mode_bit_map) + op_idx += op->if_mode.cmd_offset; + break; + case OP_IF_MODE_OR: + /* if all the flags don't match, skip the conditional + * block. + */ + if ((INIT_MODE_FLAGS(bp) & + op->if_mode.mode_bit_map) == 0) + op_idx += op->if_mode.cmd_offset; + break; default: - /* happens whenever an op is of a diff HW */ + /* Should never get here! */ + break; } } @@ -417,7 +458,8 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = { PXP2_REG_RQ_BW_WR_UBOUND30} }; -static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) +static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, + int w_order) { u32 val, i; @@ -491,19 +533,21 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) if ((CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) && (r_order == MAX_RD_ORD)) REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); - if (CHIP_IS_E2(bp)) + if (CHIP_IS_E3(bp)) + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x4 << w_order)); + else if (CHIP_IS_E2(bp)) REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x8 << w_order)); else REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); - if (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1(bp)) { /* MPS w_order optimal TH presently TH * 128 0 0 2 * 256 1 1 3 * >=512 2 2 3 */ /* DMAE is special */ - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1H(bp)) { /* E2 can use optimal TH */ val = w_order; REG_WR(bp, PXP2_REG_WR_DMAE_MPS, val); @@ -557,8 +601,8 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) #define ILT_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) #define ILT_RANGE(f, l) (((l) << 10) | f) -static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, struct ilt_line *line, - u32 size, u8 memop) +static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, + struct ilt_line *line, u32 size, u8 memop) { if (memop == ILT_MEMOP_FREE) { BNX2X_ILT_FREE(line->page, line->page_mapping, line->size); @@ -572,7 +616,8 @@ static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, struct ilt_line *line, } -static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, u8 memop) +static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, + u8 memop) { int i, rc; struct bnx2x_ilt *ilt = BP_ILT(bp); @@ -617,8 +662,8 @@ static void bnx2x_ilt_line_wr(struct bnx2x *bp, int abs_idx, bnx2x_wr_64(bp, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping)); } -static void bnx2x_ilt_line_init_op(struct bnx2x *bp, struct bnx2x_ilt *ilt, - int idx, u8 initop) +static void bnx2x_ilt_line_init_op(struct bnx2x *bp, + struct bnx2x_ilt *ilt, int idx, u8 initop) { dma_addr_t null_mapping; int abs_idx = ilt->start_line + idx; @@ -733,7 +778,7 @@ static void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop) } static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num, - u32 psz_reg, u8 initop) + u32 psz_reg, u8 initop) { struct bnx2x_ilt *ilt = BP_ILT(bp); struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; @@ -848,7 +893,8 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, /* Initialize T2 */ for (i = 0; i < src_cid_count-1; i++) - t2[i].next = (u64)(t2_mapping + (i+1)*sizeof(struct src_ent)); + t2[i].next = (u64)(t2_mapping + + (i+1)*sizeof(struct src_ent)); /* tell the searcher where the T2 table is */ REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, src_cid_count); diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 15b5bc17433..347f3239ad1 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -25,6 +25,8 @@ #include #include "bnx2x.h" +#include "bnx2x_cmn.h" + /********************************************************/ #define ETH_HLEN 14 @@ -874,6 +876,54 @@ static void bnx2x_update_pfc_brb(struct link_params *params, } } +/****************************************************************************** +* Description: +* This function is needed because NIG ARB_CREDIT_WEIGHT_X are +* not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable. +******************************************************************************/ +int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp, + u8 cos_entry, + u32 priority_mask, u8 port) +{ + u32 nig_reg_rx_priority_mask_add = 0; + + switch (cos_entry) { + case 0: + nig_reg_rx_priority_mask_add = (port) ? + NIG_REG_P1_RX_COS0_PRIORITY_MASK : + NIG_REG_P0_RX_COS0_PRIORITY_MASK; + break; + case 1: + nig_reg_rx_priority_mask_add = (port) ? + NIG_REG_P1_RX_COS1_PRIORITY_MASK : + NIG_REG_P0_RX_COS1_PRIORITY_MASK; + break; + case 2: + nig_reg_rx_priority_mask_add = (port) ? + NIG_REG_P1_RX_COS2_PRIORITY_MASK : + NIG_REG_P0_RX_COS2_PRIORITY_MASK; + break; + case 3: + if (port) + return -EINVAL; + nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK; + break; + case 4: + if (port) + return -EINVAL; + nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK; + break; + case 5: + if (port) + return -EINVAL; + nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK; + break; + } + + REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask); + + return 0; +} static void bnx2x_update_pfc_nig(struct link_params *params, struct link_vars *vars, struct bnx2x_nig_brb_pfc_port_params *nig_params) @@ -958,15 +1008,12 @@ static void bnx2x_update_pfc_nig(struct link_params *params, REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val); if (nig_params) { + u8 i = 0; pkt_priority_to_cos = nig_params->pkt_priority_to_cos; - REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK : - NIG_REG_P0_RX_COS0_PRIORITY_MASK, - nig_params->rx_cos0_priority_mask); - - REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK : - NIG_REG_P0_RX_COS1_PRIORITY_MASK, - nig_params->rx_cos1_priority_mask); + for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++) + bnx2x_pfc_nig_rx_priority_mask(bp, i, + nig_params->rx_cos_priority_mask[i], port); REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 : NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0, @@ -1824,26 +1871,6 @@ void bnx2x_link_status_update(struct link_params *params, vars->line_speed = SPEED_10000; break; - case LINK_12GTFD: - vars->line_speed = SPEED_12000; - break; - - case LINK_12_5GTFD: - vars->line_speed = SPEED_12500; - break; - - case LINK_13GTFD: - vars->line_speed = SPEED_13000; - break; - - case LINK_15GTFD: - vars->line_speed = SPEED_15000; - break; - - case LINK_16GTFD: - vars->line_speed = SPEED_16000; - break; - default: break; } @@ -2667,31 +2694,6 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, vars->link_status |= LINK_10GTFD; break; - case GP_STATUS_12G_HIG: - new_line_speed = SPEED_12000; - vars->link_status |= LINK_12GTFD; - break; - - case GP_STATUS_12_5G: - new_line_speed = SPEED_12500; - vars->link_status |= LINK_12_5GTFD; - break; - - case GP_STATUS_13G: - new_line_speed = SPEED_13000; - vars->link_status |= LINK_13GTFD; - break; - - case GP_STATUS_15G: - new_line_speed = SPEED_15000; - vars->link_status |= LINK_15GTFD; - break; - - case GP_STATUS_16G: - new_line_speed = SPEED_16000; - vars->link_status |= LINK_16GTFD; - break; - default: DP(NETIF_MSG_LINK, "link speed unsupported gp_status 0x%x\n", diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index a106d8cbd69..3fef7782490 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -81,6 +81,7 @@ #define PFC_BRB_FULL_LB_XOFF_THRESHOLD 170 #define PFC_BRB_FULL_LB_XON_THRESHOLD 250 +#define MAXVAL(a, b) (((a) > (b)) ? (a) : (b)) /***********************************************************/ /* Structs */ /***********************************************************/ @@ -262,6 +263,8 @@ struct link_vars { #define MAC_TYPE_NONE 0 #define MAC_TYPE_EMAC 1 #define MAC_TYPE_BMAC 2 +#define MAC_TYPE_UMAC 3 +#define MAC_TYPE_XMAC 4 u8 phy_link_up; /* internal phy link indication */ u8 link_up; @@ -363,6 +366,20 @@ int bnx2x_phy_probe(struct link_params *params); u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 port); +/* DCBX structs */ + +/* Number of maximum COS per chip */ +#define DCBX_E2E3_MAX_NUM_COS (2) +#define DCBX_E3B0_MAX_NUM_COS_PORT0 (6) +#define DCBX_E3B0_MAX_NUM_COS_PORT1 (3) +#define DCBX_E3B0_MAX_NUM_COS ( \ + MAXVAL(DCBX_E3B0_MAX_NUM_COS_PORT0, \ + DCBX_E3B0_MAX_NUM_COS_PORT1)) + +#define DCBX_MAX_NUM_COS ( \ + MAXVAL(DCBX_E3B0_MAX_NUM_COS, \ + DCBX_E2E3_MAX_NUM_COS)) + /* PFC port configuration params */ struct bnx2x_nig_brb_pfc_port_params { /* NIG */ @@ -370,8 +387,8 @@ struct bnx2x_nig_brb_pfc_port_params { u32 llfc_out_en; u32 llfc_enable; u32 pkt_priority_to_cos; - u32 rx_cos0_priority_mask; - u32 rx_cos1_priority_mask; + u8 num_of_rx_cos_priority_mask; + u32 rx_cos_priority_mask[DCBX_MAX_NUM_COS]; u32 llfc_high_priority_classes; u32 llfc_low_priority_classes; /* BRB */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 84f419fcde2..63c92091586 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,6 @@ #include #include -#define BNX2X_MAIN #include "bnx2x.h" #include "bnx2x_init.h" #include "bnx2x_init_ops.h" @@ -74,12 +74,14 @@ #define TX_TIMEOUT (5*HZ) static char version[] __devinitdata = - "Broadcom NetXtreme II 5771x 10Gigabit Ethernet Driver " + "Broadcom NetXtreme II 5771x/578xx 10/20-Gigabit Ethernet Driver " DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir"); MODULE_DESCRIPTION("Broadcom NetXtreme II " - "BCM57710/57711/57711E/57712/57712E Driver"); + "BCM57710/57711/57711E/" + "57712/57712_MF/57800/57800_MF/57810/57810_MF/" + "57840/57840_MF Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_FIRMWARE(FW_FILE_NAME_E1); @@ -104,7 +106,7 @@ MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); #define INT_MODE_MSI 2 static int int_mode; module_param(int_mode, int, 0); -MODULE_PARM_DESC(int_mode, " Force interrupt mode other then MSI-X " +MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " "(1 INT#x; 2 MSI)"); static int dropless_fc; @@ -123,37 +125,87 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, " Default debug msglevel"); -static struct workqueue_struct *bnx2x_wq; -#ifdef BCM_CNIC -static u8 ALL_ENODE_MACS[] = {0x01, 0x10, 0x18, 0x01, 0x00, 0x01}; -#endif + +struct workqueue_struct *bnx2x_wq; enum bnx2x_board_type { BCM57710 = 0, - BCM57711 = 1, - BCM57711E = 2, - BCM57712 = 3, - BCM57712E = 4 + BCM57711, + BCM57711E, + BCM57712, + BCM57712_MF, + BCM57800, + BCM57800_MF, + BCM57810, + BCM57810_MF, + BCM57840, + BCM57840_MF }; /* indexed by board_type, above */ static struct { char *name; } board_info[] __devinitdata = { - { "Broadcom NetXtreme II BCM57710 XGb" }, - { "Broadcom NetXtreme II BCM57711 XGb" }, - { "Broadcom NetXtreme II BCM57711E XGb" }, - { "Broadcom NetXtreme II BCM57712 XGb" }, - { "Broadcom NetXtreme II BCM57712E XGb" } + { "Broadcom NetXtreme II BCM57710 10 Gigabit PCIe [Everest]" }, + { "Broadcom NetXtreme II BCM57711 10 Gigabit PCIe" }, + { "Broadcom NetXtreme II BCM57711E 10 Gigabit PCIe" }, + { "Broadcom NetXtreme II BCM57712 10 Gigabit Ethernet" }, + { "Broadcom NetXtreme II BCM57712 10 Gigabit Ethernet Multi Function" }, + { "Broadcom NetXtreme II BCM57800 10 Gigabit Ethernet" }, + { "Broadcom NetXtreme II BCM57800 10 Gigabit Ethernet Multi Function" }, + { "Broadcom NetXtreme II BCM57810 10 Gigabit Ethernet" }, + { "Broadcom NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function" }, + { "Broadcom NetXtreme II BCM57840 10/20 Gigabit Ethernet" }, + { "Broadcom NetXtreme II BCM57840 10/20 Gigabit " + "Ethernet Multi Function"} }; +#ifndef PCI_DEVICE_ID_NX2_57710 +#define PCI_DEVICE_ID_NX2_57710 CHIP_NUM_57710 +#endif +#ifndef PCI_DEVICE_ID_NX2_57711 +#define PCI_DEVICE_ID_NX2_57711 CHIP_NUM_57711 +#endif +#ifndef PCI_DEVICE_ID_NX2_57711E +#define PCI_DEVICE_ID_NX2_57711E CHIP_NUM_57711E +#endif +#ifndef PCI_DEVICE_ID_NX2_57712 +#define PCI_DEVICE_ID_NX2_57712 CHIP_NUM_57712 +#endif +#ifndef PCI_DEVICE_ID_NX2_57712_MF +#define PCI_DEVICE_ID_NX2_57712_MF CHIP_NUM_57712_MF +#endif +#ifndef PCI_DEVICE_ID_NX2_57800 +#define PCI_DEVICE_ID_NX2_57800 CHIP_NUM_57800 +#endif +#ifndef PCI_DEVICE_ID_NX2_57800_MF +#define PCI_DEVICE_ID_NX2_57800_MF CHIP_NUM_57800_MF +#endif +#ifndef PCI_DEVICE_ID_NX2_57810 +#define PCI_DEVICE_ID_NX2_57810 CHIP_NUM_57810 +#endif +#ifndef PCI_DEVICE_ID_NX2_57810_MF +#define PCI_DEVICE_ID_NX2_57810_MF CHIP_NUM_57810_MF +#endif +#ifndef PCI_DEVICE_ID_NX2_57840 +#define PCI_DEVICE_ID_NX2_57840 CHIP_NUM_57840 +#endif +#ifndef PCI_DEVICE_ID_NX2_57840_MF +#define PCI_DEVICE_ID_NX2_57840_MF CHIP_NUM_57840_MF +#endif static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = { { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712), BCM57712 }, - { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712E), BCM57712E }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712_MF), BCM57712_MF }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57800), BCM57800 }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57800_MF), BCM57800_MF }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810), BCM57810 }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810_MF), BCM57810_MF }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840), BCM57840 }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_MF), BCM57840_MF }, { 0 } }; @@ -163,11 +215,47 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); * General service functions ****************************************************************************/ -static inline void storm_memset_ov(struct bnx2x *bp, u16 ov, u16 abs_fid) +static inline void __storm_memset_dma_mapping(struct bnx2x *bp, + u32 addr, dma_addr_t mapping) +{ + REG_WR(bp, addr, U64_LO(mapping)); + REG_WR(bp, addr + 4, U64_HI(mapping)); +} + +static inline void storm_memset_spq_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, + u16 pf_id) { - REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(abs_fid), ov); + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); } +static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, + u8 enable) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), + enable); +} static inline void storm_memset_eq_data(struct bnx2x *bp, struct event_ring_data *eq_data, @@ -187,45 +275,6 @@ static inline void storm_memset_eq_prod(struct bnx2x *bp, u16 eq_prod, REG_WR16(bp, addr, eq_prod); } -static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port, - u16 fw_sb_id, u8 sb_index, - u8 ticks) -{ - - int index_offset = CHIP_IS_E2(bp) ? - offsetof(struct hc_status_block_data_e2, index_data) : - offsetof(struct hc_status_block_data_e1x, index_data); - u32 addr = BAR_CSTRORM_INTMEM + - CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + - index_offset + - sizeof(struct hc_index_data)*sb_index + - offsetof(struct hc_index_data, timeout); - REG_WR8(bp, addr, ticks); - DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d ticks %d\n", - port, fw_sb_id, sb_index, ticks); -} -static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port, - u16 fw_sb_id, u8 sb_index, - u8 disable) -{ - u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); - int index_offset = CHIP_IS_E2(bp) ? - offsetof(struct hc_status_block_data_e2, index_data) : - offsetof(struct hc_status_block_data_e1x, index_data); - u32 addr = BAR_CSTRORM_INTMEM + - CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + - index_offset + - sizeof(struct hc_index_data)*sb_index + - offsetof(struct hc_index_data, flags); - u16 flags = REG_RD16(bp, addr); - /* clear and set */ - flags &= ~HC_INDEX_DATA_HC_ENABLED; - flags |= enable_flag; - REG_WR16(bp, addr, flags); - DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d disable %d\n", - port, fw_sb_id, sb_index, disable); -} - /* used only at init * locking is done by mcp */ @@ -319,13 +368,6 @@ static void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae, } -const u32 dmae_reg_go_c[] = { - DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, - DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, - DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11, - DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15 -}; - /* copy command into DMAE command memory and set DMAE command go */ void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx) { @@ -406,7 +448,11 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); - /* lock the dmae channel */ + /* + * Lock the dmae channel. Disable BHs to prevent a dead-lock + * as long as this code is called both from syscall context and + * from ndo_set_rx_mode() flow that may be called from BH. + */ spin_lock_bh(&bp->dmae_lock); /* reset completion */ @@ -730,9 +776,9 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* Indices */ /* Common */ BNX2X_ERR("def_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)" - " spq_prod_idx(0x%x)\n", - bp->def_idx, bp->def_att_idx, - bp->attn_state, bp->spq_prod_idx); + " spq_prod_idx(0x%x) next_stats_cnt(0x%x)\n", + bp->def_idx, bp->def_att_idx, bp->attn_state, + bp->spq_prod_idx, bp->stats_counter); BNX2X_ERR("DSB: attn bits(0x%x) ack(0x%x) id(0x%x) idx(0x%x)\n", bp->def_status_blk->atten_status_block.attn_bits, bp->def_status_blk->atten_status_block.attn_bits_ack, @@ -749,15 +795,17 @@ void bnx2x_panic_dump(struct bnx2x *bp) CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + i*sizeof(u32)); - pr_cont("igu_sb_id(0x%x) igu_seg_id (0x%x) " + pr_cont("igu_sb_id(0x%x) igu_seg_id(0x%x) " "pf_id(0x%x) vnic_id(0x%x) " - "vf_id(0x%x) vf_valid (0x%x)\n", + "vf_id(0x%x) vf_valid (0x%x) " + "state(0x%x)\n", sp_sb_data.igu_sb_id, sp_sb_data.igu_seg_id, sp_sb_data.p_func.pf_id, sp_sb_data.p_func.vnic_id, sp_sb_data.p_func.vf_id, - sp_sb_data.p_func.vf_valid); + sp_sb_data.p_func.vf_valid, + sp_sb_data.state); for_each_eth_queue(bp, i) { @@ -766,13 +814,13 @@ void bnx2x_panic_dump(struct bnx2x *bp) struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; struct hc_status_block_sm *hc_sm_p = - CHIP_IS_E2(bp) ? - sb_data_e2.common.state_machine : - sb_data_e1x.common.state_machine; + CHIP_IS_E1x(bp) ? + sb_data_e1x.common.state_machine : + sb_data_e2.common.state_machine; struct hc_index_data *hc_index_p = - CHIP_IS_E2(bp) ? - sb_data_e2.index_data : - sb_data_e1x.index_data; + CHIP_IS_E1x(bp) ? + sb_data_e1x.index_data : + sb_data_e2.index_data; int data_size; u32 *sb_data_p; @@ -795,8 +843,8 @@ void bnx2x_panic_dump(struct bnx2x *bp) i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); - loop = CHIP_IS_E2(bp) ? - HC_SB_MAX_INDICES_E2 : HC_SB_MAX_INDICES_E1X; + loop = CHIP_IS_E1x(bp) ? + HC_SB_MAX_INDICES_E1X : HC_SB_MAX_INDICES_E2; /* host sb data */ @@ -816,35 +864,39 @@ void bnx2x_panic_dump(struct bnx2x *bp) fp->sb_index_values[j], (j == loop - 1) ? ")" : " "); /* fw sb data */ - data_size = CHIP_IS_E2(bp) ? - sizeof(struct hc_status_block_data_e2) : - sizeof(struct hc_status_block_data_e1x); + data_size = CHIP_IS_E1x(bp) ? + sizeof(struct hc_status_block_data_e1x) : + sizeof(struct hc_status_block_data_e2); data_size /= sizeof(u32); - sb_data_p = CHIP_IS_E2(bp) ? - (u32 *)&sb_data_e2 : - (u32 *)&sb_data_e1x; + sb_data_p = CHIP_IS_E1x(bp) ? + (u32 *)&sb_data_e1x : + (u32 *)&sb_data_e2; /* copy sb data in here */ for (j = 0; j < data_size; j++) *(sb_data_p + j) = REG_RD(bp, BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + j * sizeof(u32)); - if (CHIP_IS_E2(bp)) { - pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " - "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + if (!CHIP_IS_E1x(bp)) { + pr_cont("pf_id(0x%x) vf_id(0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x) " + "state(0x%x)\n", sb_data_e2.common.p_func.pf_id, sb_data_e2.common.p_func.vf_id, sb_data_e2.common.p_func.vf_valid, sb_data_e2.common.p_func.vnic_id, - sb_data_e2.common.same_igu_sb_1b); + sb_data_e2.common.same_igu_sb_1b, + sb_data_e2.common.state); } else { - pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " - "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + pr_cont("pf_id(0x%x) vf_id(0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x) " + "state(0x%x)\n", sb_data_e1x.common.p_func.pf_id, sb_data_e1x.common.p_func.vf_id, sb_data_e1x.common.p_func.vf_valid, sb_data_e1x.common.p_func.vnic_id, - sb_data_e1x.common.same_igu_sb_1b); + sb_data_e1x.common.same_igu_sb_1b, + sb_data_e1x.common.state); } /* SB_SMs data */ @@ -933,6 +985,373 @@ void bnx2x_panic_dump(struct bnx2x *bp) BNX2X_ERR("end crash dump -----------------\n"); } +/* + * FLR Support for E2 + * + * bnx2x_pf_flr_clnup() is called during nic_load in the per function HW + * initialization. + */ +#define FLR_WAIT_USEC 10000 /* 10 miliseconds */ +#define FLR_WAIT_INTERAVAL 50 /* usec */ +#define FLR_POLL_CNT (FLR_WAIT_USEC/FLR_WAIT_INTERAVAL) /* 200 */ + +struct pbf_pN_buf_regs { + int pN; + u32 init_crd; + u32 crd; + u32 crd_freed; +}; + +struct pbf_pN_cmd_regs { + int pN; + u32 lines_occup; + u32 lines_freed; +}; + +static void bnx2x_pbf_pN_buf_flushed(struct bnx2x *bp, + struct pbf_pN_buf_regs *regs, + u32 poll_count) +{ + u32 init_crd, crd, crd_start, crd_freed, crd_freed_start; + u32 cur_cnt = poll_count; + + crd_freed = crd_freed_start = REG_RD(bp, regs->crd_freed); + crd = crd_start = REG_RD(bp, regs->crd); + init_crd = REG_RD(bp, regs->init_crd); + + DP(BNX2X_MSG_SP, "INIT CREDIT[%d] : %x\n", regs->pN, init_crd); + DP(BNX2X_MSG_SP, "CREDIT[%d] : s:%x\n", regs->pN, crd); + DP(BNX2X_MSG_SP, "CREDIT_FREED[%d]: s:%x\n", regs->pN, crd_freed); + + while ((crd != init_crd) && ((u32)SUB_S32(crd_freed, crd_freed_start) < + (init_crd - crd_start))) { + if (cur_cnt--) { + udelay(FLR_WAIT_INTERAVAL); + crd = REG_RD(bp, regs->crd); + crd_freed = REG_RD(bp, regs->crd_freed); + } else { + DP(BNX2X_MSG_SP, "PBF tx buffer[%d] timed out\n", + regs->pN); + DP(BNX2X_MSG_SP, "CREDIT[%d] : c:%x\n", + regs->pN, crd); + DP(BNX2X_MSG_SP, "CREDIT_FREED[%d]: c:%x\n", + regs->pN, crd_freed); + break; + } + } + DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF tx buffer[%d]\n", + poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN); +} + +static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp, + struct pbf_pN_cmd_regs *regs, + u32 poll_count) +{ + u32 occup, to_free, freed, freed_start; + u32 cur_cnt = poll_count; + + occup = to_free = REG_RD(bp, regs->lines_occup); + freed = freed_start = REG_RD(bp, regs->lines_freed); + + DP(BNX2X_MSG_SP, "OCCUPANCY[%d] : s:%x\n", regs->pN, occup); + DP(BNX2X_MSG_SP, "LINES_FREED[%d] : s:%x\n", regs->pN, freed); + + while (occup && ((u32)SUB_S32(freed, freed_start) < to_free)) { + if (cur_cnt--) { + udelay(FLR_WAIT_INTERAVAL); + occup = REG_RD(bp, regs->lines_occup); + freed = REG_RD(bp, regs->lines_freed); + } else { + DP(BNX2X_MSG_SP, "PBF cmd queue[%d] timed out\n", + regs->pN); + DP(BNX2X_MSG_SP, "OCCUPANCY[%d] : s:%x\n", + regs->pN, occup); + DP(BNX2X_MSG_SP, "LINES_FREED[%d] : s:%x\n", + regs->pN, freed); + break; + } + } + DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF cmd queue[%d]\n", + poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN); +} + +static inline u32 bnx2x_flr_clnup_reg_poll(struct bnx2x *bp, u32 reg, + u32 expected, u32 poll_count) +{ + u32 cur_cnt = poll_count; + u32 val; + + while ((val = REG_RD(bp, reg)) != expected && cur_cnt--) + udelay(FLR_WAIT_INTERAVAL); + + return val; +} + +static inline int bnx2x_flr_clnup_poll_hw_counter(struct bnx2x *bp, u32 reg, + char *msg, u32 poll_cnt) +{ + u32 val = bnx2x_flr_clnup_reg_poll(bp, reg, 0, poll_cnt); + if (val != 0) { + BNX2X_ERR("%s usage count=%d\n", msg, val); + return 1; + } + return 0; +} + +static u32 bnx2x_flr_clnup_poll_count(struct bnx2x *bp) +{ + /* adjust polling timeout */ + if (CHIP_REV_IS_EMUL(bp)) + return FLR_POLL_CNT * 2000; + + if (CHIP_REV_IS_FPGA(bp)) + return FLR_POLL_CNT * 120; + + return FLR_POLL_CNT; +} + +static void bnx2x_tx_hw_flushed(struct bnx2x *bp, u32 poll_count) +{ + struct pbf_pN_cmd_regs cmd_regs[] = { + {0, (CHIP_IS_E3B0(bp)) ? + PBF_REG_TQ_OCCUPANCY_Q0 : + PBF_REG_P0_TQ_OCCUPANCY, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_TQ_LINES_FREED_CNT_Q0 : + PBF_REG_P0_TQ_LINES_FREED_CNT}, + {1, (CHIP_IS_E3B0(bp)) ? + PBF_REG_TQ_OCCUPANCY_Q1 : + PBF_REG_P1_TQ_OCCUPANCY, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_TQ_LINES_FREED_CNT_Q1 : + PBF_REG_P1_TQ_LINES_FREED_CNT}, + {4, (CHIP_IS_E3B0(bp)) ? + PBF_REG_TQ_OCCUPANCY_LB_Q : + PBF_REG_P4_TQ_OCCUPANCY, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_TQ_LINES_FREED_CNT_LB_Q : + PBF_REG_P4_TQ_LINES_FREED_CNT} + }; + + struct pbf_pN_buf_regs buf_regs[] = { + {0, (CHIP_IS_E3B0(bp)) ? + PBF_REG_INIT_CRD_Q0 : + PBF_REG_P0_INIT_CRD , + (CHIP_IS_E3B0(bp)) ? + PBF_REG_CREDIT_Q0 : + PBF_REG_P0_CREDIT, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_INTERNAL_CRD_FREED_CNT_Q0 : + PBF_REG_P0_INTERNAL_CRD_FREED_CNT}, + {1, (CHIP_IS_E3B0(bp)) ? + PBF_REG_INIT_CRD_Q1 : + PBF_REG_P1_INIT_CRD, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_CREDIT_Q1 : + PBF_REG_P1_CREDIT, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_INTERNAL_CRD_FREED_CNT_Q1 : + PBF_REG_P1_INTERNAL_CRD_FREED_CNT}, + {4, (CHIP_IS_E3B0(bp)) ? + PBF_REG_INIT_CRD_LB_Q : + PBF_REG_P4_INIT_CRD, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_CREDIT_LB_Q : + PBF_REG_P4_CREDIT, + (CHIP_IS_E3B0(bp)) ? + PBF_REG_INTERNAL_CRD_FREED_CNT_LB_Q : + PBF_REG_P4_INTERNAL_CRD_FREED_CNT}, + }; + + int i; + + /* Verify the command queues are flushed P0, P1, P4 */ + for (i = 0; i < ARRAY_SIZE(cmd_regs); i++) + bnx2x_pbf_pN_cmd_flushed(bp, &cmd_regs[i], poll_count); + + + /* Verify the transmission buffers are flushed P0, P1, P4 */ + for (i = 0; i < ARRAY_SIZE(buf_regs); i++) + bnx2x_pbf_pN_buf_flushed(bp, &buf_regs[i], poll_count); +} + +#define OP_GEN_PARAM(param) \ + (((param) << SDM_OP_GEN_COMP_PARAM_SHIFT) & SDM_OP_GEN_COMP_PARAM) + +#define OP_GEN_TYPE(type) \ + (((type) << SDM_OP_GEN_COMP_TYPE_SHIFT) & SDM_OP_GEN_COMP_TYPE) + +#define OP_GEN_AGG_VECT(index) \ + (((index) << SDM_OP_GEN_AGG_VECT_IDX_SHIFT) & SDM_OP_GEN_AGG_VECT_IDX) + + +static inline int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, + u32 poll_cnt) +{ + struct sdm_op_gen op_gen = {0}; + + u32 comp_addr = BAR_CSTRORM_INTMEM + + CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(clnup_func); + int ret = 0; + + if (REG_RD(bp, comp_addr)) { + BNX2X_ERR("Cleanup complete is not 0\n"); + return 1; + } + + op_gen.command |= OP_GEN_PARAM(XSTORM_AGG_INT_FINAL_CLEANUP_INDEX); + op_gen.command |= OP_GEN_TYPE(XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE); + op_gen.command |= OP_GEN_AGG_VECT(clnup_func); + op_gen.command |= 1 << SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT; + + DP(BNX2X_MSG_SP, "FW Final cleanup\n"); + REG_WR(bp, XSDM_REG_OPERATION_GEN, op_gen.command); + + if (bnx2x_flr_clnup_reg_poll(bp, comp_addr, 1, poll_cnt) != 1) { + BNX2X_ERR("FW final cleanup did not succeed\n"); + ret = 1; + } + /* Zero completion for nxt FLR */ + REG_WR(bp, comp_addr, 0); + + return ret; +} + +static inline u8 bnx2x_is_pcie_pending(struct pci_dev *dev) +{ + int pos; + u16 status; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return false; + + pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status); + return status & PCI_EXP_DEVSTA_TRPND; +} + +/* PF FLR specific routines +*/ +static int bnx2x_poll_hw_usage_counters(struct bnx2x *bp, u32 poll_cnt) +{ + + /* wait for CFC PF usage-counter to zero (includes all the VFs) */ + if (bnx2x_flr_clnup_poll_hw_counter(bp, + CFC_REG_NUM_LCIDS_INSIDE_PF, + "CFC PF usage counter timed out", + poll_cnt)) + return 1; + + + /* Wait for DQ PF usage-counter to zero (until DQ cleanup) */ + if (bnx2x_flr_clnup_poll_hw_counter(bp, + DORQ_REG_PF_USAGE_CNT, + "DQ PF usage counter timed out", + poll_cnt)) + return 1; + + /* Wait for QM PF usage-counter to zero (until DQ cleanup) */ + if (bnx2x_flr_clnup_poll_hw_counter(bp, + QM_REG_PF_USG_CNT_0 + 4*BP_FUNC(bp), + "QM PF usage counter timed out", + poll_cnt)) + return 1; + + /* Wait for Timer PF usage-counters to zero (until DQ cleanup) */ + if (bnx2x_flr_clnup_poll_hw_counter(bp, + TM_REG_LIN0_VNIC_UC + 4*BP_PORT(bp), + "Timers VNIC usage counter timed out", + poll_cnt)) + return 1; + if (bnx2x_flr_clnup_poll_hw_counter(bp, + TM_REG_LIN0_NUM_SCANS + 4*BP_PORT(bp), + "Timers NUM_SCANS usage counter timed out", + poll_cnt)) + return 1; + + /* Wait DMAE PF usage counter to zero */ + if (bnx2x_flr_clnup_poll_hw_counter(bp, + dmae_reg_go_c[INIT_DMAE_C(bp)], + "DMAE dommand register timed out", + poll_cnt)) + return 1; + + return 0; +} + +static void bnx2x_hw_enable_status(struct bnx2x *bp) +{ + u32 val; + + val = REG_RD(bp, CFC_REG_WEAK_ENABLE_PF); + DP(BNX2X_MSG_SP, "CFC_REG_WEAK_ENABLE_PF is 0x%x\n", val); + + val = REG_RD(bp, PBF_REG_DISABLE_PF); + DP(BNX2X_MSG_SP, "PBF_REG_DISABLE_PF is 0x%x\n", val); + + val = REG_RD(bp, IGU_REG_PCI_PF_MSI_EN); + DP(BNX2X_MSG_SP, "IGU_REG_PCI_PF_MSI_EN is 0x%x\n", val); + + val = REG_RD(bp, IGU_REG_PCI_PF_MSIX_EN); + DP(BNX2X_MSG_SP, "IGU_REG_PCI_PF_MSIX_EN is 0x%x\n", val); + + val = REG_RD(bp, IGU_REG_PCI_PF_MSIX_FUNC_MASK); + DP(BNX2X_MSG_SP, "IGU_REG_PCI_PF_MSIX_FUNC_MASK is 0x%x\n", val); + + val = REG_RD(bp, PGLUE_B_REG_SHADOW_BME_PF_7_0_CLR); + DP(BNX2X_MSG_SP, "PGLUE_B_REG_SHADOW_BME_PF_7_0_CLR is 0x%x\n", val); + + val = REG_RD(bp, PGLUE_B_REG_FLR_REQUEST_PF_7_0_CLR); + DP(BNX2X_MSG_SP, "PGLUE_B_REG_FLR_REQUEST_PF_7_0_CLR is 0x%x\n", val); + + val = REG_RD(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER); + DP(BNX2X_MSG_SP, "PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER is 0x%x\n", + val); +} + +static int bnx2x_pf_flr_clnup(struct bnx2x *bp) +{ + u32 poll_cnt = bnx2x_flr_clnup_poll_count(bp); + + DP(BNX2X_MSG_SP, "Cleanup after FLR PF[%d]\n", BP_ABS_FUNC(bp)); + + /* Re-enable PF target read access */ + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); + + /* Poll HW usage counters */ + if (bnx2x_poll_hw_usage_counters(bp, poll_cnt)) + return -EBUSY; + + /* Zero the igu 'trailing edge' and 'leading edge' */ + + /* Send the FW cleanup command */ + if (bnx2x_send_final_clnup(bp, (u8)BP_FUNC(bp), poll_cnt)) + return -EBUSY; + + /* ATC cleanup */ + + /* Verify TX hw is flushed */ + bnx2x_tx_hw_flushed(bp, poll_cnt); + + /* Wait 100ms (not adjusted according to platform) */ + msleep(100); + + /* Verify no pending pci transactions */ + if (bnx2x_is_pcie_pending(bp->pdev)) + BNX2X_ERR("PCIE Transactions still pending\n"); + + /* Debug */ + bnx2x_hw_enable_status(bp); + + /* + * Master enable - Due to WB DMAE writes performed before this + * register is re-initialized as part of the regular function init + */ + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); + + return 0; +} + static void bnx2x_hc_int_enable(struct bnx2x *bp) { int port = BP_PORT(bp); @@ -1188,52 +1607,85 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) } #ifdef BCM_CNIC -static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid); +static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid, u8 err); #endif -void bnx2x_sp_event(struct bnx2x_fastpath *fp, - union eth_rx_cqe *rr_cqe) +void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) { struct bnx2x *bp = fp->bp; int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data); int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data); + enum bnx2x_queue_cmd drv_cmd = BNX2X_Q_CMD_MAX; + struct bnx2x_queue_sp_obj *q_obj = &fp->q_obj; DP(BNX2X_MSG_SP, "fp %d cid %d got ramrod #%d state is %x type is %d\n", fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.ramrod_type); - switch (command | fp->state) { - case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | BNX2X_FP_STATE_OPENING): + switch (command) { + case (RAMROD_CMD_ID_ETH_CLIENT_UPDATE): + DP(NETIF_MSG_IFUP, "got UPDATE ramrod. CID %d\n", cid); + drv_cmd = BNX2X_Q_CMD_UPDATE; + break; + case (RAMROD_CMD_ID_ETH_CLIENT_SETUP): DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", cid); - fp->state = BNX2X_FP_STATE_OPEN; + drv_cmd = BNX2X_Q_CMD_SETUP; break; - case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING): + case (RAMROD_CMD_ID_ETH_HALT): DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", cid); - fp->state = BNX2X_FP_STATE_HALTED; + drv_cmd = BNX2X_Q_CMD_HALT; break; - case (RAMROD_CMD_ID_ETH_TERMINATE | BNX2X_FP_STATE_TERMINATING): + case (RAMROD_CMD_ID_ETH_TERMINATE): DP(NETIF_MSG_IFDOWN, "got MULTI[%d] teminate ramrod\n", cid); - fp->state = BNX2X_FP_STATE_TERMINATED; + drv_cmd = BNX2X_Q_CMD_TERMINATE; break; - default: - BNX2X_ERR("unexpected MC reply (%d) " - "fp[%d] state is %x\n", - command, fp->index, fp->state); + case (RAMROD_CMD_ID_ETH_EMPTY): + DP(NETIF_MSG_IFDOWN, "got MULTI[%d] empty ramrod\n", cid); + drv_cmd = BNX2X_Q_CMD_EMPTY; break; + + default: + BNX2X_ERR("unexpected MC reply (%d) on fp[%d]\n", + command, fp->index); + return; } + if ((drv_cmd != BNX2X_Q_CMD_MAX) && + q_obj->complete_cmd(bp, q_obj, drv_cmd)) + /* q_obj->complete_cmd() failure means that this was + * an unexpected completion. + * + * In this case we don't want to increase the bp->spq_left + * because apparently we haven't sent this command the first + * place. + */ +#ifdef BNX2X_STOP_ON_ERROR + bnx2x_panic(); +#else + return; +#endif + smp_mb__before_atomic_inc(); atomic_inc(&bp->cq_spq_left); - /* push the change in fp->state and towards the memory */ - smp_wmb(); + /* push the change in bp->spq_left and towards the memory */ + smp_mb__after_atomic_inc(); return; } +void bnx2x_update_rx_prod(struct bnx2x *bp, struct bnx2x_fastpath *fp, + u16 bd_prod, u16 rx_comp_prod, u16 rx_sge_prod) +{ + u32 start = BAR_USTRORM_INTMEM + fp->ustorm_rx_prods_offset; + + bnx2x_update_rx_prod_gen(bp, fp, bd_prod, rx_comp_prod, rx_sge_prod, + start); +} + irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) { struct bnx2x *bp = netdev_priv(dev_instance); @@ -1258,7 +1710,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); if (status & mask) { - /* Handle Rx and Tx according to SB id */ + /* Handle Rx or Tx according to SB id */ prefetch(fp->rx_cons_sb); prefetch(fp->tx_cons_sb); prefetch(&fp->sb_running_index[SM_RX_ID]); @@ -1272,11 +1724,13 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) if (status & (mask | 0x1)) { struct cnic_ops *c_ops = NULL; - rcu_read_lock(); - c_ops = rcu_dereference(bp->cnic_ops); - if (c_ops) - c_ops->cnic_handler(bp->cnic_data, NULL); - rcu_read_unlock(); + if (likely(bp->state == BNX2X_STATE_OPEN)) { + rcu_read_lock(); + c_ops = rcu_dereference(bp->cnic_ops); + if (c_ops) + c_ops->cnic_handler(bp->cnic_data, NULL); + rcu_read_unlock(); + } status &= ~mask; } @@ -1297,9 +1751,6 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; } -/* end of fast path */ - - /* Link */ /* @@ -1939,11 +2390,11 @@ static void bnx2x_link_attn(struct bnx2x *bp) pause_enabled); } - if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { + if (bp->link_vars.mac_type != MAC_TYPE_EMAC) { struct host_port_stats *pstats; pstats = bnx2x_sp(bp, port_stats); - /* reset old bmac stats */ + /* reset old mac stats */ memset(&(pstats->mac_stx[0]), 0, sizeof(struct mac_stx)); } @@ -1998,7 +2449,7 @@ static void bnx2x_pmf_update(struct bnx2x *bp) if (bp->common.int_block == INT_BLOCK_HC) { REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); - } else if (CHIP_IS_E2(bp)) { + } else if (!CHIP_IS_E1x(bp)) { REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val); REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val); } @@ -2059,45 +2510,89 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) static u8 stat_counter_valid(struct bnx2x *bp, struct bnx2x_fastpath *fp) { #ifdef BCM_CNIC - if (IS_FCOE_FP(fp) && IS_MF(bp)) + /* Statistics are not supported for CNIC Clients at the moment */ + if (IS_FCOE_FP(fp)) return false; #endif return true; } -static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, - struct bnx2x_fastpath *fp) +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) +{ + if (CHIP_IS_E1x(bp)) { + struct tstorm_eth_function_common_config tcfg = {0}; + + storm_memset_func_cfg(bp, &tcfg, p->func_id); + } + + /* Enable the function in the FW */ + storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); + storm_memset_func_en(bp, p->func_id, 1); + + /* spq */ + if (p->func_flgs & FUNC_FLG_SPQ) { + storm_memset_spq_addr(bp, p->spq_map, p->func_id); + REG_WR(bp, XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); + } +} + +static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp, + struct bnx2x_fastpath *fp, + bool leading) { - u16 flags = 0; + unsigned long flags = 0; + + /* PF driver will always initialize the Queue to an ACTIVE state */ + __set_bit(BNX2X_Q_FLG_ACTIVE, &flags); - /* calculate queue flags */ - flags |= QUEUE_FLG_CACHE_ALIGN; - flags |= QUEUE_FLG_HC; - flags |= IS_MF_SD(bp) ? QUEUE_FLG_OV : 0; + /* calculate other queue flags */ + if (IS_MF_SD(bp)) + __set_bit(BNX2X_Q_FLG_OV, &flags); - flags |= QUEUE_FLG_VLAN; - DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); + if (IS_FCOE_FP(fp)) + __set_bit(BNX2X_Q_FLG_FCOE, &flags); if (!fp->disable_tpa) - flags |= QUEUE_FLG_TPA; + __set_bit(BNX2X_Q_FLG_TPA, &flags); + + if (stat_counter_valid(bp, fp)) { + __set_bit(BNX2X_Q_FLG_STATS, &flags); + __set_bit(BNX2X_Q_FLG_ZERO_STATS, &flags); + } + + if (leading) { + __set_bit(BNX2X_Q_FLG_LEADING_RSS, &flags); + __set_bit(BNX2X_Q_FLG_MCAST, &flags); + } - flags = stat_counter_valid(bp, fp) ? - (flags | QUEUE_FLG_STATS) : (flags & ~QUEUE_FLG_STATS); + /* Always set HW VLAN stripping */ + __set_bit(BNX2X_Q_FLG_VLAN, &flags); return flags; } -static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, +static void bnx2x_pf_q_prep_general(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct bnx2x_general_setup_params *gen_init) +{ + gen_init->stat_id = bnx2x_stats_id(fp); + gen_init->spcl_id = fp->cl_id; + + /* Always use mini-jumbo MTU for FCoE L2 ring */ + if (IS_FCOE_FP(fp)) + gen_init->mtu = BNX2X_FCOE_MINI_JUMBO_MTU; + else + gen_init->mtu = bp->dev->mtu; +} + +static void bnx2x_pf_rx_q_prep(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct rxq_pause_params *pause, - struct bnx2x_rxq_init_params *rxq_init) + struct bnx2x_rxq_setup_params *rxq_init) { - u16 max_sge = 0; + u8 max_sge = 0; u16 sge_sz = 0; u16 tpa_agg_size = 0; - /* calculate queue flags */ - u16 flags = bnx2x_get_cl_flags(bp, fp); - if (!fp->disable_tpa) { pause->sge_th_hi = 250; pause->sge_th_lo = 150; @@ -2118,33 +2613,37 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, pause->bd_th_lo = 250; pause->rcq_th_hi = 350; pause->rcq_th_lo = 250; - pause->sge_th_hi = 0; - pause->sge_th_lo = 0; + pause->pri_map = 1; } /* rxq setup */ - rxq_init->flags = flags; - rxq_init->cxt = &bp->context.vcxt[fp->cid].eth; rxq_init->dscr_map = fp->rx_desc_mapping; rxq_init->sge_map = fp->rx_sge_mapping; rxq_init->rcq_map = fp->rx_comp_mapping; rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE; - /* Always use mini-jumbo MTU for FCoE L2 ring */ - if (IS_FCOE_FP(fp)) - rxq_init->mtu = BNX2X_FCOE_MINI_JUMBO_MTU; - else - rxq_init->mtu = bp->dev->mtu; + /* This should be a maximum number of data bytes that may be + * placed on the BD (not including paddings). + */ + rxq_init->buf_sz = fp->rx_buf_size - BNX2X_FW_RX_ALIGN - + IP_HEADER_ALIGNMENT_PADDING; - rxq_init->buf_sz = fp->rx_buf_size; rxq_init->cl_qzone_id = fp->cl_qzone_id; - rxq_init->cl_id = fp->cl_id; - rxq_init->spcl_id = fp->cl_id; - rxq_init->stat_id = fp->cl_id; rxq_init->tpa_agg_sz = tpa_agg_size; rxq_init->sge_buf_sz = sge_sz; rxq_init->max_sges_pkt = max_sge; + rxq_init->rss_engine_id = BP_FUNC(bp); + + /* Maximum number or simultaneous TPA aggregation for this Queue. + * + * For PF Clients it should be the maximum avaliable number. + * VF driver(s) may want to define it to a smaller value. + */ + rxq_init->max_tpa_queues = + (CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : + ETH_MAX_AGGREGATION_QUEUES_E1H_E2); + rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT; rxq_init->fw_sb_id = fp->fw_sb_id; @@ -2152,46 +2651,35 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, rxq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS; else rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; - - rxq_init->cid = HW_CID(bp, fp->cid); - - rxq_init->hc_rate = bp->rx_ticks ? (1000000 / bp->rx_ticks) : 0; } -static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp, - struct bnx2x_fastpath *fp, struct bnx2x_txq_init_params *txq_init) +static void bnx2x_pf_tx_q_prep(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct bnx2x_txq_setup_params *txq_init) { - u16 flags = bnx2x_get_cl_flags(bp, fp); - - txq_init->flags = flags; - txq_init->cxt = &bp->context.vcxt[fp->cid].eth; txq_init->dscr_map = fp->tx_desc_mapping; - txq_init->stat_id = fp->cl_id; - txq_init->cid = HW_CID(bp, fp->cid); txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX; txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; txq_init->fw_sb_id = fp->fw_sb_id; + /* + * set the tss leading client id for TX classfication == + * leading RSS client id + */ + txq_init->tss_leading_cl_id = bnx2x_fp(bp, 0, cl_id); + if (IS_FCOE_FP(fp)) { txq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS; txq_init->traffic_type = LLFC_TRAFFIC_TYPE_FCOE; } - - txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0; } static void bnx2x_pf_init(struct bnx2x *bp) { struct bnx2x_func_init_params func_init = {0}; - struct bnx2x_rss_params rss = {0}; struct event_ring_data eq_data = { {0} }; u16 flags; - /* pf specific setups */ - if (!CHIP_IS_E1(bp)) - storm_memset_ov(bp, bp->mf_ov, BP_FUNC(bp)); - - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { /* reset IGU PF statistics: MSIX + ATTN */ /* PF */ REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + @@ -2209,27 +2697,14 @@ static void bnx2x_pf_init(struct bnx2x *bp) /* function setup flags */ flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); - if (CHIP_IS_E1x(bp)) - flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; - else - flags |= FUNC_FLG_TPA; - - /* function setup */ - - /** - * Although RSS is meaningless when there is a single HW queue we - * still need it enabled in order to have HW Rx hash generated. + /* This flag is relevant for E1x only. + * E2 doesn't have a TPA configuration in a function level. */ - rss.cap = (RSS_IPV4_CAP | RSS_IPV4_TCP_CAP | - RSS_IPV6_CAP | RSS_IPV6_TCP_CAP); - rss.mode = bp->multi_mode; - rss.result_mask = MULTI_MASK; - func_init.rss = &rss; + flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; func_init.func_flgs = flags; func_init.pf_id = BP_FUNC(bp); func_init.func_id = BP_FUNC(bp); - func_init.fw_stat_map = bnx2x_sp_mapping(bp, fw_stats); func_init.spq_map = bp->spq_mapping; func_init.spq_prod = bp->spq_prod_idx; @@ -2238,11 +2713,11 @@ static void bnx2x_pf_init(struct bnx2x *bp) memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); /* - Congestion management values depend on the link rate - There is no active link so initial link rate is set to 10 Gbps. - When the link comes up The congestion management values are - re-calculated according to the actual link rate. - */ + * Congestion management values depend on the link rate + * There is no active link so initial link rate is set to 10 Gbps. + * When the link comes up The congestion management values are + * re-calculated according to the actual link rate. + */ bp->link_vars.line_speed = SPEED_10000; bnx2x_cmng_fns_init(bp, true, bnx2x_get_cmng_fns_mode(bp)); @@ -2250,10 +2725,6 @@ static void bnx2x_pf_init(struct bnx2x *bp) if (bp->port.pmf) storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); - /* no rx until link is up */ - bp->rx_mode = BNX2X_RX_MODE_NONE; - bnx2x_set_storm_rx_mode(bp); - /* init Event Queue */ eq_data.base_addr.hi = U64_HI(bp->eq_mapping); eq_data.base_addr.lo = U64_LO(bp->eq_mapping); @@ -2268,11 +2739,9 @@ static void bnx2x_e1h_disable(struct bnx2x *bp) { int port = BP_PORT(bp); - netif_tx_disable(bp->dev); + bnx2x_tx_disable(bp); REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); - - netif_carrier_off(bp->dev); } static void bnx2x_e1h_enable(struct bnx2x *bp) @@ -2375,12 +2844,47 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) mmiowb(); } -/* the slow path queue is odd since completions arrive on the fastpath ring */ +/** + * bnx2x_is_contextless_ramrod - check if the current command ends on EQ + * + * @cmd: command to check + * @cmd_type: command type + */ +static inline bool bnx2x_is_contextless_ramrod(int cmd, int cmd_type) +{ + if ((cmd_type == NONE_CONNECTION_TYPE) || + (cmd == RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES) || + (cmd == RAMROD_CMD_ID_ETH_FILTER_RULES) || + (cmd == RAMROD_CMD_ID_ETH_MULTICAST_RULES) || + (cmd == RAMROD_CMD_ID_ETH_SET_MAC) || + (cmd == RAMROD_CMD_ID_ETH_RSS_UPDATE)) + return true; + else + return false; + +} + + +/** + * bnx2x_sp_post - place a single command on an SP ring + * + * @bp: driver handle + * @command: command to place (e.g. SETUP, FILTER_RULES, etc.) + * @cid: SW CID the command is related to + * @data_hi: command private data address (high 32 bits) + * @data_lo: command private data address (low 32 bits) + * @cmd_type: command type (e.g. NONE, ETH) + * + * SP data is handled as if it's always an address pair, thus data fields are + * not swapped to little endian in upper functions. Instead this function swaps + * data as if it's two u32 fields. + */ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common) + u32 data_hi, u32 data_lo, int cmd_type) { struct eth_spe *spe; u16 type; + bool common = bnx2x_is_contextless_ramrod(command, cmd_type); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -2410,17 +2914,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | HW_CID(bp, cid)); - if (common) - /* Common ramrods: - * FUNC_START, FUNC_STOP, CFC_DEL, STATS, SET_MAC - * TRAFFIC_STOP, TRAFFIC_START - */ - type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) - & SPE_HDR_CONN_TYPE; - else - /* ETH ramrods: SETUP, HALT */ - type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) - & SPE_HDR_CONN_TYPE; + type = (cmd_type << SPE_HDR_CONN_TYPE_SHIFT) & SPE_HDR_CONN_TYPE; type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) & SPE_HDR_FUNCTION_ID); @@ -2432,7 +2926,8 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, /* stats ramrod has it's own slot on the spq */ if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) { - /* It's ok if the actual decrement is issued towards the memory + /* + * It's ok if the actual decrement is issued towards the memory * somewhere between the spin_lock and spin_unlock. Thus no * more explict memory barrier is needed. */ @@ -2728,13 +3223,13 @@ static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) } if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { - val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); - BNX2X_ERR("PXP hw attention 0x%x\n", val); + BNX2X_ERR("PXP hw attention-0 0x%x\n", val); /* RQ_USDMDP_FIFO_OVERFLOW */ if (val & 0x18000) BNX2X_ERR("FATAL error from PXP\n"); - if (CHIP_IS_E2(bp)) { + + if (!CHIP_IS_E1x(bp)) { val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_1); BNX2X_ERR("PXP hw attention-1 0x%x\n", val); } @@ -3224,7 +3719,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4); attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) attn.sig[4] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 + port*4); else @@ -3320,6 +3815,15 @@ static void bnx2x_attn_int(struct bnx2x *bp) bnx2x_attn_int_deasserted(bp, deasserted); } +void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, + u16 index, u8 op, u8 update) +{ + u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8; + + bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update, + igu_addr); +} + static inline void bnx2x_update_eq_prod(struct bnx2x *bp, u16 prod) { /* No memory barriers */ @@ -3331,6 +3835,8 @@ static inline void bnx2x_update_eq_prod(struct bnx2x *bp, u16 prod) static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, union event_ring_elem *elem) { + u8 err = elem->message.error; + if (!bp->cnic_eth_dev.starting_cid || (cid < bp->cnic_eth_dev.starting_cid && cid != bp->cnic_eth_dev.iscsi_l2_cid)) @@ -3338,16 +3844,122 @@ static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, DP(BNX2X_MSG_SP, "got delete ramrod for CNIC CID %d\n", cid); - if (unlikely(elem->message.data.cfc_del_event.error)) { + if (unlikely(err)) { + BNX2X_ERR("got delete ramrod for CNIC CID %d with error!\n", cid); bnx2x_panic_dump(bp); } - bnx2x_cnic_cfc_comp(bp, cid); + bnx2x_cnic_cfc_comp(bp, cid, err); return 0; } #endif +static inline void bnx2x_handle_mcast_eqe(struct bnx2x *bp) +{ + struct bnx2x_mcast_ramrod_params rparam; + int rc; + + memset(&rparam, 0, sizeof(rparam)); + + rparam.mcast_obj = &bp->mcast_obj; + + netif_addr_lock_bh(bp->dev); + + /* Clear pending state for the last command */ + bp->mcast_obj.raw.clear_pending(&bp->mcast_obj.raw); + + /* If there are pending mcast commands - send them */ + if (bp->mcast_obj.check_pending(&bp->mcast_obj)) { + rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_CONT); + if (rc < 0) + BNX2X_ERR("Failed to send pending mcast commands: %d\n", + rc); + } + + netif_addr_unlock_bh(bp->dev); +} + +static inline void bnx2x_handle_classification_eqe(struct bnx2x *bp, + union event_ring_elem *elem) +{ + unsigned long ramrod_flags = 0; + int rc = 0; + u32 cid = elem->message.data.eth_event.echo & BNX2X_SWCID_MASK; + struct bnx2x_vlan_mac_obj *vlan_mac_obj; + + /* Always push next commands out, don't wait here */ + __set_bit(RAMROD_CONT, &ramrod_flags); + + switch (elem->message.data.eth_event.echo >> BNX2X_SWCID_SHIFT) { + case BNX2X_FILTER_MAC_PENDING: +#ifdef BCM_CNIC + if (cid == BNX2X_ISCSI_ETH_CID) + vlan_mac_obj = &bp->iscsi_l2_mac_obj; + else +#endif + vlan_mac_obj = &bp->fp[cid].mac_obj; + + break; + vlan_mac_obj = &bp->fp[cid].mac_obj; + + case BNX2X_FILTER_MCAST_PENDING: + /* This is only relevant for 57710 where multicast MACs are + * configured as unicast MACs using the same ramrod. + */ + bnx2x_handle_mcast_eqe(bp); + return; + default: + BNX2X_ERR("Unsupported classification command: %d\n", + elem->message.data.eth_event.echo); + return; + } + + rc = vlan_mac_obj->complete(bp, vlan_mac_obj, elem, &ramrod_flags); + + if (rc < 0) + BNX2X_ERR("Failed to schedule new commands: %d\n", rc); + else if (rc > 0) + DP(BNX2X_MSG_SP, "Scheduled next pending commands...\n"); + +} + +#ifdef BCM_CNIC +static void bnx2x_set_iscsi_eth_rx_mode(struct bnx2x *bp, bool start); +#endif + +static inline void bnx2x_handle_rx_mode_eqe(struct bnx2x *bp) +{ + netif_addr_lock_bh(bp->dev); + + clear_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state); + + /* Send rx_mode command again if was requested */ + if (test_and_clear_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state)) + bnx2x_set_storm_rx_mode(bp); +#ifdef BCM_CNIC + else if (test_and_clear_bit(BNX2X_FILTER_ISCSI_ETH_START_SCHED, + &bp->sp_state)) + bnx2x_set_iscsi_eth_rx_mode(bp, true); + else if (test_and_clear_bit(BNX2X_FILTER_ISCSI_ETH_STOP_SCHED, + &bp->sp_state)) + bnx2x_set_iscsi_eth_rx_mode(bp, false); +#endif + + netif_addr_unlock_bh(bp->dev); +} + +static inline struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj( + struct bnx2x *bp, u32 cid) +{ +#ifdef BCM_CNIC + if (cid == BNX2X_FCOE_ETH_CID) + return &bnx2x_fcoe(bp, q_obj); + else +#endif + return &bnx2x_fp(bp, cid, q_obj); +} + static void bnx2x_eq_int(struct bnx2x *bp) { u16 hw_cons, sw_cons, sw_prod; @@ -3355,6 +3967,9 @@ static void bnx2x_eq_int(struct bnx2x *bp) u32 cid; u8 opcode; int spqe_cnt = 0; + struct bnx2x_queue_sp_obj *q_obj; + struct bnx2x_func_sp_obj *f_obj = &bp->func_obj; + struct bnx2x_raw_obj *rss_raw = &bp->rss_conf_obj.raw; hw_cons = le16_to_cpu(*bp->eq_cons_sb); @@ -3389,7 +4004,8 @@ static void bnx2x_eq_int(struct bnx2x *bp) /* handle eq element */ switch (opcode) { case EVENT_RING_OPCODE_STAT_QUERY: - DP(NETIF_MSG_TIMER, "got statistics comp event\n"); + DP(NETIF_MSG_TIMER, "got statistics comp event %d\n", + bp->stats_comp++); /* nothing to do with stats comp */ continue; @@ -3404,12 +4020,13 @@ static void bnx2x_eq_int(struct bnx2x *bp) #ifdef BCM_CNIC if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem)) goto next_spqe; - if (cid == BNX2X_FCOE_ETH_CID) - bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED; - else #endif - bnx2x_fp(bp, cid, state) = - BNX2X_FP_STATE_CLOSED; + q_obj = bnx2x_cid_to_q_obj(bp, cid); + + if (q_obj->complete_cmd(bp, q_obj, BNX2X_Q_CMD_CFC_DEL)) + break; + + goto next_spqe; @@ -3417,42 +4034,75 @@ static void bnx2x_eq_int(struct bnx2x *bp) DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n"); bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); goto next_spqe; + case EVENT_RING_OPCODE_START_TRAFFIC: DP(NETIF_MSG_IFUP, "got START TRAFFIC\n"); bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); goto next_spqe; + case EVENT_RING_OPCODE_FUNCTION_START: + DP(NETIF_MSG_IFUP, "got FUNC_START ramrod\n"); + if (f_obj->complete_cmd(bp, f_obj, BNX2X_F_CMD_START)) + break; + + goto next_spqe; + + case EVENT_RING_OPCODE_FUNCTION_STOP: + DP(NETIF_MSG_IFDOWN, "got FUNC_STOP ramrod\n"); + if (f_obj->complete_cmd(bp, f_obj, BNX2X_F_CMD_STOP)) + break; + + goto next_spqe; } switch (opcode | bp->state) { - case (EVENT_RING_OPCODE_FUNCTION_START | + case (EVENT_RING_OPCODE_RSS_UPDATE_RULES | + BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_RSS_UPDATE_RULES | BNX2X_STATE_OPENING_WAIT4_PORT): - DP(NETIF_MSG_IFUP, "got setup ramrod\n"); - bp->state = BNX2X_STATE_FUNC_STARTED; + cid = elem->message.data.eth_event.echo & + BNX2X_SWCID_MASK; + DP(NETIF_MSG_IFUP, "got RSS_UPDATE ramrod. CID %d\n", + cid); + rss_raw->clear_pending(rss_raw); break; - case (EVENT_RING_OPCODE_FUNCTION_STOP | + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG): + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got halt ramrod\n"); - bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + case (EVENT_RING_OPCODE_CLASSIFICATION_RULES | + BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_CLASSIFICATION_RULES | + BNX2X_STATE_DIAG): + case (EVENT_RING_OPCODE_CLASSIFICATION_RULES | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n"); + bnx2x_handle_classification_eqe(bp, elem); break; - case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN): - case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG): - DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); - if (elem->message.data.set_mac_event.echo) - bp->set_mac_pending = 0; + case (EVENT_RING_OPCODE_MULTICAST_RULES | + BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_MULTICAST_RULES | + BNX2X_STATE_DIAG): + case (EVENT_RING_OPCODE_MULTICAST_RULES | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFUP, "got mcast ramrod\n"); + bnx2x_handle_mcast_eqe(bp); break; - case (EVENT_RING_OPCODE_SET_MAC | + case (EVENT_RING_OPCODE_FILTERS_RULES | + BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_FILTERS_RULES | + BNX2X_STATE_DIAG): + case (EVENT_RING_OPCODE_FILTERS_RULES | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); - if (elem->message.data.set_mac_event.echo) - bp->set_mac_pending = 0; + DP(NETIF_MSG_IFUP, "got rx_mode ramrod\n"); + bnx2x_handle_rx_mode_eqe(bp); break; default: /* unknown event log error and continue */ - BNX2X_ERR("Unknown EQ event %d\n", - elem->message.opcode); + BNX2X_ERR("Unknown EQ event %d, bp->state 0x%x\n", + elem->message.opcode, bp->state); } next_spqe: spqe_cnt++; @@ -3544,6 +4194,14 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) /* end of slow path */ + +void bnx2x_drv_pulse(struct bnx2x *bp) +{ + SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb, + bp->fw_drv_pulse_wr_seq); +} + + static void bnx2x_timer(unsigned long data) { struct bnx2x *bp = (struct bnx2x *) data; @@ -3567,7 +4225,7 @@ static void bnx2x_timer(unsigned long data) bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; /* TBD - add SYSTEM_TIME */ drv_pulse = bp->fw_drv_pulse_wr_seq; - SHMEM_WR(bp, func_mb[mb_idx].drv_pulse_mb, drv_pulse); + bnx2x_drv_pulse(bp); mcp_pulse = (SHMEM_RD(bp, func_mb[mb_idx].mcp_pulse_mb) & MCP_PULSE_SEQ_MASK); @@ -3630,18 +4288,16 @@ static inline void bnx2x_zero_fp_sb(struct bnx2x *bp, int fw_sb_id) struct hc_status_block_data_e1x sb_data_e1x; /* disable the function first */ - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); - sb_data_e2.common.p_func.pf_id = HC_FUNCTION_DISABLED; - sb_data_e2.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e2.common.state = SB_DISABLED; sb_data_e2.common.p_func.vf_valid = false; sb_data_p = (u32 *)&sb_data_e2; data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); } else { memset(&sb_data_e1x, 0, sizeof(struct hc_status_block_data_e1x)); - sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; - sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.state = SB_DISABLED; sb_data_e1x.common.p_func.vf_valid = false; sb_data_p = (u32 *)&sb_data_e1x; data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); @@ -3675,8 +4331,7 @@ static inline void bnx2x_zero_sp_sb(struct bnx2x *bp) struct hc_sp_status_block_data sp_sb_data; memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); - sp_sb_data.p_func.pf_id = HC_FUNCTION_DISABLED; - sp_sb_data.p_func.vf_id = HC_FUNCTION_DISABLED; + sp_sb_data.state = SB_DISABLED; sp_sb_data.p_func.vf_valid = false; bnx2x_wr_sp_sb_data(bp, &sp_sb_data); @@ -3719,8 +4374,9 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, bnx2x_zero_fp_sb(bp, fw_sb_id); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); + sb_data_e2.common.state = SB_ENABLED; sb_data_e2.common.p_func.pf_id = BP_FUNC(bp); sb_data_e2.common.p_func.vf_id = vfid; sb_data_e2.common.p_func.vf_valid = vf_valid; @@ -3734,6 +4390,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, } else { memset(&sb_data_e1x, 0, sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.state = SB_ENABLED; sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); sb_data_e1x.common.p_func.vf_id = 0xff; sb_data_e1x.common.p_func.vf_valid = false; @@ -3757,19 +4414,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); } -void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, - u8 sb_index, u8 disable, u16 usec) -{ - int port = BP_PORT(bp); - u8 ticks = usec / BNX2X_BTR; - - storm_memset_hc_timeout(bp, port, fw_sb_id, sb_index, ticks); - - disable = disable ? 1 : (usec ? 0 : 1); - storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable); -} - -static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u16 fw_sb_id, +static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u8 fw_sb_id, u16 tx_usec, u16 rx_usec) { bnx2x_update_coalesce_sb_index(bp, fw_sb_id, U_SB_ETH_RX_CQ_INDEX, @@ -3816,7 +4461,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) bp->attn_group[index].sig[sindex] = REG_RD(bp, reg_offset + sindex*0x4 + 0x10*index); - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) /* * enable5 is separate from the rest of the registers, * and therefore the address skip is 4 @@ -3834,7 +4479,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) REG_WR(bp, reg_offset, U64_LO(section)); REG_WR(bp, reg_offset + 4, U64_HI(section)); - } else if (CHIP_IS_E2(bp)) { + } else if (!CHIP_IS_E1x(bp)) { REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_L, U64_LO(section)); REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_H, U64_HI(section)); } @@ -3844,6 +4489,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) bnx2x_zero_sp_sb(bp); + sp_sb_data.state = SB_ENABLED; sp_sb_data.host_sb_addr.lo = U64_LO(section); sp_sb_data.host_sb_addr.hi = U64_HI(section); sp_sb_data.igu_sb_id = igu_sp_sb_index; @@ -3854,9 +4500,6 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) bnx2x_wr_sp_sb_data(bp, &sp_sb_data); - bp->stats_pending = 0; - bp->set_mac_pending = 0; - bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); } @@ -3902,34 +4545,129 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp) min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1); } -static void bnx2x_init_ind_table(struct bnx2x *bp) + +/* called with netif_addr_lock_bh() */ +void bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, + unsigned long rx_mode_flags, + unsigned long rx_accept_flags, + unsigned long tx_accept_flags, + unsigned long ramrod_flags) { - int i; + struct bnx2x_rx_mode_ramrod_params ramrod_param; + int rc; + + memset(&ramrod_param, 0, sizeof(ramrod_param)); + + /* Prepare ramrod parameters */ + ramrod_param.cid = 0; + ramrod_param.cl_id = cl_id; + ramrod_param.rx_mode_obj = &bp->rx_mode_obj; + ramrod_param.func_id = BP_FUNC(bp); - for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) - bp->rx_indir_table[i] = i % BNX2X_NUM_ETH_QUEUES(bp); + ramrod_param.pstate = &bp->sp_state; + ramrod_param.state = BNX2X_FILTER_RX_MODE_PENDING; - bnx2x_push_indir_table(bp); + ramrod_param.rdata = bnx2x_sp(bp, rx_mode_rdata); + ramrod_param.rdata_mapping = bnx2x_sp_mapping(bp, rx_mode_rdata); + + set_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state); + + ramrod_param.ramrod_flags = ramrod_flags; + ramrod_param.rx_mode_flags = rx_mode_flags; + + ramrod_param.rx_accept_flags = rx_accept_flags; + ramrod_param.tx_accept_flags = tx_accept_flags; + + rc = bnx2x_config_rx_mode(bp, &ramrod_param); + if (rc < 0) { + BNX2X_ERR("Set rx_mode %d failed\n", bp->rx_mode); + return; + } } -static void bnx2x_init_internal_common(struct bnx2x *bp) +/* called with netif_addr_lock_bh() */ +void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { - int i; + unsigned long rx_mode_flags = 0, ramrod_flags = 0; + unsigned long rx_accept_flags = 0, tx_accept_flags = 0; - if (!CHIP_IS_E1(bp)) { +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) + + /* Configure rx_mode of FCoE Queue */ + __set_bit(BNX2X_RX_MODE_FCOE_ETH, &rx_mode_flags); +#endif + + switch (bp->rx_mode) { + case BNX2X_RX_MODE_NONE: + /* + * 'drop all' supersedes any accept flags that may have been + * passed to the function. + */ + break; + case BNX2X_RX_MODE_NORMAL: + __set_bit(BNX2X_ACCEPT_UNICAST, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_MULTICAST, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_BROADCAST, &rx_accept_flags); + + /* internal switching mode */ + __set_bit(BNX2X_ACCEPT_UNICAST, &tx_accept_flags); + __set_bit(BNX2X_ACCEPT_MULTICAST, &tx_accept_flags); + __set_bit(BNX2X_ACCEPT_BROADCAST, &tx_accept_flags); + + break; + case BNX2X_RX_MODE_ALLMULTI: + __set_bit(BNX2X_ACCEPT_UNICAST, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_ALL_MULTICAST, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_BROADCAST, &rx_accept_flags); + + /* internal switching mode */ + __set_bit(BNX2X_ACCEPT_UNICAST, &tx_accept_flags); + __set_bit(BNX2X_ACCEPT_ALL_MULTICAST, &tx_accept_flags); + __set_bit(BNX2X_ACCEPT_BROADCAST, &tx_accept_flags); + + break; + case BNX2X_RX_MODE_PROMISC: + /* According to deffinition of SI mode, iface in promisc mode + * should receive matched and unmatched (in resolution of port) + * unicast packets. + */ + __set_bit(BNX2X_ACCEPT_UNMATCHED, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_UNICAST, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_ALL_MULTICAST, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_BROADCAST, &rx_accept_flags); + + /* internal switching mode */ + __set_bit(BNX2X_ACCEPT_ALL_MULTICAST, &tx_accept_flags); + __set_bit(BNX2X_ACCEPT_BROADCAST, &tx_accept_flags); + + if (IS_MF_SI(bp)) + __set_bit(BNX2X_ACCEPT_ALL_UNICAST, &tx_accept_flags); + else + __set_bit(BNX2X_ACCEPT_UNICAST, &tx_accept_flags); + + break; + default: + BNX2X_ERR("Unknown rx_mode: %d\n", bp->rx_mode); + return; + } - /* xstorm needs to know whether to add ovlan to packets or not, - * in switch-independent we'll write 0 to here... */ - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, - bp->mf_mode); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, - bp->mf_mode); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, - bp->mf_mode); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, - bp->mf_mode); + if (bp->rx_mode != BNX2X_RX_MODE_NONE) { + __set_bit(BNX2X_ACCEPT_ANY_VLAN, &rx_accept_flags); + __set_bit(BNX2X_ACCEPT_ANY_VLAN, &tx_accept_flags); } + __set_bit(RAMROD_RX, &ramrod_flags); + __set_bit(RAMROD_TX, &ramrod_flags); + + bnx2x_set_q_rx_mode(bp, bp->fp->cl_id, rx_mode_flags, rx_accept_flags, + tx_accept_flags, ramrod_flags); +} + +static void bnx2x_init_internal_common(struct bnx2x *bp) +{ + int i; + if (IS_MF_SI(bp)) /* * In switch independent mode, the TSTORM needs to accept @@ -3938,25 +4676,22 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) */ REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 2); + else if (!CHIP_IS_E1(bp)) /* 57710 doesn't support MF */ + REG_WR8(bp, BAR_TSTRORM_INTMEM + + TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 0); /* Zero this manually as its initialization is currently missing in the initTool */ for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_AGG_DATA_OFFSET + i * 4, 0); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_IGU_MODE_OFFSET, CHIP_INT_MODE_IS_BC(bp) ? HC_IGU_BC_MODE : HC_IGU_NBC_MODE); } } -static void bnx2x_init_internal_port(struct bnx2x *bp) -{ - /* port */ - bnx2x_dcb_init_intmem_pfc(bp); -} - static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) { switch (load_code) { @@ -3966,7 +4701,7 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) /* no break */ case FW_MSG_CODE_DRV_LOAD_PORT: - bnx2x_init_internal_port(bp); + /* nothing to do */ /* no break */ case FW_MSG_CODE_DRV_LOAD_FUNCTION: @@ -3980,31 +4715,57 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) } } -static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx) +static inline u8 bnx2x_fp_igu_sb_id(struct bnx2x_fastpath *fp) { - struct bnx2x_fastpath *fp = &bp->fp[fp_idx]; + return fp->bp->igu_base_sb + fp->index + CNIC_CONTEXT_USE; +} - fp->state = BNX2X_FP_STATE_CLOSED; +static inline u8 bnx2x_fp_fw_sb_id(struct bnx2x_fastpath *fp) +{ + return fp->bp->base_fw_ndsb + fp->index + CNIC_CONTEXT_USE; +} + +static inline u8 bnx2x_fp_cl_id(struct bnx2x_fastpath *fp) +{ + if (CHIP_IS_E1x(fp->bp)) + return BP_L_ID(fp->bp) + fp->index; + else /* We want Client ID to be the same as IGU SB ID for 57712 */ + return bnx2x_fp_igu_sb_id(fp); +} + +static void bnx2x_init_fp(struct bnx2x *bp, int fp_idx) +{ + struct bnx2x_fastpath *fp = &bp->fp[fp_idx]; + unsigned long q_type = 0; fp->cid = fp_idx; - fp->cl_id = BP_L_ID(bp) + fp_idx; - fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE; - fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; + fp->cl_id = bnx2x_fp_cl_id(fp); + fp->fw_sb_id = bnx2x_fp_fw_sb_id(fp); + fp->igu_sb_id = bnx2x_fp_igu_sb_id(fp); /* qZone id equals to FW (per path) client id */ - fp->cl_qzone_id = fp->cl_id + - BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 : - ETH_MAX_RX_CLIENTS_E1H); + fp->cl_qzone_id = bnx2x_fp_qzone_id(fp); + /* init shortcut */ - fp->ustorm_rx_prods_offset = CHIP_IS_E2(bp) ? - USTORM_RX_PRODS_E2_OFFSET(fp->cl_qzone_id) : - USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); + fp->ustorm_rx_prods_offset = bnx2x_rx_ustorm_prods_offset(fp); /* Setup SB indicies */ fp->rx_cons_sb = BNX2X_RX_SB_INDEX; fp->tx_cons_sb = BNX2X_TX_SB_INDEX; + /* Configure Queue State object */ + __set_bit(BNX2X_Q_TYPE_HAS_RX, &q_type); + __set_bit(BNX2X_Q_TYPE_HAS_TX, &q_type); + bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, fp->cid, BP_FUNC(bp), + bnx2x_sp(bp, q_rdata), bnx2x_sp_mapping(bp, q_rdata), + q_type); + + /** + * Configure classification DBs: Always enable Tx switching + */ + bnx2x_init_vlan_mac_fp_objs(fp, BNX2X_OBJ_TYPE_RX_TX); + DP(NETIF_MSG_IFUP, "queue[%d]: bnx2x_init_sb(%p,%p) " "cl_id %d fw_sb %d igu_sb %d\n", - fp_idx, bp, fp->status_blk.e1x_sb, fp->cl_id, fp->fw_sb_id, + fp_idx, bp, fp->status_blk.e2_sb, fp->cl_id, fp->fw_sb_id, fp->igu_sb_id); bnx2x_init_sb(bp, fp->status_blk_mapping, BNX2X_VF_ID_INVALID, false, fp->fw_sb_id, fp->igu_sb_id); @@ -4017,14 +4778,14 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) int i; for_each_eth_queue(bp, i) - bnx2x_init_fp_sb(bp, i); + bnx2x_init_fp(bp, i); #ifdef BCM_CNIC if (!NO_FCOE(bp)) bnx2x_init_fcoe_fp(bp); bnx2x_init_sb(bp, bp->cnic_sb_mapping, BNX2X_VF_ID_INVALID, false, - CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); + bnx2x_cnic_fw_sb_id(bp), bnx2x_cnic_igu_sb_id(bp)); #endif @@ -4043,7 +4804,6 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) bnx2x_init_eq_ring(bp); bnx2x_init_internal(bp, load_code); bnx2x_pf_init(bp); - bnx2x_init_ind_table(bp); bnx2x_stats_init(bp); /* flush all before enabling interrupts */ @@ -4249,8 +5009,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) msleep(50); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); msleep(50); - bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_BRB1, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_PRS, PHASE_COMMON); DP(NETIF_MSG_HW, "part2\n"); @@ -4314,8 +5074,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) msleep(50); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); msleep(50); - bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_BRB1, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_PRS, PHASE_COMMON); #ifndef BCM_CNIC /* set NIC mode */ REG_WR(bp, PRS_REG_NIC_MODE, 1); @@ -4335,7 +5095,7 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) static void bnx2x_enable_blocks_attention(struct bnx2x *bp) { REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0x40); else REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); @@ -4369,7 +5129,7 @@ static void bnx2x_enable_blocks_attention(struct bnx2x *bp) if (CHIP_REV_IS_FPGA(bp)) REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); - else if (CHIP_IS_E2(bp)) + else if (!CHIP_IS_E1x(bp)) REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, (PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF | PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT @@ -4382,7 +5142,11 @@ static void bnx2x_enable_blocks_attention(struct bnx2x *bp) REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0); REG_WR(bp, TCM_REG_TCM_INT_MASK, 0); /* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */ -/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */ + + if (!CHIP_IS_E1x(bp)) + /* enable VFC attentions: bits 11 and 12, bits 31:13 reserved */ + REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0x07ff); + REG_WR(bp, CDU_REG_CDU_INT_MASK, 0); REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0); /* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */ @@ -4391,10 +5155,24 @@ static void bnx2x_enable_blocks_attention(struct bnx2x *bp) static void bnx2x_reset_common(struct bnx2x *bp) { + u32 val = 0x1400; + /* reset_common */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0xd3ffff7f); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403); + + if (CHIP_IS_E3(bp)) { + val |= MISC_REGISTERS_RESET_REG_2_MSTAT0; + val |= MISC_REGISTERS_RESET_REG_2_MSTAT1; + } + + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, val); +} + +static void bnx2x_setup_dmae(struct bnx2x *bp) +{ + bp->dmae_ready = 0; + spin_lock_init(&bp->dmae_lock); } static void bnx2x_init_pxp(struct bnx2x *bp) @@ -4521,22 +5299,48 @@ static void bnx2x_pf_disable(struct bnx2x *bp) REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 0); } -static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) +static inline void bnx2x__common_init_phy(struct bnx2x *bp) +{ + u32 shmem_base[2], shmem2_base[2]; + shmem_base[0] = bp->common.shmem_base; + shmem2_base[0] = bp->common.shmem2_base; + if (!CHIP_IS_E1x(bp)) { + shmem_base[1] = + SHMEM2_RD(bp, other_shmem_base_addr); + shmem2_base[1] = + SHMEM2_RD(bp, other_shmem2_base_addr); + } + bnx2x_acquire_phy_lock(bp); + bnx2x_common_init_phy(bp, shmem_base, shmem2_base, + bp->common.chip_id); + bnx2x_release_phy_lock(bp); +} + +/** + * bnx2x_init_hw_common - initialize the HW at the COMMON phase. + * + * @bp: driver handle + */ +static int bnx2x_init_hw_common(struct bnx2x *bp) { - u32 val, i; + u32 val; DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_ABS_FUNC(bp)); bnx2x_reset_common(bp); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); - bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); - if (!CHIP_IS_E1(bp)) - REG_WR(bp, MISC_REG_E1HMF_MODE, IS_MF(bp)); + val = 0xfffc; + if (CHIP_IS_E3(bp)) { + val |= MISC_REGISTERS_RESET_REG_2_MSTAT0; + val |= MISC_REGISTERS_RESET_REG_2_MSTAT1; + } + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, val); + + bnx2x_init_block(bp, BLOCK_MISC, PHASE_COMMON); - if (CHIP_IS_E2(bp)) { - u8 fid; + if (!CHIP_IS_E1x(bp)) { + u8 abs_func_id; /** * 4-port mode or 2-port mode we need to turn of master-enable @@ -4545,29 +5349,30 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) * for all functions on the given path, this means 0,2,4,6 for * path 0 and 1,3,5,7 for path 1 */ - for (fid = BP_PATH(bp); fid < E2_FUNC_MAX*2; fid += 2) { - if (fid == BP_ABS_FUNC(bp)) { + for (abs_func_id = BP_PATH(bp); + abs_func_id < E2_FUNC_MAX*2; abs_func_id += 2) { + if (abs_func_id == BP_ABS_FUNC(bp)) { REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); continue; } - bnx2x_pretend_func(bp, fid); + bnx2x_pretend_func(bp, abs_func_id); /* clear pf enable */ bnx2x_pf_disable(bp); bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); } } - bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_PXP, PHASE_COMMON); if (CHIP_IS_E1(bp)) { /* enable HW interrupt from PXP on USDM overflow bit 16 on INT_MASK_0 */ REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); } - bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_PXP2, PHASE_COMMON); bnx2x_init_pxp(bp); #ifdef __BIG_ENDIAN @@ -4610,7 +5415,69 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) * This needs to be done by the first PF that is loaded in a path * (i.e. common phase) */ - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { +/* In E2 there is a bug in the timers block that can cause function 6 / 7 + * (i.e. vnic3) to start even if it is marked as "scan-off". + * This occurs when a different function (func2,3) is being marked + * as "scan-off". Real-life scenario for example: if a driver is being + * load-unloaded while func6,7 are down. This will cause the timer to access + * the ilt, translate to a logical address and send a request to read/write. + * Since the ilt for the function that is down is not valid, this will cause + * a translation error which is unrecoverable. + * The Workaround is intended to make sure that when this happens nothing fatal + * will occur. The workaround: + * 1. First PF driver which loads on a path will: + * a. After taking the chip out of reset, by using pretend, + * it will write "0" to the following registers of + * the other vnics. + * REG_WR(pdev, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0); + * REG_WR(pdev, CFC_REG_WEAK_ENABLE_PF,0); + * REG_WR(pdev, CFC_REG_STRONG_ENABLE_PF,0); + * And for itself it will write '1' to + * PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER to enable + * dmae-operations (writing to pram for example.) + * note: can be done for only function 6,7 but cleaner this + * way. + * b. Write zero+valid to the entire ILT. + * c. Init the first_timers_ilt_entry, last_timers_ilt_entry of + * VNIC3 (of that port). The range allocated will be the + * entire ILT. This is needed to prevent ILT range error. + * 2. Any PF driver load flow: + * a. ILT update with the physical addresses of the allocated + * logical pages. + * b. Wait 20msec. - note that this timeout is needed to make + * sure there are no requests in one of the PXP internal + * queues with "old" ILT addresses. + * c. PF enable in the PGLC. + * d. Clear the was_error of the PF in the PGLC. (could have + * occured while driver was down) + * e. PF enable in the CFC (WEAK + STRONG) + * f. Timers scan enable + * 3. PF driver unload flow: + * a. Clear the Timers scan_en. + * b. Polling for scan_on=0 for that PF. + * c. Clear the PF enable bit in the PXP. + * d. Clear the PF enable in the CFC (WEAK + STRONG) + * e. Write zero+valid to all ILT entries (The valid bit must + * stay set) + * f. If this is VNIC 3 of a port then also init + * first_timers_ilt_entry to zero and last_timers_ilt_entry + * to the last enrty in the ILT. + * + * Notes: + * Currently the PF error in the PGLC is non recoverable. + * In the future the there will be a recovery routine for this error. + * Currently attention is masked. + * Having an MCP lock on the load/unload process does not guarantee that + * there is no Timer disable during Func6/7 enable. This is because the + * Timers scan is currently being cleared by the MCP on FLR. + * Step 2.d can be done only for PF6/7 and the driver can also check if + * there is error before clearing it. But the flow above is simpler and + * more general. + * All ILT entries are written by zero+valid and not just PF6/7 + * ILT entries since in the future the ILT entries allocation for + * PF-s might be dynamic. + */ struct ilt_client_info ilt_cli; struct bnx2x_ilt ilt; memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); @@ -4624,7 +5491,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) /* Step 1: set zeroes to all ilt page entries with valid bit on * Step 2: set the timers first/last ilt entry to point * to the entire range to prevent ILT range error for 3rd/4th - * vnic (this code assumes existence of the vnic) + * vnic (this code assumes existance of the vnic) * * both steps performed by call to bnx2x_ilt_client_init_op() * with dummy TM client @@ -4645,12 +5512,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { int factor = CHIP_REV_IS_EMUL(bp) ? 1000 : (CHIP_REV_IS_FPGA(bp) ? 400 : 0); - bnx2x_init_block(bp, PGLUE_B_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_PGLUE_B, PHASE_COMMON); - bnx2x_init_block(bp, ATC_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_ATC, PHASE_COMMON); /* let the HW do it's magic ... */ do { @@ -4664,26 +5531,27 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) } } - bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_DMAE, PHASE_COMMON); /* clean the DMAE memory */ bp->dmae_ready = 1; - bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8); + bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8, 1); + + bnx2x_init_block(bp, BLOCK_TCM, PHASE_COMMON); + + bnx2x_init_block(bp, BLOCK_UCM, PHASE_COMMON); + + bnx2x_init_block(bp, BLOCK_CCM, PHASE_COMMON); - bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_XCM, PHASE_COMMON); bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3); bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3); bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3); bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3); - bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_QM, PHASE_COMMON); - if (CHIP_MODE_IS_4_PORT(bp)) - bnx2x_init_block(bp, QM_4PORT_BLOCK, COMMON_STAGE); /* QM queues pointers table */ bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); @@ -4693,57 +5561,51 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, QM_REG_SOFT_RESET, 0); #ifdef BCM_CNIC - bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_TM, PHASE_COMMON); #endif - bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_DORQ, PHASE_COMMON); REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT); - - if (!CHIP_REV_IS_SLOW(bp)) { + if (!CHIP_REV_IS_SLOW(bp)) /* enable hw interrupt from doorbell Q */ REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); - } - bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); - if (CHIP_MODE_IS_4_PORT(bp)) { - REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD, 248); - REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD, 328); - } + bnx2x_init_block(bp, BLOCK_BRB1, PHASE_COMMON); - bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_PRS, PHASE_COMMON); REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); -#ifndef BCM_CNIC - /* set NIC mode */ - REG_WR(bp, PRS_REG_NIC_MODE, 1); -#endif + if (!CHIP_IS_E1(bp)) - REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF_SD(bp)); + REG_WR(bp, PRS_REG_E1HOV_MODE, bp->path_has_ovlan); - if (CHIP_IS_E2(bp)) { - /* Bit-map indicating which L2 hdrs may appear after the - basic Ethernet header */ - int has_ovlan = IS_MF_SD(bp); - REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); - REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); - } + if (!CHIP_IS_E1x(bp) && !CHIP_IS_E3B0(bp)) + /* Bit-map indicating which L2 hdrs may appear + * after the basic Ethernet header + */ + REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, + bp->path_has_ovlan ? 7 : 6); - bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_TSDM, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_CSDM, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_USDM, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_XSDM, PHASE_COMMON); - bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); - bnx2x_init_fill(bp, USEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); - bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); + if (!CHIP_IS_E1x(bp)) { + /* reset VFC memories */ + REG_WR(bp, TSEM_REG_FAST_MEMORY + VFC_REG_MEMORIES_RST, + VFC_MEMORIES_RST_REG_CAM_RST | + VFC_MEMORIES_RST_REG_RAM_RST); + REG_WR(bp, XSEM_REG_FAST_MEMORY + VFC_REG_MEMORIES_RST, + VFC_MEMORIES_RST_REG_CAM_RST | + VFC_MEMORIES_RST_REG_RAM_RST); - bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE); + msleep(20); + } - if (CHIP_MODE_IS_4_PORT(bp)) - bnx2x_init_block(bp, XSEM_4PORT_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_TSEM, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_USEM, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_CSEM, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_XSEM, PHASE_COMMON); /* sync semi rtc */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, @@ -4751,21 +5613,18 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x80000000); - bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_UPB, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_XPB, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_PBF, PHASE_COMMON); - if (CHIP_IS_E2(bp)) { - int has_ovlan = IS_MF_SD(bp); - REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); - REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); - } + if (!CHIP_IS_E1x(bp)) + REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, + bp->path_has_ovlan ? 7 : 6); REG_WR(bp, SRC_REG_SOFT_RST, 1); - for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) - REG_WR(bp, i, random32()); - bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_SRC, PHASE_COMMON); + #ifdef BCM_CNIC REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); REG_WR(bp, SRC_REG_KEYSEARCH_1, 0x24b8f2cc); @@ -4786,11 +5645,11 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) "of cdu_context(%ld)\n", (long)sizeof(union cdu_context)); - bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_CDU, PHASE_COMMON); val = (4 << 24) + (0 << 12) + 1024; REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val); - bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_CFC, PHASE_COMMON); REG_WR(bp, CFC_REG_INIT_REG, 0x7FF); /* enable context validation interrupt from CFC */ REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); @@ -4798,20 +5657,19 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) /* set the thresholds to prevent CFC/CDU race */ REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); - bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_HC, PHASE_COMMON); - if (CHIP_IS_E2(bp) && BP_NOMCP(bp)) + if (!CHIP_IS_E1x(bp) && BP_NOMCP(bp)) REG_WR(bp, IGU_REG_RESET_MEMORIES, 0x36); - bnx2x_init_block(bp, IGU_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_IGU, PHASE_COMMON); + bnx2x_init_block(bp, BLOCK_MISC_AEU, PHASE_COMMON); - bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE); /* Reset PCIE errors for debug */ REG_WR(bp, 0x2814, 0xffffffff); REG_WR(bp, 0x3820, 0xffffffff); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_CONTROL_5, (PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 | PXPCS_TL_CONTROL_5_ERR_UNSPPORT)); @@ -4825,21 +5683,15 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5)); } - bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE); - - bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, BLOCK_NIG, PHASE_COMMON); if (!CHIP_IS_E1(bp)) { - REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); - REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF_SD(bp)); - } - if (CHIP_IS_E2(bp)) { - /* Bit-map indicating which L2 hdrs may appear after the - basic Ethernet header */ - REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF_SD(bp) ? 7 : 6)); + /* in E3 this done in per-port section */ + if (!CHIP_IS_E3(bp)) + REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); } + if (CHIP_IS_E1H(bp)) + /* not applicable for E2 (and above ...) */ + REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF_SD(bp)); if (CHIP_REV_IS_SLOW(bp)) msleep(200); @@ -4885,123 +5737,133 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_enable_blocks_parity(bp); if (!BP_NOMCP(bp)) { - /* In E2 2-PORT mode, same ext phy is used for the two paths */ - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || - CHIP_IS_E1x(bp)) { - u32 shmem_base[2], shmem2_base[2]; - shmem_base[0] = bp->common.shmem_base; - shmem2_base[0] = bp->common.shmem2_base; - if (CHIP_IS_E2(bp)) { - shmem_base[1] = - SHMEM2_RD(bp, other_shmem_base_addr); - shmem2_base[1] = - SHMEM2_RD(bp, other_shmem2_base_addr); - } - bnx2x_acquire_phy_lock(bp); - bnx2x_common_init_phy(bp, shmem_base, shmem2_base, - bp->common.chip_id); - bnx2x_release_phy_lock(bp); - } + if (CHIP_IS_E1x(bp)) + bnx2x__common_init_phy(bp); } else BNX2X_ERR("Bootcode is missing - can not initialize link\n"); return 0; } +/** + * bnx2x_init_hw_common_chip - init HW at the COMMON_CHIP phase. + * + * @bp: driver handle + */ +static int bnx2x_init_hw_common_chip(struct bnx2x *bp) +{ + int rc = bnx2x_init_hw_common(bp); + + if (rc) + return rc; + + /* In E2 2-PORT mode, same ext phy is used for the two paths */ + if (!BP_NOMCP(bp)) + bnx2x__common_init_phy(bp); + + return 0; +} + static int bnx2x_init_hw_port(struct bnx2x *bp) { int port = BP_PORT(bp); - int init_stage = port ? PORT1_STAGE : PORT0_STAGE; + int init_phase = port ? PHASE_PORT1 : PHASE_PORT0; u32 low, high; u32 val; + bnx2x__link_reset(bp); + DP(BNX2X_MSG_MCP, "starting port init port %d\n", port); REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); - bnx2x_init_block(bp, PXP_BLOCK, init_stage); - bnx2x_init_block(bp, PXP2_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_MISC, init_phase); + bnx2x_init_block(bp, BLOCK_PXP, init_phase); + bnx2x_init_block(bp, BLOCK_PXP2, init_phase); /* Timers bug workaround: disables the pf_master bit in pglue at * common phase, we need to enable it here before any dmae access are * attempted. Therefore we manually added the enable-master to the * port phase (it also happens in the function phase) */ - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); - bnx2x_init_block(bp, TCM_BLOCK, init_stage); - bnx2x_init_block(bp, UCM_BLOCK, init_stage); - bnx2x_init_block(bp, CCM_BLOCK, init_stage); - bnx2x_init_block(bp, XCM_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_ATC, init_phase); + bnx2x_init_block(bp, BLOCK_DMAE, init_phase); + bnx2x_init_block(bp, BLOCK_PGLUE_B, init_phase); + bnx2x_init_block(bp, BLOCK_QM, init_phase); + + bnx2x_init_block(bp, BLOCK_TCM, init_phase); + bnx2x_init_block(bp, BLOCK_UCM, init_phase); + bnx2x_init_block(bp, BLOCK_CCM, init_phase); + bnx2x_init_block(bp, BLOCK_XCM, init_phase); /* QM cid (connection) count */ bnx2x_qm_init_cid_count(bp, bp->qm_cid_count, INITOP_SET); #ifdef BCM_CNIC - bnx2x_init_block(bp, TIMERS_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_TM, init_phase); REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); #endif - bnx2x_init_block(bp, DQ_BLOCK, init_stage); - - if (CHIP_MODE_IS_4_PORT(bp)) - bnx2x_init_block(bp, QM_4PORT_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_DORQ, init_phase); if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { - bnx2x_init_block(bp, BRB1_BLOCK, init_stage); - if (CHIP_REV_IS_SLOW(bp) && CHIP_IS_E1(bp)) { - /* no pause for emulation and FPGA */ - low = 0; - high = 513; - } else { - if (IS_MF(bp)) - low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); - else if (bp->dev->mtu > 4096) { - if (bp->flags & ONE_PORT_FLAG) - low = 160; - else { - val = bp->dev->mtu; - /* (24*1024 + val*4)/256 */ - low = 96 + (val/64) + - ((val % 64) ? 1 : 0); - } - } else - low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); - high = low + 56; /* 14*1024/256 */ - } + bnx2x_init_block(bp, BLOCK_BRB1, init_phase); + + if (IS_MF(bp)) + low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); + else if (bp->dev->mtu > 4096) { + if (bp->flags & ONE_PORT_FLAG) + low = 160; + else { + val = bp->dev->mtu; + /* (24*1024 + val*4)/256 */ + low = 96 + (val/64) + + ((val % 64) ? 1 : 0); + } + } else + low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); + high = low + 56; /* 14*1024/256 */ REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); } - if (CHIP_MODE_IS_4_PORT(bp)) { - REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 + port*8, 248); - REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 + port*8, 328); - REG_WR(bp, (BP_PORT(bp) ? BRB1_REG_MAC_GUARANTIED_1 : - BRB1_REG_MAC_GUARANTIED_0), 40); - } + if (CHIP_MODE_IS_4_PORT(bp)) + REG_WR(bp, (BP_PORT(bp) ? + BRB1_REG_MAC_GUARANTIED_1 : + BRB1_REG_MAC_GUARANTIED_0), 40); - bnx2x_init_block(bp, PRS_BLOCK, init_stage); - bnx2x_init_block(bp, TSDM_BLOCK, init_stage); - bnx2x_init_block(bp, CSDM_BLOCK, init_stage); - bnx2x_init_block(bp, USDM_BLOCK, init_stage); - bnx2x_init_block(bp, XSDM_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_PRS, init_phase); + if (CHIP_IS_E3B0(bp)) + /* Ovlan exists only if we are in multi-function + + * switch-dependent mode, in switch-independent there + * is no ovlan headers + */ + REG_WR(bp, BP_PORT(bp) ? + PRS_REG_HDRS_AFTER_BASIC_PORT_1 : + PRS_REG_HDRS_AFTER_BASIC_PORT_0, + (bp->path_has_ovlan ? 7 : 6)); - bnx2x_init_block(bp, TSEM_BLOCK, init_stage); - bnx2x_init_block(bp, USEM_BLOCK, init_stage); - bnx2x_init_block(bp, CSEM_BLOCK, init_stage); - bnx2x_init_block(bp, XSEM_BLOCK, init_stage); - if (CHIP_MODE_IS_4_PORT(bp)) - bnx2x_init_block(bp, XSEM_4PORT_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_TSDM, init_phase); + bnx2x_init_block(bp, BLOCK_CSDM, init_phase); + bnx2x_init_block(bp, BLOCK_USDM, init_phase); + bnx2x_init_block(bp, BLOCK_XSDM, init_phase); - bnx2x_init_block(bp, UPB_BLOCK, init_stage); - bnx2x_init_block(bp, XPB_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_TSEM, init_phase); + bnx2x_init_block(bp, BLOCK_USEM, init_phase); + bnx2x_init_block(bp, BLOCK_CSEM, init_phase); + bnx2x_init_block(bp, BLOCK_XSEM, init_phase); - bnx2x_init_block(bp, PBF_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_UPB, init_phase); + bnx2x_init_block(bp, BLOCK_XPB, init_phase); - if (!CHIP_IS_E2(bp)) { + bnx2x_init_block(bp, BLOCK_PBF, init_phase); + + if (CHIP_IS_E1x(bp)) { /* configure PBF to work without PAUSE mtu 9000 */ REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); @@ -5017,20 +5879,20 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) } #ifdef BCM_CNIC - bnx2x_init_block(bp, SRCH_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_SRC, init_phase); #endif - bnx2x_init_block(bp, CDU_BLOCK, init_stage); - bnx2x_init_block(bp, CFC_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_CDU, init_phase); + bnx2x_init_block(bp, BLOCK_CFC, init_phase); if (CHIP_IS_E1(bp)) { REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); } - bnx2x_init_block(bp, HC_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_HC, init_phase); - bnx2x_init_block(bp, IGU_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_IGU, init_phase); - bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage); + bnx2x_init_block(bp, BLOCK_MISC_AEU, init_phase); /* init aeu_mask_attn_func_0/1: * - SF mode: bits 3-7 are masked. only bits 0-2 are in use * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF @@ -5040,22 +5902,31 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) val |= CHIP_IS_E1(bp) ? 0 : 0x10; REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, val); - bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); - bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); - bnx2x_init_block(bp, EMAC1_BLOCK, init_stage); - bnx2x_init_block(bp, DBU_BLOCK, init_stage); - bnx2x_init_block(bp, DBG_BLOCK, init_stage); - - bnx2x_init_block(bp, NIG_BLOCK, init_stage); - - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); + bnx2x_init_block(bp, BLOCK_NIG, init_phase); + + if (!CHIP_IS_E1x(bp)) { + /* Bit-map indicating which L2 hdrs may appear after the + * basic Ethernet header + */ + REG_WR(bp, BP_PORT(bp) ? + NIG_REG_P1_HDRS_AFTER_BASIC : + NIG_REG_P0_HDRS_AFTER_BASIC, + IS_MF_SD(bp) ? 7 : 6); + + if (CHIP_IS_E3(bp)) + REG_WR(bp, BP_PORT(bp) ? + NIG_REG_LLH1_MF_MODE : + NIG_REG_LLH_MF_MODE, IS_MF(bp)); + } + if (!CHIP_IS_E3(bp)) + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); if (!CHIP_IS_E1(bp)) { /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, (IS_MF_SD(bp) ? 0x1 : 0x2)); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { val = 0; switch (bp->mf_mode) { case MULTI_FUNCTION_SD: @@ -5076,17 +5947,16 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) } } - bnx2x_init_block(bp, MCP_BLOCK, init_stage); - bnx2x_init_block(bp, DMAE_BLOCK, init_stage); - if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, - bp->common.shmem2_base, port)) { + + /* If SPIO5 is set to generate interrupts, enable it for this port */ + val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN); + if (val & (1 << MISC_REGISTERS_SPIO_5)) { u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); val = REG_RD(bp, reg_addr); val |= AEU_INPUTS_ATTN_BITS_SPIO5; REG_WR(bp, reg_addr, val); } - bnx2x__link_reset(bp); return 0; } @@ -5105,7 +5975,7 @@ static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) static inline void bnx2x_igu_clear_sb(struct bnx2x *bp, u8 idu_sb_id) { - bnx2x_igu_clear_sb_gen(bp, idu_sb_id, true /*PF*/); + bnx2x_igu_clear_sb_gen(bp, BP_FUNC(bp), idu_sb_id, true /*PF*/); } static inline void bnx2x_clear_func_ilt(struct bnx2x *bp, u32 func) @@ -5119,6 +5989,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); + int init_phase = PHASE_PF0 + func; struct bnx2x_ilt *ilt = BP_ILT(bp); u16 cdu_ilt_start; u32 addr, val; @@ -5127,6 +5998,10 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); + /* FLR cleanup - hmmm */ + if (!CHIP_IS_E1x(bp)) + bnx2x_pf_flr_clnup(bp); + /* set MSI reconfigure capability */ if (bp->common.int_block == INT_BLOCK_HC) { addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); @@ -5135,6 +6010,9 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_WR(bp, addr, val); } + bnx2x_init_block(bp, BLOCK_PXP, init_phase); + bnx2x_init_block(bp, BLOCK_PXP2, init_phase); + ilt = BP_ILT(bp); cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; @@ -5160,7 +6038,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif /* BCM_CNIC */ - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { u32 pf_conf = IGU_PF_CONF_FUNC_EN; /* Turn on a single ISR mode in IGU if driver is going to use @@ -5187,58 +6065,55 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bp->dmae_ready = 1; - bnx2x_init_block(bp, PGLUE_B_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BLOCK_PGLUE_B, init_phase); - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, func); - bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); - - if (CHIP_IS_E2(bp)) { - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_PATH_ID_OFFSET, - BP_PATH(bp)); - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_PATH_ID_OFFSET, - BP_PATH(bp)); - } - - if (CHIP_MODE_IS_4_PORT(bp)) - bnx2x_init_block(bp, XSEM_4PORT_BLOCK, FUNC0_STAGE + func); - - if (CHIP_IS_E2(bp)) + bnx2x_init_block(bp, BLOCK_ATC, init_phase); + bnx2x_init_block(bp, BLOCK_DMAE, init_phase); + bnx2x_init_block(bp, BLOCK_NIG, init_phase); + bnx2x_init_block(bp, BLOCK_SRC, init_phase); + bnx2x_init_block(bp, BLOCK_MISC, init_phase); + bnx2x_init_block(bp, BLOCK_TCM, init_phase); + bnx2x_init_block(bp, BLOCK_UCM, init_phase); + bnx2x_init_block(bp, BLOCK_CCM, init_phase); + bnx2x_init_block(bp, BLOCK_XCM, init_phase); + bnx2x_init_block(bp, BLOCK_TSEM, init_phase); + bnx2x_init_block(bp, BLOCK_USEM, init_phase); + bnx2x_init_block(bp, BLOCK_CSEM, init_phase); + bnx2x_init_block(bp, BLOCK_XSEM, init_phase); + + if (!CHIP_IS_E1x(bp)) REG_WR(bp, QM_REG_PF_EN, 1); - bnx2x_init_block(bp, QM_BLOCK, FUNC0_STAGE + func); - - if (CHIP_MODE_IS_4_PORT(bp)) - bnx2x_init_block(bp, QM_4PORT_BLOCK, FUNC0_STAGE + func); - - bnx2x_init_block(bp, TIMERS_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, DQ_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, BRB1_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, PRS_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TSDM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CSDM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, USDM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XSDM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, UPB_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XPB_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, PBF_BLOCK, FUNC0_STAGE + func); - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) { + REG_WR(bp, TSEM_REG_VFPF_ERR_NUM, BNX2X_MAX_NUM_OF_VFS + func); + REG_WR(bp, USEM_REG_VFPF_ERR_NUM, BNX2X_MAX_NUM_OF_VFS + func); + REG_WR(bp, CSEM_REG_VFPF_ERR_NUM, BNX2X_MAX_NUM_OF_VFS + func); + REG_WR(bp, XSEM_REG_VFPF_ERR_NUM, BNX2X_MAX_NUM_OF_VFS + func); + } + bnx2x_init_block(bp, BLOCK_QM, init_phase); + + bnx2x_init_block(bp, BLOCK_TM, init_phase); + bnx2x_init_block(bp, BLOCK_DORQ, init_phase); + bnx2x_init_block(bp, BLOCK_BRB1, init_phase); + bnx2x_init_block(bp, BLOCK_PRS, init_phase); + bnx2x_init_block(bp, BLOCK_TSDM, init_phase); + bnx2x_init_block(bp, BLOCK_CSDM, init_phase); + bnx2x_init_block(bp, BLOCK_USDM, init_phase); + bnx2x_init_block(bp, BLOCK_XSDM, init_phase); + bnx2x_init_block(bp, BLOCK_UPB, init_phase); + bnx2x_init_block(bp, BLOCK_XPB, init_phase); + bnx2x_init_block(bp, BLOCK_PBF, init_phase); + if (!CHIP_IS_E1x(bp)) REG_WR(bp, PBF_REG_DISABLE_PF, 0); - bnx2x_init_block(bp, CDU_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BLOCK_CDU, init_phase); - bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BLOCK_CFC, init_phase); - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 1); if (IS_MF(bp)) { @@ -5246,7 +6121,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov); } - bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BLOCK_MISC_AEU, init_phase); /* HC init per function */ if (bp->common.int_block == INT_BLOCK_HC) { @@ -5256,21 +6131,21 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); } - bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BLOCK_HC, init_phase); } else { int num_segs, sb_idx, prod_offset; REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0); REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); } - bnx2x_init_block(bp, IGU_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BLOCK_IGU, init_phase); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { int dsb_idx = 0; /** * Producer memory: @@ -5365,13 +6240,6 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_WR(bp, 0x2114, 0xffffffff); REG_WR(bp, 0x2120, 0xffffffff); - bnx2x_init_block(bp, EMAC0_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, EMAC1_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, DBU_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, DBG_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, MCP_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func); - if (CHIP_IS_E1x(bp)) { main_mem_size = HC_REG_MAIN_MEMORY_SIZE / 2; /*dwords*/ main_mem_base = HC_REG_MAIN_MEMORY + @@ -5397,65 +6265,26 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_RD(bp, main_mem_prty_clr); } +#ifdef BNX2X_STOP_ON_ERROR + /* Enable STORMs SP logging */ + REG_WR8(bp, BAR_USTRORM_INTMEM + + USTORM_RECORD_SLOW_PATH_OFFSET(BP_FUNC(bp)), 1); + REG_WR8(bp, BAR_TSTRORM_INTMEM + + TSTORM_RECORD_SLOW_PATH_OFFSET(BP_FUNC(bp)), 1); + REG_WR8(bp, BAR_CSTRORM_INTMEM + + CSTORM_RECORD_SLOW_PATH_OFFSET(BP_FUNC(bp)), 1); + REG_WR8(bp, BAR_XSTRORM_INTMEM + + XSTORM_RECORD_SLOW_PATH_OFFSET(BP_FUNC(bp)), 1); +#endif + bnx2x_phy_probe(&bp->link_params); return 0; } -int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) -{ - int rc = 0; - - DP(BNX2X_MSG_MCP, "function %d load_code %x\n", - BP_ABS_FUNC(bp), load_code); - - bp->dmae_ready = 0; - spin_lock_init(&bp->dmae_lock); - - switch (load_code) { - case FW_MSG_CODE_DRV_LOAD_COMMON: - case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: - rc = bnx2x_init_hw_common(bp, load_code); - if (rc) - goto init_hw_err; - /* no break */ - - case FW_MSG_CODE_DRV_LOAD_PORT: - rc = bnx2x_init_hw_port(bp); - if (rc) - goto init_hw_err; - /* no break */ - - case FW_MSG_CODE_DRV_LOAD_FUNCTION: - rc = bnx2x_init_hw_func(bp); - if (rc) - goto init_hw_err; - break; - - default: - BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code); - break; - } - - if (!BP_NOMCP(bp)) { - int mb_idx = BP_FW_MB_IDX(bp); - - bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & - DRV_PULSE_SEQ_MASK); - DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); - } - -init_hw_err: - bnx2x_gunzip_end(bp); - - return rc; -} void bnx2x_free_mem(struct bnx2x *bp) { - bnx2x_gunzip_end(bp); - /* fastpath */ bnx2x_free_fp_mem(bp); /* end of fastpath */ @@ -5463,6 +6292,9 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, sizeof(struct host_sp_status_block)); + BNX2X_PCI_FREE(bp->fw_stats, bp->fw_stats_mapping, + bp->fw_stats_data_sz + bp->fw_stats_req_sz); + BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, sizeof(struct bnx2x_slowpath)); @@ -5474,7 +6306,7 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_FREE(bp->ilt->lines); #ifdef BCM_CNIC - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, sizeof(struct host_hc_status_block_e2)); else @@ -5488,18 +6320,67 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, BCM_PAGE_SIZE * NUM_EQ_PAGES); +} + +static inline int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp) +{ + int num_groups; + + /* number of eth_queues */ + u8 num_queue_stats = BNX2X_NUM_ETH_QUEUES(bp); + + /* Total number of FW statistics requests = + * 1 for port stats + 1 for PF stats + num_eth_queues */ + bp->fw_stats_num = 2 + num_queue_stats; - BNX2X_FREE(bp->rx_indir_table); + + /* Request is built from stats_query_header and an array of + * stats_query_cmd_group each of which contains + * STATS_QUERY_CMD_COUNT rules. The real number or requests is + * configured in the stats_query_header. + */ + num_groups = (2 + num_queue_stats) / STATS_QUERY_CMD_COUNT + + (((2 + num_queue_stats) % STATS_QUERY_CMD_COUNT) ? 1 : 0); + + bp->fw_stats_req_sz = sizeof(struct stats_query_header) + + num_groups * sizeof(struct stats_query_cmd_group); + + /* Data for statistics requests + stats_conter + * + * stats_counter holds per-STORM counters that are incremented + * when STORM has finished with the current request. + */ + bp->fw_stats_data_sz = sizeof(struct per_port_stats) + + sizeof(struct per_pf_stats) + + sizeof(struct per_queue_stats) * num_queue_stats + + sizeof(struct stats_counter); + + BNX2X_PCI_ALLOC(bp->fw_stats, &bp->fw_stats_mapping, + bp->fw_stats_data_sz + bp->fw_stats_req_sz); + + /* Set shortcuts */ + bp->fw_stats_req = (struct bnx2x_fw_stats_req *)bp->fw_stats; + bp->fw_stats_req_mapping = bp->fw_stats_mapping; + + bp->fw_stats_data = (struct bnx2x_fw_stats_data *) + ((u8 *)bp->fw_stats + bp->fw_stats_req_sz); + + bp->fw_stats_data_mapping = bp->fw_stats_mapping + + bp->fw_stats_req_sz; + return 0; + +alloc_mem_err: + BNX2X_PCI_FREE(bp->fw_stats, bp->fw_stats_mapping, + bp->fw_stats_data_sz + bp->fw_stats_req_sz); + return -ENOMEM; } int bnx2x_alloc_mem(struct bnx2x *bp) { - if (bnx2x_gunzip_init(bp)) - return -ENOMEM; - #ifdef BCM_CNIC - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) + /* size = the status block + ramrod buffers */ BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping, sizeof(struct host_hc_status_block_e2)); else @@ -5517,6 +6398,10 @@ int bnx2x_alloc_mem(struct bnx2x *bp) BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, sizeof(struct bnx2x_slowpath)); + /* Allocated memory for FW statistics */ + if (bnx2x_alloc_fw_stats_mem(bp)) + goto alloc_mem_err; + bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count; BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, @@ -5534,8 +6419,6 @@ int bnx2x_alloc_mem(struct bnx2x *bp) BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, BCM_PAGE_SIZE * NUM_EQ_PAGES); - BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) * - TSTORM_INDIRECTION_TABLE_SIZE); /* fastpath */ /* need to be done at the end, since it's self adjusting to amount @@ -5553,235 +6436,76 @@ alloc_mem_err: /* * Init service functions */ -int bnx2x_func_start(struct bnx2x *bp) -{ - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 0, 0, 1); - - /* Wait for completion */ - return bnx2x_wait_ramrod(bp, BNX2X_STATE_FUNC_STARTED, 0, &(bp->state), - WAIT_RAMROD_COMMON); -} - -static int bnx2x_func_stop(struct bnx2x *bp) -{ - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0, 0, 1); - /* Wait for completion */ - return bnx2x_wait_ramrod(bp, BNX2X_STATE_CLOSING_WAIT4_UNLOAD, - 0, &(bp->state), WAIT_RAMROD_COMMON); -} - -int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags) +int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac, + struct bnx2x_vlan_mac_obj *obj, bool set, + int mac_type, unsigned long *ramrod_flags) { - /* can take a while if any port is running */ - int cnt = 5000; - u8 poll = flags & WAIT_RAMROD_POLL; - u8 common = flags & WAIT_RAMROD_COMMON; + int rc; + struct bnx2x_vlan_mac_ramrod_params ramrod_param; - DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", - poll ? "polling" : "waiting", state, idx); + memset(&ramrod_param, 0, sizeof(ramrod_param)); - might_sleep(); - while (cnt--) { - if (poll) { - if (common) - bnx2x_eq_int(bp); - else { - bnx2x_rx_int(bp->fp, 10); - /* if index is different from 0 - * the reply for some commands will - * be on the non default queue - */ - if (idx) - bnx2x_rx_int(&bp->fp[idx], 10); - } - } + /* Fill general parameters */ + ramrod_param.vlan_mac_obj = obj; + ramrod_param.ramrod_flags = *ramrod_flags; - mb(); /* state is changed by bnx2x_sp_event() */ - if (*state_p == state) { -#ifdef BNX2X_STOP_ON_ERROR - DP(NETIF_MSG_IFUP, "exit (cnt %d)\n", 5000 - cnt); -#endif - return 0; - } + /* Fill a user request section if needed */ + if (!test_bit(RAMROD_CONT, ramrod_flags)) { + memcpy(ramrod_param.user_req.u.mac.mac, mac, ETH_ALEN); - msleep(1); + __set_bit(mac_type, &ramrod_param.user_req.vlan_mac_flags); - if (bp->panic) - return -EIO; + /* Set the command: ADD or DEL */ + if (set) + ramrod_param.user_req.cmd = BNX2X_VLAN_MAC_ADD; + else + ramrod_param.user_req.cmd = BNX2X_VLAN_MAC_DEL; } - /* timeout! */ - BNX2X_ERR("timeout %s for state %x on IDX [%d]\n", - poll ? "polling" : "waiting", state, idx); -#ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); -#endif - - return -EBUSY; + rc = bnx2x_config_vlan_mac(bp, &ramrod_param); + if (rc < 0) + BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); + return rc; } -static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) +int bnx2x_del_all_macs(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *mac_obj, + int mac_type, bool wait_for_comp) { - if (CHIP_IS_E1H(bp)) - return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); - else if (CHIP_MODE_IS_4_PORT(bp)) - return E2_FUNC_MAX * rel_offset + BP_FUNC(bp); - else - return E2_FUNC_MAX * rel_offset + BP_VN(bp); -} - -/** - * LLH CAM line allocations: currently only iSCSI and ETH macs are - * relevant. In addition, current implementation is tuned for a - * single ETH MAC. - */ -enum { - LLH_CAM_ISCSI_ETH_LINE = 0, - LLH_CAM_ETH_LINE, - LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE -}; - -static void bnx2x_set_mac_in_nig(struct bnx2x *bp, - int set, - unsigned char *dev_addr, - int index) -{ - u32 wb_data[2]; - u32 mem_offset, ena_offset, mem_index; - /** - * indexes mapping: - * 0..7 - goes to MEM - * 8..15 - goes to MEM2 - */ - - if (!IS_MF_SI(bp) || index > LLH_CAM_MAX_PF_LINE) - return; - - /* calculate memory start offset according to the mapping - * and index in the memory */ - if (index < NIG_LLH_FUNC_MEM_MAX_OFFSET) { - mem_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM : - NIG_REG_LLH0_FUNC_MEM; - ena_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM_ENABLE : - NIG_REG_LLH0_FUNC_MEM_ENABLE; - mem_index = index; - } else { - mem_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2 : - NIG_REG_P0_LLH_FUNC_MEM2; - ena_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2_ENABLE : - NIG_REG_P0_LLH_FUNC_MEM2_ENABLE; - mem_index = index - NIG_LLH_FUNC_MEM_MAX_OFFSET; - } - - if (set) { - /* LLH_FUNC_MEM is a u64 WB register */ - mem_offset += 8*mem_index; + int rc; + unsigned long ramrod_flags = 0, vlan_mac_flags = 0; - wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) | - (dev_addr[4] << 8) | dev_addr[5]); - wb_data[1] = ((dev_addr[0] << 8) | dev_addr[1]); + /* Wait for completion of requested */ + if (wait_for_comp) + __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); - REG_WR_DMAE(bp, mem_offset, wb_data, 2); - } + /* Set the mac type of addresses we want to clear */ + __set_bit(mac_type, &vlan_mac_flags); - /* enable/disable the entry */ - REG_WR(bp, ena_offset + 4*mem_index, set); + rc = mac_obj->delete_all(bp, mac_obj, &vlan_mac_flags, &ramrod_flags); + if (rc < 0) + BNX2X_ERR("Failed to delete MACs: %d\n", rc); + return rc; } -void bnx2x_set_eth_mac(struct bnx2x *bp, int set) +int bnx2x_set_eth_mac(struct bnx2x *bp, bool set) { - u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : - bnx2x_e1h_cam_offset(bp, CAM_ETH_LINE)); - - /* networking MAC */ - bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), cam_offset , 0); + unsigned long ramrod_flags = 0; - bnx2x_set_mac_in_nig(bp, set, bp->dev->dev_addr, LLH_CAM_ETH_LINE); + DP(NETIF_MSG_IFUP, "Adding Eth MAC\n"); - if (CHIP_IS_E1(bp)) { - /* broadcast MAC */ - static const u8 bcast[ETH_ALEN] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1); - } + __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); + /* Eth MAC is set on RSS leading client (fp[0]) */ + return bnx2x_set_mac_one(bp, bp->dev->dev_addr, &bp->fp->mac_obj, set, + BNX2X_ETH_MAC, &ramrod_flags); } -#ifdef BCM_CNIC -/** - * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s). - * - * @bp: driver handle - * @set: set or clear the CAM entry - * - * This function will wait until the ramdord completion returns. - * Return 0 if success, -ENODEV if ramrod doesn't return. - */ -static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) -{ - u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) : - bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE)); - u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID + - BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; - u32 cl_bit_vec = (1 << iscsi_l2_cl_id); - u8 *iscsi_mac = bp->cnic_eth_dev.iscsi_mac; - - /* Send a SET_MAC ramrod */ - bnx2x_set_mac_addr_gen(bp, set, iscsi_mac, cl_bit_vec, - cam_offset, 0); - - bnx2x_set_mac_in_nig(bp, set, iscsi_mac, LLH_CAM_ISCSI_ETH_LINE); - - return 0; -} - -/** - * bnx2x_set_fip_eth_mac_addr - set FCoE L2 MAC(s) - * - * @bp: driver handle - * @set: set or clear the CAM entry - * - * This function will wait until the ramrod completion returns. - * Returns 0 if success, -ENODEV if ramrod doesn't return. - */ -int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set) -{ - u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id)); - /** - * CAM allocation for E1H - * eth unicasts: by func number - * iscsi: by func number - * fip unicast: by func number - * fip multicast: by func number - */ - bnx2x_set_mac_addr_gen(bp, set, bp->fip_mac, - cl_bit_vec, bnx2x_e1h_cam_offset(bp, CAM_FIP_ETH_LINE), 0); - - return 0; -} - -int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set) +int bnx2x_setup_leading(struct bnx2x *bp) { - u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id)); - - /** - * CAM allocation for E1H - * eth unicasts: by func number - * iscsi: by func number - * fip unicast: by func number - * fip multicast: by func number - */ - bnx2x_set_mac_addr_gen(bp, set, ALL_ENODE_MACS, cl_bit_vec, - bnx2x_e1h_cam_offset(bp, CAM_FIP_MCAST_LINE), 0); - - return 0; + return bnx2x_setup_queue(bp, &bp->fp[0], 1); } -#endif - /** * bnx2x_set_int_mode - configure interrupt mode @@ -5792,7 +6516,6 @@ int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set) */ static void __devinit bnx2x_set_int_mode(struct bnx2x *bp) { - switch (int_mode) { case INT_MODE_MSI: bnx2x_enable_msi(bp); @@ -5852,7 +6575,7 @@ void bnx2x_ilt_set_info(struct bnx2x *bp) ilt_client->page_size = CDU_ILT_PAGE_SZ; ilt_client->flags = ILT_CLIENT_SKIP_MEM; ilt_client->start = line; - line += L2_ILT_LINES(bp); + line += bnx2x_cid_ilt_lines(bp); #ifdef BCM_CNIC line += CNIC_ILT_LINES; #endif @@ -5932,12 +6655,72 @@ void bnx2x_ilt_set_info(struct bnx2x *bp) #else ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); #endif + BUG_ON(line > ILT_MAX_LINES); } -int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, - int is_leading) +/** + * bnx2x_pf_q_prep_init - prepare INIT transition parameters + * + * @bp: driver handle + * @fp: pointer to fastpath + * @init_params: pointer to parameters structure + * + * parameters configured: + * - HC configuration + * - Queue's CDU context + */ +static inline void bnx2x_pf_q_prep_init(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct bnx2x_queue_init_params *init_params) { - struct bnx2x_client_init_params params = { {0} }; + /* FCoE Queue uses Default SB, thus has no HC capabilities */ + if (!IS_FCOE_FP(fp)) { + __set_bit(BNX2X_Q_FLG_HC, &init_params->rx.flags); + __set_bit(BNX2X_Q_FLG_HC, &init_params->tx.flags); + + /* If HC is supporterd, enable host coalescing in the transition + * to INIT state. + */ + __set_bit(BNX2X_Q_FLG_HC_EN, &init_params->rx.flags); + __set_bit(BNX2X_Q_FLG_HC_EN, &init_params->tx.flags); + + /* HC rate */ + init_params->rx.hc_rate = bp->rx_ticks ? + (1000000 / bp->rx_ticks) : 0; + init_params->tx.hc_rate = bp->tx_ticks ? + (1000000 / bp->tx_ticks) : 0; + + /* FW SB ID */ + init_params->rx.fw_sb_id = init_params->tx.fw_sb_id = + fp->fw_sb_id; + + /* + * CQ index among the SB indices: FCoE clients uses the default + * SB, therefore it's different. + */ + init_params->rx.sb_cq_index = U_SB_ETH_RX_CQ_INDEX; + init_params->tx.sb_cq_index = C_SB_ETH_TX_CQ_INDEX; + } + + init_params->cxt = &bp->context.vcxt[fp->cid].eth; +} + +/** + * bnx2x_setup_queue - setup queue + * + * @bp: driver handle + * @fp: pointer to fastpath + * @leading: is leading + * + * This function performs 2 steps in a Queue state machine + * actually: 1) RESET->INIT 2) INIT->SETUP + */ + +int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, + bool leading) +{ + struct bnx2x_queue_state_params q_params = {0}; + struct bnx2x_queue_setup_params *setup_params = + &q_params.params.setup; int rc; /* reset IGU state skip FCoE L2 queue */ @@ -5945,79 +6728,73 @@ int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); - params.ramrod_params.pstate = &fp->state; - params.ramrod_params.state = BNX2X_FP_STATE_OPEN; - params.ramrod_params.index = fp->index; - params.ramrod_params.cid = fp->cid; + q_params.q_obj = &fp->q_obj; + /* We want to wait for completion in this context */ + __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); -#ifdef BCM_CNIC - if (IS_FCOE_FP(fp)) - params.ramrod_params.flags |= CLIENT_IS_FCOE; + /* Prepare the INIT parameters */ + bnx2x_pf_q_prep_init(bp, fp, &q_params.params.init); -#endif + /* Set the command */ + q_params.cmd = BNX2X_Q_CMD_INIT; + + /* Change the state to INIT */ + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) { + BNX2X_ERR("Queue INIT failed\n"); + return rc; + } - if (is_leading) - params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS; + /* Now move the Queue to the SETUP state... */ + memset(setup_params, 0, sizeof(*setup_params)); - bnx2x_pf_rx_cl_prep(bp, fp, ¶ms.pause, ¶ms.rxq_params); + /* Set QUEUE flags */ + setup_params->flags = bnx2x_get_q_flags(bp, fp, leading); - bnx2x_pf_tx_cl_prep(bp, fp, ¶ms.txq_params); + /* Set general SETUP parameters */ + bnx2x_pf_q_prep_general(bp, fp, &setup_params->gen_params); + + bnx2x_pf_rx_q_prep(bp, fp, &setup_params->pause, + &setup_params->rxq_params); + + bnx2x_pf_tx_q_prep(bp, fp, &setup_params->txq_params); + + /* Set the command */ + q_params.cmd = BNX2X_Q_CMD_SETUP; + + /* Change the state to SETUP */ + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) + BNX2X_ERR("Queue SETUP failed\n"); - rc = bnx2x_setup_fw_client(bp, ¶ms, 1, - bnx2x_sp(bp, client_init_data), - bnx2x_sp_mapping(bp, client_init_data)); return rc; } -static int bnx2x_stop_fw_client(struct bnx2x *bp, - struct bnx2x_client_ramrod_params *p) +static int bnx2x_stop_queue(struct bnx2x *bp, int index) { + struct bnx2x_fastpath *fp = &bp->fp[index]; + struct bnx2x_queue_state_params q_params = {0}; int rc; - int poll_flag = p->poll ? WAIT_RAMROD_POLL : 0; + q_params.q_obj = &fp->q_obj; + /* We want to wait for completion in this context */ + __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); /* halt the connection */ - *p->pstate = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, p->cid, 0, - p->cl_id, 0); - - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, p->index, - p->pstate, poll_flag); - if (rc) /* timeout */ + q_params.cmd = BNX2X_Q_CMD_HALT; + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) return rc; - *p->pstate = BNX2X_FP_STATE_TERMINATING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, p->cid, 0, - p->cl_id, 0); - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_TERMINATED, p->index, - p->pstate, poll_flag); - if (rc) /* timeout */ + /* terminate the connection */ + q_params.cmd = BNX2X_Q_CMD_TERMINATE; + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) return rc; - /* delete cfc entry */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, p->cid, 0, 0, 1); - - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, p->index, - p->pstate, WAIT_RAMROD_COMMON); - return rc; -} - -static int bnx2x_stop_client(struct bnx2x *bp, int index) -{ - struct bnx2x_client_ramrod_params client_stop = {0}; - struct bnx2x_fastpath *fp = &bp->fp[index]; - - client_stop.index = index; - client_stop.cid = fp->cid; - client_stop.cl_id = fp->cl_id; - client_stop.pstate = &(fp->state); - client_stop.poll = 0; - - return bnx2x_stop_fw_client(bp, &client_stop); + q_params.cmd = BNX2X_Q_CMD_CFC_DEL; + return bnx2x_queue_state_change(bp, &q_params); } @@ -6026,12 +6803,6 @@ static void bnx2x_reset_func(struct bnx2x *bp) int port = BP_PORT(bp); int func = BP_FUNC(bp); int i; - int pfunc_offset_fp = offsetof(struct hc_sb_data, p_func) + - (CHIP_IS_E2(bp) ? - offsetof(struct hc_status_block_data_e2, common) : - offsetof(struct hc_status_block_data_e1x, common)); - int pfunc_offset_sp = offsetof(struct hc_sp_status_block_data, p_func); - int pfid_offset = offsetof(struct pci_entity, pf_id); /* Disable the function in the FW */ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(func), 0); @@ -6042,20 +6813,21 @@ static void bnx2x_reset_func(struct bnx2x *bp) /* FP SBs */ for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - REG_WR8(bp, - BAR_CSTRORM_INTMEM + - CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) - + pfunc_offset_fp + pfid_offset, - HC_FUNCTION_DISABLED); + REG_WR8(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(fp->fw_sb_id), + SB_DISABLED); } +#ifdef BCM_CNIC + /* CNIC SB */ + REG_WR8(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(bnx2x_cnic_fw_sb_id(bp)), + SB_DISABLED); +#endif /* SP SB */ - REG_WR8(bp, - BAR_CSTRORM_INTMEM + - CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + - pfunc_offset_sp + pfid_offset, - HC_FUNCTION_DISABLED); - + REG_WR8(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(func), + SB_DISABLED); for (i = 0; i < XSTORM_SPQ_DATA_SIZE / 4; i++) REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_DATA_OFFSET(func), @@ -6089,7 +6861,7 @@ static void bnx2x_reset_func(struct bnx2x *bp) /* Timers workaround bug for E2: if this is vnic-3, * we need to set the entire ilt range for this timers. */ - if (CHIP_IS_E2(bp) && BP_VN(bp) == 3) { + if (!CHIP_IS_E1x(bp) && BP_VN(bp) == 3) { struct ilt_client_info ilt_cli; /* use dummy TM client */ memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); @@ -6101,7 +6873,7 @@ static void bnx2x_reset_func(struct bnx2x *bp) } /* this assumes that reset_port() called before reset_func()*/ - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) bnx2x_pf_disable(bp); bp->dmae_ready = 0; @@ -6112,6 +6884,9 @@ static void bnx2x_reset_port(struct bnx2x *bp) int port = BP_PORT(bp); u32 val; + /* Reset physical Link */ + bnx2x__link_reset(bp); + REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); /* Do not rcv packets to BRB */ @@ -6133,92 +6908,66 @@ static void bnx2x_reset_port(struct bnx2x *bp) /* TODO: Close Doorbell port? */ } -static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) +static inline int bnx2x_reset_hw(struct bnx2x *bp, u32 load_code) { - DP(BNX2X_MSG_MCP, "function %d reset_code %x\n", - BP_ABS_FUNC(bp), reset_code); + struct bnx2x_func_state_params func_params = {0}; - switch (reset_code) { - case FW_MSG_CODE_DRV_UNLOAD_COMMON: - bnx2x_reset_port(bp); - bnx2x_reset_func(bp); - bnx2x_reset_common(bp); - break; + /* Prepare parameters for function state transitions */ + __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); - case FW_MSG_CODE_DRV_UNLOAD_PORT: - bnx2x_reset_port(bp); - bnx2x_reset_func(bp); - break; + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_HW_RESET; - case FW_MSG_CODE_DRV_UNLOAD_FUNCTION: - bnx2x_reset_func(bp); - break; + func_params.params.hw_init.load_phase = load_code; - default: - BNX2X_ERR("Unknown reset_code (0x%x) from MCP\n", reset_code); - break; - } + return bnx2x_func_state_change(bp, &func_params); } -#ifdef BCM_CNIC -static inline void bnx2x_del_fcoe_eth_macs(struct bnx2x *bp) +static inline int bnx2x_func_stop(struct bnx2x *bp) { - if (bp->flags & FCOE_MACS_SET) { - if (!IS_MF_SD(bp)) - bnx2x_set_fip_eth_mac_addr(bp, 0); - - bnx2x_set_all_enode_macs(bp, 0); - - bp->flags &= ~FCOE_MACS_SET; - } -} -#endif - -void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) -{ - int port = BP_PORT(bp); - u32 reset_code = 0; - int i, cnt, rc; - - /* Wait until tx fastpath tasks complete */ - for_each_tx_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; + struct bnx2x_func_state_params func_params = {0}; + int rc; - cnt = 1000; - while (bnx2x_has_tx_work_unload(fp)) { + /* Prepare parameters for function state transitions */ + __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_STOP; - if (!cnt) { - BNX2X_ERR("timeout waiting for queue[%d]\n", - i); + /* + * Try to stop the function the 'good way'. If fails (in case + * of a parity error during bnx2x_chip_cleanup()) and we are + * not in a debug mode, perform a state transaction in order to + * enable further HW_RESET transaction. + */ + rc = bnx2x_func_state_change(bp, &func_params); + if (rc) { #ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); - return -EBUSY; + return rc; #else - break; + BNX2X_ERR("FUNC_STOP ramrod failed. Running a dry " + "transaction\n"); + __set_bit(RAMROD_DRV_CLR_ONLY, &func_params.ramrod_flags); + return bnx2x_func_state_change(bp, &func_params); #endif - } - cnt--; - msleep(1); - } } - /* Give HW time to discard old tx messages */ - msleep(1); - bnx2x_set_eth_mac(bp, 0); - - bnx2x_invalidate_uc_list(bp); - - if (CHIP_IS_E1(bp)) - bnx2x_invalidate_e1_mc_list(bp); - else { - bnx2x_invalidate_e1h_mc_list(bp); - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); - } + return 0; +} -#ifdef BCM_CNIC - bnx2x_del_fcoe_eth_macs(bp); -#endif +/** + * bnx2x_send_unload_req - request unload mode from the MCP. + * + * @bp: driver handle + * @unload_mode: requested function's unload mode + * + * Return unload mode returned by the MCP: COMMON, PORT or FUNC. + */ +u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode) +{ + u32 reset_code = 0; + int port = BP_PORT(bp); + /* Select the UNLOAD request mode */ if (unload_mode == UNLOAD_NORMAL) reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; @@ -6245,54 +6994,135 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) } else reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + /* Send the request to the MCP */ + if (!BP_NOMCP(bp)) + reset_code = bnx2x_fw_command(bp, reset_code, 0); + else { + int path = BP_PATH(bp); + + DP(NETIF_MSG_IFDOWN, "NO MCP - load counts[%d] " + "%d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + load_count[path][0]--; + load_count[path][1 + port]--; + DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts[%d] " + "%d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + if (load_count[path][0] == 0) + reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; + else if (load_count[path][1 + port] == 0) + reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; + else + reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; + } + + return reset_code; +} + +/** + * bnx2x_send_unload_done - send UNLOAD_DONE command to the MCP. + * + * @bp: driver handle + */ +void bnx2x_send_unload_done(struct bnx2x *bp) +{ + /* Report UNLOAD_DONE to MCP */ + if (!BP_NOMCP(bp)) + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); +} + +void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) +{ + int port = BP_PORT(bp); + int i, rc; + struct bnx2x_mcast_ramrod_params rparam = {0}; + u32 reset_code; + + /* Wait until tx fastpath tasks complete */ + for_each_tx_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + rc = bnx2x_clean_tx_queue(bp, fp); +#ifdef BNX2X_STOP_ON_ERROR + if (rc) + return; +#endif + } + + /* Give HW time to discard old tx messages */ + usleep_range(1000, 1000); + + /* Clean all ETH MACs */ + rc = bnx2x_del_all_macs(bp, &bp->fp[0].mac_obj, BNX2X_ETH_MAC, false); + if (rc < 0) + BNX2X_ERR("Failed to delete all ETH macs: %d\n", rc); + + /* Clean up UC list */ + rc = bnx2x_del_all_macs(bp, &bp->fp[0].mac_obj, BNX2X_UC_LIST_MAC, + true); + if (rc < 0) + BNX2X_ERR("Failed to schedule DEL commands for UC MACs list: " + "%d\n", rc); + + /* Disable LLH */ + if (!CHIP_IS_E1(bp)) + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); + + /* Set "drop all" (stop Rx). + * We need to take a netif_addr_lock() here in order to prevent + * a race between the completion code and this code. + */ + netif_addr_lock_bh(bp->dev); + /* Schedule the rx_mode command */ + if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state)) + set_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state); + else + bnx2x_set_storm_rx_mode(bp); + + /* Cleanup multicast configuration */ + rparam.mcast_obj = &bp->mcast_obj; + rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL); + if (rc < 0) + BNX2X_ERR("Failed to send DEL multicast command: %d\n", rc); + + netif_addr_unlock_bh(bp->dev); + + /* Close multi and leading connections - Completions for ramrods are collected in a synchronous way */ + * Completions for ramrods are collected in a synchronous way + */ for_each_queue(bp, i) - - if (bnx2x_stop_client(bp, i)) + if (bnx2x_stop_queue(bp, i)) #ifdef BNX2X_STOP_ON_ERROR return; #else goto unload_error; #endif + /* If SP settings didn't get completed so far - something + * very wrong has happen. + */ + if (!bnx2x_wait_sp_comp(bp, ~0x0UL)) + BNX2X_ERR("Hmmm... Common slow path ramrods got stuck!\n"); +#ifndef BNX2X_STOP_ON_ERROR +unload_error: +#endif rc = bnx2x_func_stop(bp); if (rc) { BNX2X_ERR("Function stop failed!\n"); #ifdef BNX2X_STOP_ON_ERROR return; -#else - goto unload_error; -#endif - } -#ifndef BNX2X_STOP_ON_ERROR -unload_error: #endif - if (!BP_NOMCP(bp)) - reset_code = bnx2x_fw_command(bp, reset_code, 0); - else { - DP(NETIF_MSG_IFDOWN, "NO MCP - load counts[%d] " - "%d, %d, %d\n", BP_PATH(bp), - load_count[BP_PATH(bp)][0], - load_count[BP_PATH(bp)][1], - load_count[BP_PATH(bp)][2]); - load_count[BP_PATH(bp)][0]--; - load_count[BP_PATH(bp)][1 + port]--; - DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts[%d] " - "%d, %d, %d\n", BP_PATH(bp), - load_count[BP_PATH(bp)][0], load_count[BP_PATH(bp)][1], - load_count[BP_PATH(bp)][2]); - if (load_count[BP_PATH(bp)][0] == 0) - reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; - else if (load_count[BP_PATH(bp)][1 + port] == 0) - reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; - else - reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; } - if ((reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) || - (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT)) - bnx2x__link_reset(bp); + /* + * Send the UNLOAD_REQUEST to the MCP. This will return if + * this function should perform FUNC, PORT or COMMON HW + * reset. + */ + reset_code = bnx2x_send_unload_req(bp, unload_mode); /* Disable HW interrupts, NAPI */ bnx2x_netif_stop(bp, 1); @@ -6301,12 +7131,13 @@ unload_error: bnx2x_free_irq(bp); /* Reset the chip */ - bnx2x_reset_chip(bp, reset_code); + rc = bnx2x_reset_hw(bp, reset_code); + if (rc) + BNX2X_ERR("HW_RESET failed\n"); - /* Report UNLOAD_DONE to MCP */ - if (!BP_NOMCP(bp)) - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); + /* Report UNLOAD_DONE to MCP */ + bnx2x_send_unload_done(bp); } void bnx2x_disable_close_the_gate(struct bnx2x *bp) @@ -6323,7 +7154,7 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp) val = REG_RD(bp, addr); val &= ~(0x300); REG_WR(bp, addr, val); - } else if (CHIP_IS_E1H(bp)) { + } else { val = REG_RD(bp, MISC_REG_AEU_GENERAL_MASK); val &= ~(MISC_AEU_GENERAL_MASK_REG_AEU_PXP_CLOSE_MASK | MISC_AEU_GENERAL_MASK_REG_AEU_NIG_CLOSE_MASK); @@ -6820,8 +7651,8 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; /* save our pf_num */ int orig_pf_num = bp->pf_num; - u32 swap_en; - u32 swap_val; + int port; + u32 swap_en, swap_val, value; /* clear the UNDI indication */ REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); @@ -6856,21 +7687,19 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); bnx2x_undi_int_disable(bp); + port = BP_PORT(bp); /* close input traffic and wait for it */ /* Do not rcv packets to BRB */ - REG_WR(bp, - (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : - NIG_REG_LLH0_BRB1_DRV_MASK), 0x0); + REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK), 0x0); /* Do not direct rcv packets that are not for MCP to * the BRB */ - REG_WR(bp, - (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_NOT_MCP : - NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); + REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP : + NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); /* clear AEU */ - REG_WR(bp, - (BP_PORT(bp) ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : - MISC_REG_AEU_MASK_ATTN_FUNC_0), 0); + REG_WR(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0), 0); msleep(10); /* save NIG port swap info */ @@ -6880,9 +7709,17 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0xd3ffffff); + + value = 0x1400; + if (CHIP_IS_E3(bp)) { + value |= MISC_REGISTERS_RESET_REG_2_MSTAT0; + value |= MISC_REGISTERS_RESET_REG_2_MSTAT1; + } + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - 0x1403); + value); + /* take the NIG out of reset and restore swap values */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, @@ -6923,7 +7760,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) /* Set doorbell size */ bp->db_size = (1 << BNX2X_DB_SHIFT); - if (CHIP_IS_E2(bp)) { + if (!CHIP_IS_E1x(bp)) { val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR); if ((val & 1) == 0) val = REG_RD(bp, MISC_REG_PORT4MODE_EN); @@ -6943,16 +7780,6 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->pfid = bp->pf_num; /* 0..7 */ } - /* - * set base FW non-default (fast path) status block id, this value is - * used to initialize the fw_sb_id saved on the fp/queue structure to - * determine the id used by the FW. - */ - if (CHIP_IS_E1x(bp)) - bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; - else /* E2 */ - bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E2; - bp->link_params.chip_id = bp->common.chip_id; BNX2X_DEV_INFO("chip ID is 0x%x\n", id); @@ -6971,6 +7798,8 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bnx2x_init_shmem(bp); + + bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ? MISC_REG_GENERIC_CR_1 : MISC_REG_GENERIC_CR_0)); @@ -7080,8 +7909,14 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) } } } - bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, - NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); + + /* It's expected that number of CAM entries for this + * functions is equal to the MSI-X table size (which was a + * used during bp->l2_cid_count value calculation. + * We want a harsh warning if these values are different! + */ + WARN_ON(bp->igu_sb_cnt != NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); + if (bp->igu_sb_cnt == 0) BNX2X_ERR("CAM configuration error\n"); } @@ -7130,24 +7965,25 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, return; } - switch (switch_cfg) { - case SWITCH_CFG_1G: - bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + - port*0x10); - BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - break; - - case SWITCH_CFG_10G: - bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + - port*0x18); - BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - break; - - default: - BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", - bp->port.link_config[0]); - return; + if (CHIP_IS_E3(bp)) + bp->port.phy_addr = REG_RD(bp, MISC_REG_WC0_CTRL_PHY_ADDR); + else { + switch (switch_cfg) { + case SWITCH_CFG_1G: + bp->port.phy_addr = REG_RD( + bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + port*0x10); + break; + case SWITCH_CFG_10G: + bp->port.phy_addr = REG_RD( + bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + port*0x18); + break; + default: + BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", + bp->port.link_config[0]); + return; + } } + BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); /* mask what we support according to speed_cap_mask per configuration */ for (idx = 0; idx < cfg_size; idx++) { if (!(bp->link_params.speed_cap_mask[idx] & @@ -7331,8 +8167,6 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_10G_CX4: - case PORT_FEATURE_LINK_SPEED_10G_KX4: - case PORT_FEATURE_LINK_SPEED_10G_KR: if (bp->port.supported[idx] & SUPPORTED_10000baseT_Full) { bp->link_params.req_line_speed[idx] = @@ -7503,6 +8337,9 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) u8 *fip_mac = bp->fip_mac; #endif + /* Zero primary MAC configuration */ + memset(bp->dev->dev_addr, 0, ETH_ALEN); + if (BP_NOMCP(bp)) { BNX2X_ERROR("warning: random MAC workaround active\n"); random_ether_addr(bp->dev->dev_addr); @@ -7524,9 +8361,10 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) iscsi_mac_addr_upper); val = MF_CFG_RD(bp, func_ext_config[func]. iscsi_mac_addr_lower); - BNX2X_DEV_INFO("Read iSCSI MAC: " - "0x%x:0x%04x\n", val2, val); bnx2x_set_mac_buf(iscsi_mac, val, val2); + BNX2X_DEV_INFO("Read iSCSI MAC: " + BNX2X_MAC_FMT"\n", + BNX2X_MAC_PRN_LIST(iscsi_mac)); } else bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; @@ -7535,9 +8373,10 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) fcoe_mac_addr_upper); val = MF_CFG_RD(bp, func_ext_config[func]. fcoe_mac_addr_lower); - BNX2X_DEV_INFO("Read FCoE MAC to " - "0x%x:0x%04x\n", val2, val); bnx2x_set_mac_buf(fip_mac, val, val2); + BNX2X_DEV_INFO("Read FCoE L2 MAC to " + BNX2X_MAC_FMT"\n", + BNX2X_MAC_PRN_LIST(fip_mac)); } else bp->flags |= NO_FCOE_FLAG; @@ -7586,6 +8425,13 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) memset(bp->fip_mac, 0, ETH_ALEN); } #endif + + if (!is_valid_ether_addr(bp->dev->dev_addr)) + dev_err(&bp->pdev->dev, + "bad Ethernet MAC address configuration: " + BNX2X_MAC_FMT", change it manually before bringing up " + "the appropriate network interface\n", + BNX2X_MAC_PRN_LIST(bp->dev->dev_addr)); } static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) @@ -7607,17 +8453,55 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } else { bp->common.int_block = INT_BLOCK_IGU; val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); + + if (val & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN) { + int tout = 5000; + + BNX2X_DEV_INFO("FORCING Normal Mode\n"); + + val &= ~(IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN); + REG_WR(bp, IGU_REG_BLOCK_CONFIGURATION, val); + REG_WR(bp, IGU_REG_RESET_MEMORIES, 0x7f); + + while (tout && REG_RD(bp, IGU_REG_RESET_MEMORIES)) { + tout--; + usleep_range(1000, 1000); + } + + if (REG_RD(bp, IGU_REG_RESET_MEMORIES)) { + dev_err(&bp->pdev->dev, + "FORCING Normal Mode failed!!!\n"); + return -EPERM; + } + } + if (val & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN) { - DP(NETIF_MSG_PROBE, "IGU Backward Compatible Mode\n"); + BNX2X_DEV_INFO("IGU Backward Compatible Mode\n"); bp->common.int_block |= INT_BLOCK_MODE_BW_COMP; } else - DP(NETIF_MSG_PROBE, "IGU Normal Mode\n"); + BNX2X_DEV_INFO("IGU Normal Mode\n"); bnx2x_get_igu_cam_info(bp); } - DP(NETIF_MSG_PROBE, "igu_dsb_id %d igu_base_sb %d igu_sb_cnt %d\n", - bp->igu_dsb_id, bp->igu_base_sb, bp->igu_sb_cnt); + + /* + * set base FW non-default (fast path) status block id, this value is + * used to initialize the fw_sb_id saved on the fp/queue structure to + * determine the id used by the FW. + */ + if (CHIP_IS_E1x(bp)) + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x + BP_L_ID(bp); + else /* + * 57712 - we currently use one FW SB per IGU SB (Rx and Tx of + * the same queue are indicated on the same IGU SB). So we prefer + * FW and IGU SBs to be the same value. + */ + bp->base_fw_ndsb = bp->igu_base_sb; + + BNX2X_DEV_INFO("igu_dsb_id %d igu_base_sb %d igu_sb_cnt %d\n" + "base_fw_ndsb %d\n", bp->igu_dsb_id, bp->igu_base_sb, + bp->igu_sb_cnt, bp->base_fw_ndsb); /* * Initialize MF configuration @@ -7628,10 +8512,10 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) vn = BP_E1HVN(bp); if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { - DP(NETIF_MSG_PROBE, - "shmem2base 0x%x, size %d, mfcfg offset %d\n", - bp->common.shmem2_base, SHMEM2_RD(bp, size), - (u32)offsetof(struct shmem2_region, mf_cfg_addr)); + BNX2X_DEV_INFO("shmem2base 0x%x, size %d, mfcfg offset %d\n", + bp->common.shmem2_base, SHMEM2_RD(bp, size), + (u32)offsetof(struct shmem2_region, mf_cfg_addr)); + if (SHMEM2_HAS(bp, mf_cfg_addr)) bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); else @@ -7662,8 +8546,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); } else - DP(NETIF_MSG_PROBE, "illegal MAC " - "address for SI\n"); + BNX2X_DEV_INFO("illegal MAC address " + "for SI\n"); break; case SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED: /* get OV configuration */ @@ -7696,13 +8580,16 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { bp->mf_ov = val; - BNX2X_DEV_INFO("MF OV for func %d is %d" - " (0x%04x)\n", func, - bp->mf_ov, bp->mf_ov); + bp->path_has_ovlan = true; + + BNX2X_DEV_INFO("MF OV for func %d is %d " + "(0x%04x)\n", func, bp->mf_ov, + bp->mf_ov); } else { - BNX2X_ERR("No valid MF OV for func %d," - " aborting\n", func); - rc = -EPERM; + dev_err(&bp->pdev->dev, + "No valid MF OV for func %d, " + "aborting\n", func); + return -EPERM; } break; case MULTI_FUNCTION_SI: @@ -7711,31 +8598,40 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) break; default: if (vn) { - BNX2X_ERR("VN %d in single function mode," - " aborting\n", vn); - rc = -EPERM; + dev_err(&bp->pdev->dev, + "VN %d is in a single function mode, " + "aborting\n", vn); + return -EPERM; } break; } + /* check if other port on the path needs ovlan: + * Since MF configuration is shared between ports + * Possible mixed modes are only + * {SF, SI} {SF, SD} {SD, SF} {SI, SF} + */ + if (CHIP_MODE_IS_4_PORT(bp) && + !bp->path_has_ovlan && + !IS_MF(bp) && + bp->common.mf_cfg_base != SHMEM_MF_CFG_ADDR_NONE) { + u8 other_port = !BP_PORT(bp); + u8 other_func = BP_PATH(bp) + 2*other_port; + val = MF_CFG_RD(bp, + func_mf_config[other_func].e1hov_tag); + if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) + bp->path_has_ovlan = true; + } } /* adjust igu_sb_cnt to MF for E1x */ if (CHIP_IS_E1x(bp) && IS_MF(bp)) bp->igu_sb_cnt /= E1HVN_MAX; - /* - * adjust E2 sb count: to be removed when FW will support - * more then 16 L2 clients - */ -#define MAX_L2_CLIENTS 16 - if (CHIP_IS_E2(bp)) - bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, - MAX_L2_CLIENTS / (IS_MF(bp) ? 4 : 1)); + /* port info */ + bnx2x_get_port_hwinfo(bp); if (!BP_NOMCP(bp)) { - bnx2x_get_port_hwinfo(bp); - bp->fw_seq = (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); @@ -7749,6 +8645,16 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bnx2x_get_cnic_info(bp); #endif + /* Get current FW pulse sequence */ + if (!BP_NOMCP(bp)) { + int mb_idx = BP_FW_MB_IDX(bp); + + bp->fw_drv_pulse_wr_seq = + (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & + DRV_PULSE_SEQ_MASK); + BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); + } + return rc; } @@ -7816,6 +8722,55 @@ out_not_found: return; } +static void __devinit bnx2x_set_modes_bitmap(struct bnx2x *bp) +{ + u32 flags = 0; + + if (CHIP_REV_IS_FPGA(bp)) + SET_FLAGS(flags, MODE_FPGA); + else if (CHIP_REV_IS_EMUL(bp)) + SET_FLAGS(flags, MODE_EMUL); + else + SET_FLAGS(flags, MODE_ASIC); + + if (CHIP_MODE_IS_4_PORT(bp)) + SET_FLAGS(flags, MODE_PORT4); + else + SET_FLAGS(flags, MODE_PORT2); + + if (CHIP_IS_E2(bp)) + SET_FLAGS(flags, MODE_E2); + else if (CHIP_IS_E3(bp)) { + SET_FLAGS(flags, MODE_E3); + if (CHIP_REV(bp) == CHIP_REV_Ax) + SET_FLAGS(flags, MODE_E3_A0); + else {/*if (CHIP_REV(bp) == CHIP_REV_Bx)*/ + SET_FLAGS(flags, MODE_E3_B0); + SET_FLAGS(flags, MODE_COS_BC); + } + } + + if (IS_MF(bp)) { + SET_FLAGS(flags, MODE_MF); + switch (bp->mf_mode) { + case MULTI_FUNCTION_SD: + SET_FLAGS(flags, MODE_MF_SD); + break; + case MULTI_FUNCTION_SI: + SET_FLAGS(flags, MODE_MF_SI); + break; + } + } else + SET_FLAGS(flags, MODE_SF); + +#if defined(__LITTLE_ENDIAN) + SET_FLAGS(flags, MODE_LITTLE_ENDIAN); +#else /*(__BIG_ENDIAN)*/ + SET_FLAGS(flags, MODE_BIG_ENDIAN); +#endif + INIT_MODE_FLAGS(bp) = flags; +} + static int __devinit bnx2x_init_bp(struct bnx2x *bp) { int func; @@ -7833,9 +8788,14 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) INIT_DELAYED_WORK(&bp->reset_task, bnx2x_reset_task); rc = bnx2x_get_hwinfo(bp); + if (rc) + return rc; - if (!rc) - rc = bnx2x_alloc_mem_bp(bp); + bnx2x_set_modes_bitmap(bp); + + rc = bnx2x_alloc_mem_bp(bp); + if (rc) + return rc; bnx2x_read_fwinfo(bp); @@ -7888,6 +8848,13 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON); bnx2x_dcbx_init_params(bp); +#ifdef BCM_CNIC + if (CHIP_IS_E1x(bp)) + bp->cnic_base_cl_id = FP_SB_MAX_E1x; + else + bp->cnic_base_cl_id = FP_SB_MAX_E2; +#endif + return rc; } @@ -7896,6 +8863,10 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) * General service functions ****************************************************************************/ +/* + * net_device service functions + */ + /* called with rtnl_lock */ static int bnx2x_open(struct net_device *dev) { @@ -7954,193 +8925,119 @@ static int bnx2x_close(struct net_device *dev) return 0; } -#define E1_MAX_UC_LIST 29 -#define E1H_MAX_UC_LIST 30 -#define E2_MAX_UC_LIST 14 -static inline u8 bnx2x_max_uc_list(struct bnx2x *bp) +static inline int bnx2x_init_mcast_macs_list(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p) { - if (CHIP_IS_E1(bp)) - return E1_MAX_UC_LIST; - else if (CHIP_IS_E1H(bp)) - return E1H_MAX_UC_LIST; - else - return E2_MAX_UC_LIST; -} + int mc_count = netdev_mc_count(bp->dev); + struct bnx2x_mcast_list_elem *mc_mac = + kzalloc(sizeof(*mc_mac) * mc_count, GFP_ATOMIC); + struct netdev_hw_addr *ha; + if (!mc_mac) + return -ENOMEM; -static inline u8 bnx2x_uc_list_cam_offset(struct bnx2x *bp) -{ - if (CHIP_IS_E1(bp)) - /* CAM Entries for Port0: - * 0 - prim ETH MAC - * 1 - BCAST MAC - * 2 - iSCSI L2 ring ETH MAC - * 3-31 - UC MACs - * - * Port1 entries are allocated the same way starting from - * entry 32. - */ - return 3 + 32 * BP_PORT(bp); - else if (CHIP_IS_E1H(bp)) { - /* CAM Entries: - * 0-7 - prim ETH MAC for each function - * 8-15 - iSCSI L2 ring ETH MAC for each function - * 16 till 255 UC MAC lists for each function - * - * Remark: There is no FCoE support for E1H, thus FCoE related - * MACs are not considered. - */ - return E1H_FUNC_MAX * (CAM_ISCSI_ETH_LINE + 1) + - bnx2x_max_uc_list(bp) * BP_FUNC(bp); - } else { - /* CAM Entries (there is a separate CAM per engine): - * 0-4 - prim ETH MAC for each function - * 4-7 - iSCSI L2 ring ETH MAC for each function - * 8-11 - FIP ucast L2 MAC for each function - * 12-15 - ALL_ENODE_MACS mcast MAC for each function - * 16 till 71 UC MAC lists for each function - */ - u8 func_idx = - (CHIP_MODE_IS_4_PORT(bp) ? BP_FUNC(bp) : BP_VN(bp)); + INIT_LIST_HEAD(&p->mcast_list); - return E2_FUNC_MAX * (CAM_MAX_PF_LINE + 1) + - bnx2x_max_uc_list(bp) * func_idx; + netdev_for_each_mc_addr(ha, bp->dev) { + mc_mac->mac = bnx2x_mc_addr(ha); + list_add_tail(&mc_mac->link, &p->mcast_list); + mc_mac++; } + + p->mcast_list_len = mc_count; + + return 0; } -/* set uc list, do not wait as wait implies sleep and - * set_rx_mode can be invoked from non-sleepable context. +static inline void bnx2x_free_mcast_macs_list( + struct bnx2x_mcast_ramrod_params *p) +{ + struct bnx2x_mcast_list_elem *mc_mac = + list_first_entry(&p->mcast_list, struct bnx2x_mcast_list_elem, + link); + + WARN_ON(!mc_mac); + kfree(mc_mac); +} + +/** + * bnx2x_set_uc_list - configure a new unicast MACs list. + * + * @bp: driver handle * - * Instead we use the same ramrod data buffer each time we need - * to configure a list of addresses, and use the fact that the - * list of MACs is changed in an incremental way and that the - * function is called under the netif_addr_lock. A temporary - * inconsistent CAM configuration (possible in case of very fast - * sequence of add/del/add on the host side) will shortly be - * restored by the handler of the last ramrod. + * We will use zero (0) as a MAC type for these MACs. */ -static int bnx2x_set_uc_list(struct bnx2x *bp) +static inline int bnx2x_set_uc_list(struct bnx2x *bp) { - int i = 0, old; + int rc; struct net_device *dev = bp->dev; - u8 offset = bnx2x_uc_list_cam_offset(bp); struct netdev_hw_addr *ha; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config); + struct bnx2x_vlan_mac_obj *mac_obj = &bp->fp->mac_obj; + unsigned long ramrod_flags = 0; - if (netdev_uc_count(dev) > bnx2x_max_uc_list(bp)) - return -EINVAL; + /* First schedule a cleanup up of old configuration */ + rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_UC_LIST_MAC, false); + if (rc < 0) { + BNX2X_ERR("Failed to schedule DELETE operations: %d\n", rc); + return rc; + } netdev_for_each_uc_addr(ha, dev) { - /* copy mac */ - config_cmd->config_table[i].msb_mac_addr = - swab16(*(u16 *)&bnx2x_uc_addr(ha)[0]); - config_cmd->config_table[i].middle_mac_addr = - swab16(*(u16 *)&bnx2x_uc_addr(ha)[2]); - config_cmd->config_table[i].lsb_mac_addr = - swab16(*(u16 *)&bnx2x_uc_addr(ha)[4]); - - config_cmd->config_table[i].vlan_id = 0; - config_cmd->config_table[i].pf_id = BP_FUNC(bp); - config_cmd->config_table[i].clients_bit_vector = - cpu_to_le32(1 << BP_L_ID(bp)); - - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_SET); - - DP(NETIF_MSG_IFUP, - "setting UCAST[%d] (%04x:%04x:%04x)\n", i, - config_cmd->config_table[i].msb_mac_addr, - config_cmd->config_table[i].middle_mac_addr, - config_cmd->config_table[i].lsb_mac_addr); - - i++; - - /* Set uc MAC in NIG */ - bnx2x_set_mac_in_nig(bp, 1, bnx2x_uc_addr(ha), - LLH_CAM_ETH_LINE + i); - } - old = config_cmd->hdr.length; - if (old > i) { - for (; i < old; i++) { - if (CAM_IS_INVALID(config_cmd-> - config_table[i])) { - /* already invalidated */ - break; - } - /* invalidate */ - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); + rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, + BNX2X_UC_LIST_MAC, &ramrod_flags); + if (rc < 0) { + BNX2X_ERR("Failed to schedule ADD operations: %d\n", + rc); + return rc; } } - wmb(); - - config_cmd->hdr.length = i; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* Mark that this ramrod doesn't use bp->set_mac_pending for - * synchronization. - */ - config_cmd->hdr.echo = 0; - - mb(); - - return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); - + /* Execute the pending commands */ + __set_bit(RAMROD_CONT, &ramrod_flags); + return bnx2x_set_mac_one(bp, NULL, mac_obj, false /* don't care */, + BNX2X_UC_LIST_MAC, &ramrod_flags); } -void bnx2x_invalidate_uc_list(struct bnx2x *bp) +static inline int bnx2x_set_mc_list(struct bnx2x *bp) { - int i; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config); - int ramrod_flags = WAIT_RAMROD_COMMON; - u8 offset = bnx2x_uc_list_cam_offset(bp); - u8 max_list_size = bnx2x_max_uc_list(bp); - - for (i = 0; i < max_list_size; i++) { - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); - bnx2x_set_mac_in_nig(bp, 0, NULL, LLH_CAM_ETH_LINE + 1 + i); - } - - wmb(); + struct net_device *dev = bp->dev; + struct bnx2x_mcast_ramrod_params rparam = {0}; + int rc = 0; - config_cmd->hdr.length = max_list_size; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* We'll wait for a completion this time... */ - config_cmd->hdr.echo = 1; + rparam.mcast_obj = &bp->mcast_obj; - bp->set_mac_pending = 1; + /* first, clear all configured multicast MACs */ + rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL); + if (rc < 0) { + BNX2X_ERR("Failed to clear multicast " + "configuration: %d\n", rc); + return rc; + } - mb(); + /* then, configure a new MACs list */ + if (netdev_mc_count(dev)) { + rc = bnx2x_init_mcast_macs_list(bp, &rparam); + if (rc) { + BNX2X_ERR("Failed to create multicast MACs " + "list: %d\n", rc); + return rc; + } - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); + /* Now add the new MACs */ + rc = bnx2x_config_mcast(bp, &rparam, + BNX2X_MCAST_CMD_ADD); + if (rc < 0) + BNX2X_ERR("Failed to set a new multicast " + "configuration: %d\n", rc); - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, - ramrod_flags); + bnx2x_free_mcast_macs_list(&rparam); + } + return rc; } -static inline int bnx2x_set_mc_list(struct bnx2x *bp) -{ - /* some multicasts */ - if (CHIP_IS_E1(bp)) { - return bnx2x_set_e1_mc_list(bp); - } else { /* E1H and newer */ - return bnx2x_set_e1h_mc_list(bp); - } -} -/* called with netif_tx_lock from dev_mcast.c */ +/* If bp->state is OPEN, should be called with netif_addr_lock_bh() */ void bnx2x_set_rx_mode(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); @@ -8151,23 +9048,31 @@ void bnx2x_set_rx_mode(struct net_device *dev) return; } - DP(NETIF_MSG_IFUP, "dev->flags = %x\n", dev->flags); + DP(NETIF_MSG_IFUP, "dev->flags = %x\n", bp->dev->flags); if (dev->flags & IFF_PROMISC) rx_mode = BNX2X_RX_MODE_PROMISC; - else if (dev->flags & IFF_ALLMULTI) + else if ((dev->flags & IFF_ALLMULTI) || + ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) && + CHIP_IS_E1(bp))) rx_mode = BNX2X_RX_MODE_ALLMULTI; else { /* some multicasts */ - if (bnx2x_set_mc_list(bp)) + if (bnx2x_set_mc_list(bp) < 0) rx_mode = BNX2X_RX_MODE_ALLMULTI; - /* some unicasts */ - if (bnx2x_set_uc_list(bp)) + if (bnx2x_set_uc_list(bp) < 0) rx_mode = BNX2X_RX_MODE_PROMISC; } bp->rx_mode = rx_mode; + + /* Schedule the rx_mode command */ + if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state)) { + set_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state); + return; + } + bnx2x_set_storm_rx_mode(bp); } @@ -8258,8 +9163,28 @@ static const struct net_device_ops bnx2x_netdev_ops = { #endif }; +static inline int bnx2x_set_coherency_mask(struct bnx2x *bp) +{ + struct device *dev = &bp->pdev->dev; + + if (dma_set_mask(dev, DMA_BIT_MASK(64)) == 0) { + bp->flags |= USING_DAC_FLAG; + if (dma_set_coherent_mask(dev, DMA_BIT_MASK(64)) != 0) { + dev_err(dev, "dma_set_coherent_mask failed, " + "aborting\n"); + return -EIO; + } + } else if (dma_set_mask(dev, DMA_BIT_MASK(32)) != 0) { + dev_err(dev, "System does not support DMA, aborting\n"); + return -EIO; + } + + return 0; +} + static int __devinit bnx2x_init_dev(struct pci_dev *pdev, - struct net_device *dev) + struct net_device *dev, + unsigned long board_type) { struct bnx2x *bp; int rc; @@ -8321,21 +9246,9 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, goto err_out_release; } - if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) == 0) { - bp->flags |= USING_DAC_FLAG; - if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)) != 0) { - dev_err(&bp->pdev->dev, "dma_set_coherent_mask" - " failed, aborting\n"); - rc = -EIO; - goto err_out_release; - } - - } else if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0) { - dev_err(&bp->pdev->dev, - "System does not support DMA, aborting\n"); - rc = -EIO; + rc = bnx2x_set_coherency_mask(bp); + if (rc) goto err_out_release; - } dev->mem_start = pci_resource_start(pdev, 0); dev->base_addr = dev->mem_start; @@ -8371,6 +9284,12 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(bp)*16, 0); REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(bp)*16, 0); + /** + * Enable internal target-read (in case we are probed after PF FLR). + * Must be done prior to any BAR read access + */ + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); + /* Reset the load counter */ bnx2x_clear_load_cnt(bp); @@ -8585,7 +9504,7 @@ int bnx2x_init_firmware(struct bnx2x *bp) fw_file_name = FW_FILE_NAME_E1; else if (CHIP_IS_E1H(bp)) fw_file_name = FW_FILE_NAME_E1H; - else if (CHIP_IS_E2(bp)) + else if (!CHIP_IS_E1x(bp)) fw_file_name = FW_FILE_NAME_E2; else { BNX2X_ERR("Unsupported chip revision\n"); @@ -8653,6 +9572,44 @@ request_firmware_exit: return rc; } +static void bnx2x_release_firmware(struct bnx2x *bp) +{ + kfree(bp->init_ops_offsets); + kfree(bp->init_ops); + kfree(bp->init_data); + release_firmware(bp->firmware); +} + + +static struct bnx2x_func_sp_drv_ops bnx2x_func_sp_drv = { + .init_hw_cmn_chip = bnx2x_init_hw_common_chip, + .init_hw_cmn = bnx2x_init_hw_common, + .init_hw_port = bnx2x_init_hw_port, + .init_hw_func = bnx2x_init_hw_func, + + .reset_hw_cmn = bnx2x_reset_common, + .reset_hw_port = bnx2x_reset_port, + .reset_hw_func = bnx2x_reset_func, + + .gunzip_init = bnx2x_gunzip_init, + .gunzip_end = bnx2x_gunzip_end, + + .init_fw = bnx2x_init_firmware, + .release_fw = bnx2x_release_firmware, +}; + +void bnx2x__init_func_obj(struct bnx2x *bp) +{ + /* Prepare DMAE related driver resources */ + bnx2x_setup_dmae(bp); + + bnx2x_init_func_obj(bp, &bp->func_obj, + bnx2x_sp(bp, func_rdata), + bnx2x_sp_mapping(bp, func_rdata), + &bnx2x_func_sp_drv); +} + +/* must be called after sriov-enable */ static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) { int cid_count = L2_FP_COUNT(l2_cid_count); @@ -8663,6 +9620,25 @@ static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) return roundup(cid_count, QM_CID_ROUND); } +/** + * bnx2x_pci_msix_table_size - get the size of the MSI-X table. + * + * @dev: pci device + * + */ +static inline int bnx2x_pci_msix_table_size(struct pci_dev *pdev) +{ + int pos; + u16 control; + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (!pos) + return 0; + + pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &control); + return (control & PCI_MSIX_FLAGS_QSIZE) + 1; +} + static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -8675,12 +9651,28 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, case BCM57710: case BCM57711: case BCM57711E: - cid_count = FP_SB_MAX_E1x; - break; - case BCM57712: - case BCM57712E: - cid_count = FP_SB_MAX_E2; + case BCM57712_MF: + case BCM57800: + case BCM57800_MF: + case BCM57810: + case BCM57810_MF: + case BCM57840: + case BCM57840_MF: + /* The size requested for the MSI-X table corresponds to the + * actual amount of avaliable IGU/HC status blocks. It includes + * the default SB vector but we want cid_count to contain the + * amount of only non-default SBs, that's what '-1' stands for. + */ + cid_count = bnx2x_pci_msix_table_size(pdev) - 1; + + /* do not allow initial cid_count grow above 16 + * since Special CIDs starts from this number + * use old FP_SB_MAX_E1x define for this matter + */ + cid_count = min_t(int, FP_SB_MAX_E1x, cid_count); + + WARN_ON(!cid_count); break; default: @@ -8689,7 +9681,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return -ENODEV; } - cid_count += NONE_ETH_CONTEXT_USE + CNIC_CONTEXT_USE; + cid_count += FCOE_CONTEXT_USE; /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mq(sizeof(*bp), cid_count); @@ -8698,6 +9690,11 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return -ENOMEM; } + /* We don't need a Tx queue for a CNIC and an OOO Rx-only ring, + * so update a cid_count after a netdev allocation. + */ + cid_count += CNIC_CONTEXT_USE; + bp = netdev_priv(dev); bp->msg_enable = debug; @@ -8705,12 +9702,14 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, bp->l2_cid_count = cid_count; - rc = bnx2x_init_dev(pdev, dev); + rc = bnx2x_init_dev(pdev, dev, ent->driver_data); if (rc < 0) { free_netdev(dev); return rc; } + BNX2X_DEV_INFO("cid_count=%d\n", cid_count); + rc = bnx2x_init_bp(bp); if (rc) goto init_one_exit; @@ -8847,12 +9846,17 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) bp->rx_mode = BNX2X_RX_MODE_NONE; +#ifdef BCM_CNIC + bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); +#endif + /* Stop Tx */ + bnx2x_tx_disable(bp); + bnx2x_netif_stop(bp, 0); - netif_carrier_off(bp->dev); del_timer_sync(&bp->timer); - bp->stats_state = STATS_STATE_DISABLED; - DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); + + bnx2x_stats_handle(bp, STATS_EVENT_STOP); /* Release IRQs */ bnx2x_free_irq(bp); @@ -8867,6 +9871,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) bp->state = BNX2X_STATE_CLOSED; + netif_carrier_off(bp->dev); + return 0; } @@ -9043,6 +10049,24 @@ module_init(bnx2x_init); module_exit(bnx2x_cleanup); #ifdef BCM_CNIC +/** + * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s). + * + * @bp: driver handle + * @set: set or clear the CAM entry + * + * This function will wait until the ramdord completion returns. + * Return 0 if success, -ENODEV if ramrod doesn't return. + */ +static inline int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp) +{ + unsigned long ramrod_flags = 0; + + __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); + return bnx2x_set_mac_one(bp, bp->cnic_eth_dev.iscsi_mac, + &bp->iscsi_l2_mac_obj, true, + BNX2X_ISCSI_ETH_MAC, &ramrod_flags); +} /* count denotes the number of new completions we have seen */ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) @@ -9063,23 +10087,22 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) u16 type = (le16_to_cpu(bp->cnic_kwq_cons->hdr.type) & SPE_HDR_CONN_TYPE) >> SPE_HDR_CONN_TYPE_SHIFT; + u8 cmd = (le32_to_cpu(bp->cnic_kwq_cons->hdr.conn_and_cmd_data) + >> SPE_HDR_CMD_ID_SHIFT) & 0xff; /* Set validation for iSCSI L2 client before sending SETUP * ramrod */ if (type == ETH_CONNECTION_TYPE) { - u8 cmd = (le32_to_cpu(bp->cnic_kwq_cons-> - hdr.conn_and_cmd_data) >> - SPE_HDR_CMD_ID_SHIFT) & 0xff; - if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) - bnx2x_set_ctx_validation(&bp->context. - vcxt[BNX2X_ISCSI_ETH_CID].eth, - HW_CID(bp, BNX2X_ISCSI_ETH_CID)); + bnx2x_set_ctx_validation(bp, &bp->context. + vcxt[BNX2X_ISCSI_ETH_CID].eth, + BNX2X_ISCSI_ETH_CID); } - /* There may be not more than 8 L2 and not more than 8 L5 SPEs - * We also check that the number of outstanding + /* + * There may be not more than 8 L2, not more than 8 L5 SPEs + * and in the air. We also check that number of outstanding * COMMON ramrods is not more than the EQ and SPQ can * accommodate. */ @@ -9205,18 +10228,61 @@ int bnx2x_cnic_notify(struct bnx2x *bp, int cmd) return bnx2x_cnic_ctl_send(bp, &ctl); } -static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid) +static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid, u8 err) { - struct cnic_ctl_info ctl; + struct cnic_ctl_info ctl = {0}; /* first we tell CNIC and only then we count this as a completion */ ctl.cmd = CNIC_CTL_COMPLETION_CMD; ctl.data.comp.cid = cid; + ctl.data.comp.error = err; bnx2x_cnic_ctl_send_bh(bp, &ctl); bnx2x_cnic_sp_post(bp, 0); } + +/* Called with netif_addr_lock_bh() taken. + * Sets an rx_mode config for an iSCSI ETH client. + * Doesn't block. + * Completion should be checked outside. + */ +static void bnx2x_set_iscsi_eth_rx_mode(struct bnx2x *bp, bool start) +{ + unsigned long accept_flags = 0, ramrod_flags = 0; + u8 cl_id = bnx2x_cnic_eth_cl_id(bp, BNX2X_ISCSI_ETH_CL_ID_IDX); + int sched_state = BNX2X_FILTER_ISCSI_ETH_STOP_SCHED; + + if (start) { + /* Start accepting on iSCSI L2 ring. Accept all multicasts + * because it's the only way for UIO Queue to accept + * multicasts (in non-promiscuous mode only one Queue per + * function will receive multicast packets (leading in our + * case). + */ + __set_bit(BNX2X_ACCEPT_UNICAST, &accept_flags); + __set_bit(BNX2X_ACCEPT_ALL_MULTICAST, &accept_flags); + __set_bit(BNX2X_ACCEPT_BROADCAST, &accept_flags); + __set_bit(BNX2X_ACCEPT_ANY_VLAN, &accept_flags); + + /* Clear STOP_PENDING bit if START is requested */ + clear_bit(BNX2X_FILTER_ISCSI_ETH_STOP_SCHED, &bp->sp_state); + + sched_state = BNX2X_FILTER_ISCSI_ETH_START_SCHED; + } else + /* Clear START_PENDING bit if STOP is requested */ + clear_bit(BNX2X_FILTER_ISCSI_ETH_START_SCHED, &bp->sp_state); + + if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state)) + set_bit(sched_state, &bp->sp_state); + else { + __set_bit(RAMROD_RX, &ramrod_flags); + bnx2x_set_q_rx_mode(bp, cl_id, 0, accept_flags, 0, + ramrod_flags); + } +} + + static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) { struct bnx2x *bp = netdev_priv(dev); @@ -9240,45 +10306,65 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) /* rtnl_lock is held. */ case DRV_CTL_START_L2_CMD: { - u32 cli = ctl->data.ring.client_id; - - /* Clear FCoE FIP and ALL ENODE MACs addresses first */ - bnx2x_del_fcoe_eth_macs(bp); + struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + unsigned long sp_bits = 0; + + /* Configure the iSCSI classification object */ + bnx2x_init_mac_obj(bp, &bp->iscsi_l2_mac_obj, + cp->iscsi_l2_client_id, + cp->iscsi_l2_cid, BP_FUNC(bp), + bnx2x_sp(bp, mac_rdata), + bnx2x_sp_mapping(bp, mac_rdata), + BNX2X_FILTER_MAC_PENDING, + &bp->sp_state, BNX2X_OBJ_TYPE_RX, + &bp->macs_pool); /* Set iSCSI MAC address */ - bnx2x_set_iscsi_eth_mac_addr(bp, 1); + rc = bnx2x_set_iscsi_eth_mac_addr(bp); + if (rc) + break; mmiowb(); barrier(); - /* Start accepting on iSCSI L2 ring. Accept all multicasts - * because it's the only way for UIO Client to accept - * multicasts (in non-promiscuous mode only one Client per - * function will receive multicast packets (leading in our - * case). - */ - bnx2x_rxq_set_mac_filters(bp, cli, - BNX2X_ACCEPT_UNICAST | - BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_ALL_MULTICAST); - storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + /* Start accepting on iSCSI L2 ring */ + + netif_addr_lock_bh(dev); + bnx2x_set_iscsi_eth_rx_mode(bp, true); + netif_addr_unlock_bh(dev); + + /* bits to wait on */ + __set_bit(BNX2X_FILTER_RX_MODE_PENDING, &sp_bits); + __set_bit(BNX2X_FILTER_ISCSI_ETH_START_SCHED, &sp_bits); + + if (!bnx2x_wait_sp_comp(bp, sp_bits)) + BNX2X_ERR("rx_mode completion timed out!\n"); break; } /* rtnl_lock is held. */ case DRV_CTL_STOP_L2_CMD: { - u32 cli = ctl->data.ring.client_id; + unsigned long sp_bits = 0; /* Stop accepting on iSCSI L2 ring */ - bnx2x_rxq_set_mac_filters(bp, cli, BNX2X_ACCEPT_NONE); - storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + netif_addr_lock_bh(dev); + bnx2x_set_iscsi_eth_rx_mode(bp, false); + netif_addr_unlock_bh(dev); + + /* bits to wait on */ + __set_bit(BNX2X_FILTER_RX_MODE_PENDING, &sp_bits); + __set_bit(BNX2X_FILTER_ISCSI_ETH_STOP_SCHED, &sp_bits); + + if (!bnx2x_wait_sp_comp(bp, sp_bits)) + BNX2X_ERR("rx_mode completion timed out!\n"); mmiowb(); barrier(); /* Unset iSCSI L2 MAC */ - bnx2x_set_iscsi_eth_mac_addr(bp, 0); + rc = bnx2x_del_all_macs(bp, &bp->iscsi_l2_mac_obj, + BNX2X_ISCSI_ETH_MAC, true); break; } case DRV_CTL_RET_L2_SPQ_CREDIT_CMD: { @@ -9290,11 +10376,6 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) break; } - case DRV_CTL_ISCSI_STOPPED_CMD: { - bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_ISCSI_STOPPED); - break; - } - default: BNX2X_ERR("unknown command %x\n", ctl->cmd); rc = -EINVAL; @@ -9315,13 +10396,13 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX; cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX; } - if (CHIP_IS_E2(bp)) + if (!CHIP_IS_E1x(bp)) cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e2_sb; else cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; - cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp); - cp->irq_arr[0].status_blk_num2 = CNIC_IGU_SB_ID(bp); + cp->irq_arr[0].status_blk_num = bnx2x_cnic_fw_sb_id(bp); + cp->irq_arr[0].status_blk_num2 = bnx2x_cnic_igu_sb_id(bp); cp->irq_arr[1].status_blk = bp->def_status_blk; cp->irq_arr[1].status_blk_num = DEF_SB_ID; cp->irq_arr[1].status_blk_num2 = DEF_SB_IGU_ID; @@ -9352,7 +10433,7 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, bp->cnic_data = data; cp->num_irq = 0; - cp->drv_state = CNIC_DRV_STATE_REGD; + cp->drv_state |= CNIC_DRV_STATE_REGD; cp->iro_arr = bp->iro_arr; bnx2x_setup_cnic_irq_info(bp); @@ -9406,8 +10487,8 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->drv_register_cnic = bnx2x_register_cnic; cp->drv_unregister_cnic = bnx2x_unregister_cnic; cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID; - cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID + - BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; + cp->iscsi_l2_client_id = + bnx2x_cnic_eth_cl_id(bp, BNX2X_ISCSI_ETH_CL_ID_IDX); cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; if (NO_ISCSI_OOO(bp)) diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 18ac2ab08f3..9868cb0270a 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -422,6 +422,7 @@ #define CFC_REG_NUM_LCIDS_ALLOC 0x104020 /* [R 9] Number of Arriving LCIDs in Link List Block */ #define CFC_REG_NUM_LCIDS_ARRIVING 0x104004 +#define CFC_REG_NUM_LCIDS_INSIDE_PF 0x104120 /* [R 9] Number of Leaving LCIDs in Link List Block */ #define CFC_REG_NUM_LCIDS_LEAVING 0x104018 #define CFC_REG_WEAK_ENABLE_PF 0x104124 @@ -783,6 +784,7 @@ /* [RW 3] The number of simultaneous outstanding requests to Context Fetch Interface. */ #define DORQ_REG_OUTST_REQ 0x17003c +#define DORQ_REG_PF_USAGE_CNT 0x1701d0 #define DORQ_REG_REGN 0x170038 /* [R 4] Current value of response A counter credit. Initial credit is configured through write to ~dorq_registers_rsp_init_crd.rsp_init_crd @@ -1645,6 +1647,17 @@ #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4) #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2) #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3) +/* [RW 5] MDIO PHY Address. The WC uses this address to determine whether or + * not it is the recipient of the message on the MDIO interface. The value + * is compared to the value on ctrl_md_devad. Drives output + * misc_xgxs0_phy_addr. Global register. */ +#define MISC_REG_WC0_CTRL_PHY_ADDR 0xa9cc +/* [RW 32] 1 [47] Packet Size = 64 Write to this register write bits 31:0. + * Reads from this register will clear bits 31:0. */ +#define MSTAT_REG_RX_STAT_GR64_LO 0x200 +/* [RW 32] 1 [00] Tx Good Packet Count Write to this register write bits + * 31:0. Reads from this register will clear bits 31:0. */ +#define MSTAT_REG_TX_STAT_GTXPOK_LO 0 #define NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN (0x1<<0) #define NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) @@ -1838,6 +1851,10 @@ #define NIG_REG_LLH1_FUNC_MEM 0x161c0 #define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160 #define NIG_REG_LLH1_FUNC_MEM_SIZE 16 +/* [RW 1] When this bit is set; the LLH will classify the packet before + * sending it to the BRB or calculating WoL on it. This bit controls port 1 + * only. The legacy llh_multi_function_mode bit controls port 0. */ +#define NIG_REG_LLH1_MF_MODE 0x18614 /* [RW 8] init credit counter for port1 in LLH */ #define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564 #define NIG_REG_LLH1_XCM_MASK 0x10134 @@ -1889,6 +1906,26 @@ * than one bit may be set; allowing multiple priorities to be mapped to one * COS. */ #define NIG_REG_P0_RX_COS1_PRIORITY_MASK 0x1805c +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 2. A + * priority is mapped to COS 2 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS2_PRIORITY_MASK 0x186b0 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 3. A + * priority is mapped to COS 3 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS3_PRIORITY_MASK 0x186b4 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 4. A + * priority is mapped to COS 4 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS4_PRIORITY_MASK 0x186b8 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 5. A + * priority is mapped to COS 5 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS5_PRIORITY_MASK 0x186bc /* [RW 15] Specify which of the credit registers the client is to be mapped * to. Bits[2:0] are for client 0; bits [14:12] are for client 4. For * clients that are not subject to WFQ credit blocking - their @@ -1926,6 +1963,9 @@ * for management at priority 0; debug traffic at priorities 1 and 2; COS0 * traffic at priority 3; and COS1 traffic at priority 4. */ #define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT 0x180e4 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define NIG_REG_P1_HDRS_AFTER_BASIC 0x1818c #define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 #define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460 /* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for @@ -1944,6 +1984,11 @@ * than one bit may be set; allowing multiple priorities to be mapped to one * COS. */ #define NIG_REG_P1_RX_COS1_PRIORITY_MASK 0x181b0 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 2. A + * priority is mapped to COS 2 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P1_RX_COS2_PRIORITY_MASK 0x186f8 /* [RW 1] Pause enable for port0. This register may get 1 only when ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same port */ @@ -2033,6 +2078,15 @@ #define PBF_REG_COS1_UPPER_BOUND 0x15c060 /* [RW 31] The weight of COS1 in the ETS command arbiter. */ #define PBF_REG_COS1_WEIGHT 0x15c058 +/* [R 11] Current credit for the LB queue in the tx port buffers in 16 byte + * lines. */ +#define PBF_REG_CREDIT_LB_Q 0x140338 +/* [R 11] Current credit for queue 0 in the tx port buffers in 16 byte + * lines. */ +#define PBF_REG_CREDIT_Q0 0x14033c +/* [R 11] Current credit for queue 1 in the tx port buffers in 16 byte + * lines. */ +#define PBF_REG_CREDIT_Q1 0x140340 /* [RW 1] Disable processing further tasks from port 0 (after ending the current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P0 0x14005c @@ -2050,14 +2104,25 @@ /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic * Ethernet header. */ #define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 -/* [RW 1] Indicates which COS is conncted to the highest priority in the - * command arbiter. */ +/* [RW 6] Bit-map indicating which L2 hdrs may appear after L2 tag 0 */ +#define PBF_REG_HDRS_AFTER_TAG_0 0x15c0b8 +/* [R 1] Removed for E3 B0 - Indicates which COS is conncted to the highest + * priority in the command arbiter. */ #define PBF_REG_HIGH_PRIORITY_COS_NUM 0x15c04c #define PBF_REG_IF_ENABLE_REG 0x140044 /* [RW 1] Init bit. When set the initial credits are copied to the credit registers (except the port credits). Should be set and then reset after the configuration of the block has ended. */ #define PBF_REG_INIT 0x140000 +/* [RW 11] Initial credit for the LB queue in the tx port buffers in 16 byte + * lines. */ +#define PBF_REG_INIT_CRD_LB_Q 0x15c248 +/* [RW 11] Initial credit for queue 0 in the tx port buffers in 16 byte + * lines. */ +#define PBF_REG_INIT_CRD_Q0 0x15c230 +/* [RW 11] Initial credit for queue 1 in the tx port buffers in 16 byte + * lines. */ +#define PBF_REG_INIT_CRD_Q1 0x15c234 /* [RW 1] Init bit for port 0. When set the initial credit of port 0 is copied to the credit register. Should be set and then reset after the configuration of the port has ended. */ @@ -2070,6 +2135,15 @@ copied to the credit register. Should be set and then reset after the configuration of the port has ended. */ #define PBF_REG_INIT_P4 0x14000c +/* [R 32] Cyclic counter for the amount credits in 16 bytes lines added for + * the LB queue. Reset upon init. */ +#define PBF_REG_INTERNAL_CRD_FREED_CNT_LB_Q 0x140354 +/* [R 32] Cyclic counter for the amount credits in 16 bytes lines added for + * queue 0. Reset upon init. */ +#define PBF_REG_INTERNAL_CRD_FREED_CNT_Q0 0x140358 +/* [R 32] Cyclic counter for the amount credits in 16 bytes lines added for + * queue 1. Reset upon init. */ +#define PBF_REG_INTERNAL_CRD_FREED_CNT_Q1 0x14035c /* [RW 1] Enable for mac interface 0. */ #define PBF_REG_MAC_IF0_ENABLE 0x140030 /* [RW 1] Enable for mac interface 1. */ @@ -2090,24 +2164,49 @@ /* [RW 11] Initial credit for port 0 in the tx port buffers in 16 byte lines. */ #define PBF_REG_P0_INIT_CRD 0x1400d0 -/* [RW 1] Indication that pause is enabled for port 0. */ -#define PBF_REG_P0_PAUSE_ENABLE 0x140014 -/* [R 8] Number of tasks in port 0 task queue. */ +/* [R 32] Cyclic counter for the amount credits in 16 bytes lines added for + * port 0. Reset upon init. */ +#define PBF_REG_P0_INTERNAL_CRD_FREED_CNT 0x140308 +/* [R 1] Removed for E3 B0 - Indication that pause is enabled for port 0. */ +#define PBF_REG_P0_PAUSE_ENABLE 0x140014 +/* [R 8] Removed for E3 B0 - Number of tasks in port 0 task queue. */ #define PBF_REG_P0_TASK_CNT 0x140204 -/* [R 11] Current credit for port 1 in the tx port buffers in 16 byte lines. */ +/* [R 32] Removed for E3 B0 - Cyclic counter for number of 8 byte lines + * freed from the task queue of port 0. Reset upon init. */ +#define PBF_REG_P0_TQ_LINES_FREED_CNT 0x1402f0 +/* [R 12] Number of 8 bytes lines occupied in the task queue of port 0. */ +#define PBF_REG_P0_TQ_OCCUPANCY 0x1402fc +/* [R 11] Removed for E3 B0 - Current credit for port 1 in the tx port + * buffers in 16 byte lines. */ #define PBF_REG_P1_CREDIT 0x140208 -/* [RW 11] Initial credit for port 1 in the tx port buffers in 16 byte - lines. */ +/* [R 11] Removed for E3 B0 - Initial credit for port 0 in the tx port + * buffers in 16 byte lines. */ #define PBF_REG_P1_INIT_CRD 0x1400d4 -/* [R 8] Number of tasks in port 1 task queue. */ +/* [R 32] Cyclic counter for the amount credits in 16 bytes lines added for + * port 1. Reset upon init. */ +#define PBF_REG_P1_INTERNAL_CRD_FREED_CNT 0x14030c +/* [R 8] Removed for E3 B0 - Number of tasks in port 1 task queue. */ #define PBF_REG_P1_TASK_CNT 0x14020c +/* [R 32] Removed for E3 B0 - Cyclic counter for number of 8 byte lines + * freed from the task queue of port 1. Reset upon init. */ +#define PBF_REG_P1_TQ_LINES_FREED_CNT 0x1402f4 +/* [R 12] Number of 8 bytes lines occupied in the task queue of port 1. */ +#define PBF_REG_P1_TQ_OCCUPANCY 0x140300 /* [R 11] Current credit for port 4 in the tx port buffers in 16 byte lines. */ #define PBF_REG_P4_CREDIT 0x140210 /* [RW 11] Initial credit for port 4 in the tx port buffers in 16 byte lines. */ #define PBF_REG_P4_INIT_CRD 0x1400e0 -/* [R 8] Number of tasks in port 4 task queue. */ +/* [R 32] Cyclic counter for the amount credits in 16 bytes lines added for + * port 4. Reset upon init. */ +#define PBF_REG_P4_INTERNAL_CRD_FREED_CNT 0x140310 +/* [R 8] Removed for E3 B0 - Number of tasks in port 4 task queue. */ #define PBF_REG_P4_TASK_CNT 0x140214 +/* [R 32] Removed for E3 B0 - Cyclic counter for number of 8 byte lines + * freed from the task queue of port 4. Reset upon init. */ +#define PBF_REG_P4_TQ_LINES_FREED_CNT 0x1402f8 +/* [R 12] Number of 8 bytes lines occupied in the task queue of port 4. */ +#define PBF_REG_P4_TQ_OCCUPANCY 0x140304 /* [RW 5] Interrupt mask register #0 read/write */ #define PBF_REG_PBF_INT_MASK 0x1401d4 /* [R 5] Interrupt register #0 read */ @@ -2116,6 +2215,27 @@ #define PBF_REG_PBF_PRTY_MASK 0x1401e4 /* [RC 20] Parity register #0 read clear */ #define PBF_REG_PBF_PRTY_STS_CLR 0x1401dc +/* [RW 16] The Ethernet type value for L2 tag 0 */ +#define PBF_REG_TAG_ETHERTYPE_0 0x15c090 +/* [RW 4] The length of the info field for L2 tag 0. The length is between + * 2B and 14B; in 2B granularity */ +#define PBF_REG_TAG_LEN_0 0x15c09c +/* [R 32] Cyclic counter for number of 8 byte lines freed from the LB task + * queue. Reset upon init. */ +#define PBF_REG_TQ_LINES_FREED_CNT_LB_Q 0x14038c +/* [R 32] Cyclic counter for number of 8 byte lines freed from the task + * queue 0. Reset upon init. */ +#define PBF_REG_TQ_LINES_FREED_CNT_Q0 0x140390 +/* [R 32] Cyclic counter for number of 8 byte lines freed from task queue 1. + * Reset upon init. */ +#define PBF_REG_TQ_LINES_FREED_CNT_Q1 0x140394 +/* [R 13] Number of 8 bytes lines occupied in the task queue of the LB + * queue. */ +#define PBF_REG_TQ_OCCUPANCY_LB_Q 0x1403a8 +/* [R 13] Number of 8 bytes lines occupied in the task queue of queue 0. */ +#define PBF_REG_TQ_OCCUPANCY_Q0 0x1403ac +/* [R 13] Number of 8 bytes lines occupied in the task queue of queue 1. */ +#define PBF_REG_TQ_OCCUPANCY_Q1 0x1403b0 #define PB_REG_CONTROL 0 /* [RW 2] Interrupt mask register #0 read/write */ #define PB_REG_PB_INT_MASK 0x28 @@ -2445,10 +2565,24 @@ /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic * Ethernet header. */ #define PRS_REG_HDRS_AFTER_BASIC 0x40238 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header for port 0 packets. */ +#define PRS_REG_HDRS_AFTER_BASIC_PORT_0 0x40270 +#define PRS_REG_HDRS_AFTER_BASIC_PORT_1 0x40290 +/* [R 6] Bit-map indicating which L2 hdrs may appear after L2 tag 0 */ +#define PRS_REG_HDRS_AFTER_TAG_0 0x40248 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after L2 tag 0 for + * port 0 packets */ +#define PRS_REG_HDRS_AFTER_TAG_0_PORT_0 0x40280 +#define PRS_REG_HDRS_AFTER_TAG_0_PORT_1 0x402a0 /* [RW 4] The increment value to send in the CFC load request message */ #define PRS_REG_INC_VALUE 0x40048 /* [RW 6] Bit-map indicating which headers must appear in the packet */ #define PRS_REG_MUST_HAVE_HDRS 0x40254 +/* [RW 6] Bit-map indicating which headers must appear in the packet for + * port 0 packets */ +#define PRS_REG_MUST_HAVE_HDRS_PORT_0 0x4028c +#define PRS_REG_MUST_HAVE_HDRS_PORT_1 0x402ac #define PRS_REG_NIC_MODE 0x40138 /* [RW 8] The 8-bit event ID for cases where there is no match on the connection. Used in packet start message to TCM. */ @@ -2497,6 +2631,11 @@ #define PRS_REG_SERIAL_NUM_STATUS_MSB 0x40158 /* [R 4] debug only: SRC current credit. Transaction based. */ #define PRS_REG_SRC_CURRENT_CREDIT 0x4016c +/* [RW 16] The Ethernet type value for L2 tag 0 */ +#define PRS_REG_TAG_ETHERTYPE_0 0x401d4 +/* [RW 4] The length of the info field for L2 tag 0. The length is between + * 2B and 14B; in 2B granularity */ +#define PRS_REG_TAG_LEN_0 0x4022c /* [R 8] debug only: TCM current credit. Cycle based. */ #define PRS_REG_TCM_CURRENT_CREDIT 0x40160 /* [R 8] debug only: TSDM current credit. Transaction based. */ @@ -3081,6 +3220,7 @@ #define QM_REG_BYTECREDITAFULLTHR 0x168094 /* [RW 4] The initial credit for interface */ #define QM_REG_CMINITCRD_0 0x1680cc +#define QM_REG_BYTECRDCMDQ_0 0x16e6e8 #define QM_REG_CMINITCRD_1 0x1680d0 #define QM_REG_CMINITCRD_2 0x1680d4 #define QM_REG_CMINITCRD_3 0x1680d8 @@ -3171,7 +3311,10 @@ /* [RW 2] The PCI attributes field used in the PCI request. */ #define QM_REG_PCIREQAT 0x168054 #define QM_REG_PF_EN 0x16e70c -/* [R 16] The byte credit of port 0 */ +/* [R 24] The number of tasks stored in the QM for the PF. only even + * functions are valid in E2 (odd I registers will be hard wired to 0) */ +#define QM_REG_PF_USG_CNT_0 0x16e040 +/* [R 16] NOT USED */ #define QM_REG_PORT0BYTECRD 0x168300 /* [R 16] The byte credit of port 1 */ #define QM_REG_PORT1BYTECRD 0x168304 @@ -3783,6 +3926,8 @@ #define TM_REG_LIN0_LOGIC_ADDR 0x164240 /* [RW 18] Linear0 Max active cid (in banks of 32 entries). */ #define TM_REG_LIN0_MAX_ACTIVE_CID 0x164048 +/* [ST 16] Linear0 Number of scans counter. */ +#define TM_REG_LIN0_NUM_SCANS 0x1640a0 /* [WB 64] Linear0 phy address. */ #define TM_REG_LIN0_PHY_ADDR 0x164270 /* [RW 1] Linear0 physical address valid. */ @@ -3790,6 +3935,7 @@ #define TM_REG_LIN0_SCAN_ON 0x1640d0 /* [RW 24] Linear0 array scan timeout. */ #define TM_REG_LIN0_SCAN_TIME 0x16403c +#define TM_REG_LIN0_VNIC_UC 0x164128 /* [RW 32] Linear1 logic address. */ #define TM_REG_LIN1_LOGIC_ADDR 0x164250 /* [WB 64] Linear1 phy address. */ @@ -4845,8 +4991,10 @@ #define XSDM_REG_NUM_OF_Q8_CMD 0x166264 /* [ST 32] The number of commands received in queue 9 */ #define XSDM_REG_NUM_OF_Q9_CMD 0x166268 -/* [RW 13] The start address in the internal RAM for queue counters */ -#define XSDM_REG_Q_COUNTER_START_ADDR 0x166010 +/* [W 17] Generate an operation after completion; bit-16 is + * AggVectIdx_valid; bits 15:8 are AggVectIdx; bits 7:5 are the TRIG and + * bits 4:0 are the T124Param[4:0] */ +#define XSDM_REG_OPERATION_GEN 0x1664c4 /* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */ #define XSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY 0x166548 /* [R 1] parser fifo empty in sdm_sync block */ @@ -5129,6 +5277,8 @@ #define MISC_REGISTERS_RESET_REG_1_RST_PXPV (0x1<<27) #define MISC_REGISTERS_RESET_REG_1_SET 0x584 #define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598 +#define MISC_REGISTERS_RESET_REG_2_MSTAT0 (0x1<<24) +#define MISC_REGISTERS_RESET_REG_2_MSTAT1 (0x1<<25) #define MISC_REGISTERS_RESET_REG_2_RST_BMAC0 (0x1<<0) #define MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE (0x1<<14) #define MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE (0x1<<15) @@ -5161,6 +5311,7 @@ #define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1 #define MISC_REGISTERS_SPIO_OUTPUT_LOW 0 #define MISC_REGISTERS_SPIO_SET_POS 8 +#define HW_LOCK_DRV_FLAGS 10 #define HW_LOCK_MAX_RESOURCE_VALUE 31 #define HW_LOCK_RESOURCE_GPIO 1 #define HW_LOCK_RESOURCE_MDIO 0 @@ -5168,7 +5319,6 @@ #define HW_LOCK_RESOURCE_RESERVED_08 8 #define HW_LOCK_RESOURCE_SPIO 2 #define HW_LOCK_RESOURCE_UNDI 5 -#define PRS_FLAG_OVERETH_IPV4 1 #define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) #define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) @@ -5320,6 +5470,8 @@ #define GRCBASE_PXP2 0x120000 #define GRCBASE_PBF 0x140000 #define GRCBASE_XPB 0x161000 +#define GRCBASE_MSTAT0 0x162000 +#define GRCBASE_MSTAT1 0x162800 #define GRCBASE_TIMERS 0x164000 #define GRCBASE_XSDM 0x166000 #define GRCBASE_QM 0x168000 @@ -6243,11 +6395,6 @@ Theotherbitsarereservedandshouldbezero*/ #define IGU_ADDR_MSI_ADDR_HI 0x0212 #define IGU_ADDR_MSI_DATA 0x0213 -#define IGU_INT_ENABLE 0 -#define IGU_INT_DISABLE 1 -#define IGU_INT_NOP 2 -#define IGU_INT_NOP2 3 - #define IGU_USE_REGISTER_ustorm_type_0_sb_cleanup 0 #define IGU_USE_REGISTER_ustorm_type_1_sb_cleanup 1 #define IGU_USE_REGISTER_cstorm_type_0_sb_cleanup 2 @@ -6318,15 +6465,6 @@ Theotherbitsarereservedandshouldbezero*/ #define IGU_BC_BASE_DSB_PROD 128 #define IGU_NORM_BASE_DSB_PROD 136 -#define IGU_CTRL_CMD_TYPE_WR\ - 1 -#define IGU_CTRL_CMD_TYPE_RD\ - 0 - -#define IGU_SEG_ACCESS_NORM 0 -#define IGU_SEG_ACCESS_DEF 1 -#define IGU_SEG_ACCESS_ATTN 2 - /* FID (if VF - [6] = 0; [5:0] = VF number; if PF - [6] = 1; \ [5:2] = 0; [1:0] = PF number) */ #define IGU_FID_ENCODE_IS_PF (0x1<<6) diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index 7c876a06b77..5bdf09459a0 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -1,3 +1,21 @@ +/* bnx2x_sp.c: Broadcom Everest network driver. + * + * Copyright 2011 Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available + * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + * + * Maintained by: Eilon Greenstein + * Written by: Vladislav Zolotarov + * + */ #include #include #include @@ -8,812 +26,5308 @@ #include "bnx2x_cmn.h" #include "bnx2x_sp.h" +#define BNX2X_MAX_EMUL_MULTI 16 + +/**** Exe Queue interfaces ****/ /** - * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips + * bnx2x_exe_queue_init - init the Exe Queue object * - * @bp: driver handle - * @set: set or clear an entry (1 or 0) - * @mac: pointer to a buffer containing a MAC - * @cl_bit_vec: bit vector of clients to register a MAC for - * @cam_offset: offset in a CAM to use - * @is_bcast: is the set MAC a broadcast address (for E1 only) + * @o: poiter to the object + * @exe_len: length + * @owner: poiter to the owner + * @validate: validate function pointer + * @optimize: optimize function pointer + * @exec: execute function pointer + * @get: get function pointer */ -void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 is_bcast) +static inline void bnx2x_exe_queue_init(struct bnx2x *bp, + struct bnx2x_exe_queue_obj *o, + int exe_len, + union bnx2x_qable_obj *owner, + exe_q_validate validate, + exe_q_optimize optimize, + exe_q_execute exec, + exe_q_get get) { - struct mac_configuration_cmd *config = - (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); - int ramrod_flags = WAIT_RAMROD_COMMON; - - bp->set_mac_pending = 1; - - config->hdr.length = 1; - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - /* Mark the single MAC configuration ramrod as opposed to a - * UC/MC list configuration). - */ - config->hdr.echo = 1; - - /* primary MAC */ - config->config_table[0].msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].vlan_id = 0; - config->config_table[0].pf_id = BP_FUNC(bp); - if (set) - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_SET); - else - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); + memset(o, 0, sizeof(*o)); - if (is_bcast) - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_BROADCAST, 1); + INIT_LIST_HEAD(&o->exe_queue); + INIT_LIST_HEAD(&o->pending_comp); - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", - (set ? "setting" : "clearing"), - config->config_table[0].msb_mac_addr, - config->config_table[0].middle_mac_addr, - config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); + spin_lock_init(&o->lock); - mb(); + o->exe_chunk_len = exe_len; + o->owner = owner; - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); + /* Owner specific callbacks */ + o->validate = validate; + o->optimize = optimize; + o->execute = exec; + o->get = get; - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); + DP(BNX2X_MSG_SP, "Setup the execution queue with the chunk " + "length of %d\n", exe_len); } +static inline void bnx2x_exe_queue_free_elem(struct bnx2x *bp, + struct bnx2x_exeq_elem *elem) +{ + DP(BNX2X_MSG_SP, "Deleting an exe_queue element\n"); + kfree(elem); +} -static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp) +static inline int bnx2x_exe_queue_length(struct bnx2x_exe_queue_obj *o) { - return CHIP_REV_IS_SLOW(bp) ? - (BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) : - (BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp))); + struct bnx2x_exeq_elem *elem; + int cnt = 0; + + spin_lock_bh(&o->lock); + + list_for_each_entry(elem, &o->exe_queue, link) + cnt++; + + spin_unlock_bh(&o->lock); + + return cnt; } -/* set mc list, do not wait as wait implies sleep and - * set_rx_mode can be invoked from non-sleepable context. +/** + * bnx2x_exe_queue_add - add a new element to the execution queue + * + * @bp: driver handle + * @o: queue + * @cmd: new command to add + * @restore: true - do not optimize the command * - * Instead we use the same ramrod data buffer each time we need - * to configure a list of addresses, and use the fact that the - * list of MACs is changed in an incremental way and that the - * function is called under the netif_addr_lock. A temporary - * inconsistent CAM configuration (possible in case of a very fast - * sequence of add/del/add on the host side) will shortly be - * restored by the handler of the last ramrod. + * If the element is optimized or is illegal, frees it. */ -int bnx2x_set_e1_mc_list(struct bnx2x *bp) +static inline int bnx2x_exe_queue_add(struct bnx2x *bp, + struct bnx2x_exe_queue_obj *o, + struct bnx2x_exeq_elem *elem, + bool restore) { - int i = 0, old; - struct net_device *dev = bp->dev; - u8 offset = bnx2x_e1_cam_mc_offset(bp); - struct netdev_hw_addr *ha; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + int rc; - if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) - return -EINVAL; + spin_lock_bh(&o->lock); - netdev_for_each_mc_addr(ha, dev) { - /* copy mac */ - config_cmd->config_table[i].msb_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); - config_cmd->config_table[i].middle_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); - config_cmd->config_table[i].lsb_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); - - config_cmd->config_table[i].vlan_id = 0; - config_cmd->config_table[i].pf_id = BP_FUNC(bp); - config_cmd->config_table[i].clients_bit_vector = - cpu_to_le32(1 << BP_L_ID(bp)); - - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_SET); - - DP(NETIF_MSG_IFUP, - "setting MCAST[%d] (%04x:%04x:%04x)\n", i, - config_cmd->config_table[i].msb_mac_addr, - config_cmd->config_table[i].middle_mac_addr, - config_cmd->config_table[i].lsb_mac_addr); - i++; - } - old = config_cmd->hdr.length; - if (old > i) { - for (; i < old; i++) { - if (CAM_IS_INVALID(config_cmd-> - config_table[i])) { - /* already invalidated */ - break; - } - /* invalidate */ - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); + if (!restore) { + /* Try to cancel this element queue */ + rc = o->optimize(bp, o->owner, elem); + if (rc) + goto free_and_exit; + + /* Check if this request is ok */ + rc = o->validate(bp, o->owner, elem); + if (rc) { + BNX2X_ERR("Preamble failed: %d\n", rc); + goto free_and_exit; } } - wmb(); - - config_cmd->hdr.length = i; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* Mark that this ramrod doesn't use bp->set_mac_pending for - * synchronization. - */ - config_cmd->hdr.echo = 0; - - mb(); - - return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); -} + /* If so, add it to the execution queue */ + list_add_tail(&elem->link, &o->exe_queue); -void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp) -{ - int i; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); - int ramrod_flags = WAIT_RAMROD_COMMON; - u8 offset = bnx2x_e1_cam_mc_offset(bp); + spin_unlock_bh(&o->lock); - for (i = 0; i < BNX2X_MAX_MULTICAST; i++) - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); + return 0; - wmb(); +free_and_exit: + bnx2x_exe_queue_free_elem(bp, elem); - config_cmd->hdr.length = BNX2X_MAX_MULTICAST; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* We'll wait for a completion this time... */ - config_cmd->hdr.echo = 1; + spin_unlock_bh(&o->lock); - bp->set_mac_pending = 1; + return rc; - mb(); +} - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); +static inline void __bnx2x_exe_queue_reset_pending( + struct bnx2x *bp, + struct bnx2x_exe_queue_obj *o) +{ + struct bnx2x_exeq_elem *elem; - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, - ramrod_flags); + while (!list_empty(&o->pending_comp)) { + elem = list_first_entry(&o->pending_comp, + struct bnx2x_exeq_elem, link); + list_del(&elem->link); + bnx2x_exe_queue_free_elem(bp, elem); + } } -/* Accept one or more multicasts */ -int bnx2x_set_e1h_mc_list(struct bnx2x *bp) +static inline void bnx2x_exe_queue_reset_pending(struct bnx2x *bp, + struct bnx2x_exe_queue_obj *o) { - struct net_device *dev = bp->dev; - struct netdev_hw_addr *ha; - u32 mc_filter[MC_HASH_SIZE]; - u32 crc, bit, regidx; - int i; - memset(mc_filter, 0, 4 * MC_HASH_SIZE); + spin_lock_bh(&o->lock); - netdev_for_each_mc_addr(ha, dev) { - DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", - bnx2x_mc_addr(ha)); - - crc = crc32c_le(0, bnx2x_mc_addr(ha), - ETH_ALEN); - bit = (crc >> 24) & 0xff; - regidx = bit >> 5; - bit &= 0x1f; - mc_filter[regidx] |= (1 << bit); - } + __bnx2x_exe_queue_reset_pending(bp, o); - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), - mc_filter[i]); + spin_unlock_bh(&o->lock); - return 0; } -void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp) +/** + * bnx2x_exe_queue_step - execute one execution chunk atomically + * + * @bp: driver handle + * @o: queue + * @ramrod_flags: flags + * + * (Atomicy is ensured using the exe_queue->lock). + */ +static inline int bnx2x_exe_queue_step(struct bnx2x *bp, + struct bnx2x_exe_queue_obj *o, + unsigned long *ramrod_flags) { - int i; + struct bnx2x_exeq_elem *elem, spacer; + int cur_len = 0, rc; - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); -} + memset(&spacer, 0, sizeof(spacer)); -/* must be called under rtnl_lock */ -void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) -{ - u32 mask = (1 << cl_id); + spin_lock_bh(&o->lock); - /* initial seeting is BNX2X_ACCEPT_NONE */ - u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; - u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; - u8 unmatched_unicast = 0; + /* + * Next step should not be performed until the current is finished, + * unless a DRV_CLEAR_ONLY bit is set. In this case we just want to + * properly clear object internals without sending any command to the FW + * which also implies there won't be any completion to clear the + * 'pending' list. + */ + if (!list_empty(&o->pending_comp)) { + if (test_bit(RAMROD_DRV_CLR_ONLY, ramrod_flags)) { + DP(BNX2X_MSG_SP, "RAMROD_DRV_CLR_ONLY requested: " + "resetting pending_comp\n"); + __bnx2x_exe_queue_reset_pending(bp, o); + } else { + spin_unlock_bh(&o->lock); + return 1; + } + } - if (filters & BNX2X_ACCEPT_UNMATCHED_UCAST) - unmatched_unicast = 1; + /* + * Run through the pending commands list and create a next + * execution chunk. + */ + while (!list_empty(&o->exe_queue)) { + elem = list_first_entry(&o->exe_queue, struct bnx2x_exeq_elem, + link); + WARN_ON(!elem->cmd_len); - if (filters & BNX2X_PROMISCUOUS_MODE) { - /* promiscious - accept all, drop none */ - drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; - accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; - if (IS_MF_SI(bp)) { + if (cur_len + elem->cmd_len <= o->exe_chunk_len) { + cur_len += elem->cmd_len; /* - * SI mode defines to accept in promiscuos mode - * only unmatched packets + * Prevent from both lists being empty when moving an + * element. This will allow the call of + * bnx2x_exe_queue_empty() without locking. */ - unmatched_unicast = 1; - accp_all_ucast = 0; - } + list_add_tail(&spacer.link, &o->pending_comp); + mb(); + list_del(&elem->link); + list_add_tail(&elem->link, &o->pending_comp); + list_del(&spacer.link); + } else + break; } - if (filters & BNX2X_ACCEPT_UNICAST) { - /* accept matched ucast */ - drop_all_ucast = 0; - } - if (filters & BNX2X_ACCEPT_MULTICAST) - /* accept matched mcast */ - drop_all_mcast = 0; - if (filters & BNX2X_ACCEPT_ALL_UNICAST) { - /* accept all mcast */ - drop_all_ucast = 0; - accp_all_ucast = 1; - } - if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { - /* accept all mcast */ - drop_all_mcast = 0; - accp_all_mcast = 1; - } - if (filters & BNX2X_ACCEPT_BROADCAST) { - /* accept (all) bcast */ - drop_all_bcast = 0; - accp_all_bcast = 1; + /* Sanity check */ + if (!cur_len) { + spin_unlock_bh(&o->lock); + return 0; } - bp->mac_filters.ucast_drop_all = drop_all_ucast ? - bp->mac_filters.ucast_drop_all | mask : - bp->mac_filters.ucast_drop_all & ~mask; + rc = o->execute(bp, o->owner, &o->pending_comp, ramrod_flags); + if (rc < 0) + /* + * In case of an error return the commands back to the queue + * and reset the pending_comp. + */ + list_splice_init(&o->pending_comp, &o->exe_queue); + else if (!rc) + /* + * If zero is returned, means there are no outstanding pending + * completions and we may dismiss the pending list. + */ + __bnx2x_exe_queue_reset_pending(bp, o); - bp->mac_filters.mcast_drop_all = drop_all_mcast ? - bp->mac_filters.mcast_drop_all | mask : - bp->mac_filters.mcast_drop_all & ~mask; + spin_unlock_bh(&o->lock); + return rc; +} - bp->mac_filters.bcast_drop_all = drop_all_bcast ? - bp->mac_filters.bcast_drop_all | mask : - bp->mac_filters.bcast_drop_all & ~mask; +static inline bool bnx2x_exe_queue_empty(struct bnx2x_exe_queue_obj *o) +{ + bool empty = list_empty(&o->exe_queue); - bp->mac_filters.ucast_accept_all = accp_all_ucast ? - bp->mac_filters.ucast_accept_all | mask : - bp->mac_filters.ucast_accept_all & ~mask; + /* Don't reorder!!! */ + mb(); - bp->mac_filters.mcast_accept_all = accp_all_mcast ? - bp->mac_filters.mcast_accept_all | mask : - bp->mac_filters.mcast_accept_all & ~mask; + return empty && list_empty(&o->pending_comp); +} - bp->mac_filters.bcast_accept_all = accp_all_bcast ? - bp->mac_filters.bcast_accept_all | mask : - bp->mac_filters.bcast_accept_all & ~mask; +static inline struct bnx2x_exeq_elem *bnx2x_exe_queue_alloc_elem( + struct bnx2x *bp) +{ + DP(BNX2X_MSG_SP, "Allocating a new exe_queue element\n"); + return kzalloc(sizeof(struct bnx2x_exeq_elem), GFP_ATOMIC); +} - bp->mac_filters.unmatched_unicast = unmatched_unicast ? - bp->mac_filters.unmatched_unicast | mask : - bp->mac_filters.unmatched_unicast & ~mask; +/************************ raw_obj functions ***********************************/ +static bool bnx2x_raw_check_pending(struct bnx2x_raw_obj *o) +{ + return !!test_bit(o->state, o->pstate); } -void bnx2x_set_storm_rx_mode(struct bnx2x *bp) +static void bnx2x_raw_clear_pending(struct bnx2x_raw_obj *o) { - int mode = bp->rx_mode; - int port = BP_PORT(bp); - u16 cl_id; - u32 def_q_filters = 0; + smp_mb__before_clear_bit(); + clear_bit(o->state, o->pstate); + smp_mb__after_clear_bit(); +} - /* All but management unicast packets should pass to the host as well */ - u32 llh_mask = - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; +static void bnx2x_raw_set_pending(struct bnx2x_raw_obj *o) +{ + smp_mb__before_clear_bit(); + set_bit(o->state, o->pstate); + smp_mb__after_clear_bit(); +} - switch (mode) { - case BNX2X_RX_MODE_NONE: /* no Rx */ - def_q_filters = BNX2X_ACCEPT_NONE; -#ifdef BCM_CNIC - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); - } -#endif - break; +/** + * bnx2x_state_wait - wait until the given bit(state) is cleared + * + * @bp: device handle + * @state: state which is to be cleared + * @state_p: state buffer + * + */ +static inline int bnx2x_state_wait(struct bnx2x *bp, int state, + unsigned long *pstate) +{ + /* can take a while if any port is running */ + int cnt = 5000; - case BNX2X_RX_MODE_NORMAL: - def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_MULTICAST; -#ifdef BCM_CNIC - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST | - BNX2X_ACCEPT_MULTICAST); - } -#endif - break; - case BNX2X_RX_MODE_ALLMULTI: - def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_ALL_MULTICAST; -#ifdef BCM_CNIC - /* - * Prevent duplication of multicast packets by configuring FCoE - * L2 Client to receive only matched unicast frames. - */ - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST); - } -#endif - break; + if (CHIP_REV_IS_EMUL(bp)) + cnt *= 20; - case BNX2X_RX_MODE_PROMISC: - def_q_filters |= BNX2X_PROMISCUOUS_MODE; -#ifdef BCM_CNIC - /* - * Prevent packets duplication by configuring DROP_ALL for FCoE - * L2 Client. - */ - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); - } + DP(BNX2X_MSG_SP, "waiting for state to become %d\n", state); + + might_sleep(); + while (cnt--) { + if (!test_bit(state, pstate)) { +#ifdef BNX2X_STOP_ON_ERROR + DP(BNX2X_MSG_SP, "exit (cnt %d)\n", 5000 - cnt); #endif - /* pass management unicast packets as well */ - llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; - break; + return 0; + } - default: - BNX2X_ERR("BAD rx mode (%d)\n", mode); - break; - } + usleep_range(1000, 1000); - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters); + if (bp->panic) + return -EIO; + } - REG_WR(bp, - (port ? NIG_REG_LLH1_BRB1_DRV_MASK : - NIG_REG_LLH0_BRB1_DRV_MASK), llh_mask); + /* timeout! */ + BNX2X_ERR("timeout waiting for state %d\n", state); +#ifdef BNX2X_STOP_ON_ERROR + bnx2x_panic(); +#endif - DP(NETIF_MSG_IFUP, "rx mode %d\n" - "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" - "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n" - "unmatched_ucast 0x%x\n", mode, - bp->mac_filters.ucast_drop_all, - bp->mac_filters.mcast_drop_all, - bp->mac_filters.bcast_drop_all, - bp->mac_filters.ucast_accept_all, - bp->mac_filters.mcast_accept_all, - bp->mac_filters.bcast_accept_all, - bp->mac_filters.unmatched_unicast - ); + return -EBUSY; +} - storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); +static int bnx2x_raw_wait(struct bnx2x *bp, struct bnx2x_raw_obj *raw) +{ + return bnx2x_state_wait(bp, raw->state, raw->pstate); } -/* RSS configuration */ -static inline void __storm_memset_dma_mapping(struct bnx2x *bp, - u32 addr, dma_addr_t mapping) +/***************** Classification verbs: Set/Del MAC/VLAN/VLAN-MAC ************/ +/* credit handling callbacks */ +static bool bnx2x_get_cam_offset_mac(struct bnx2x_vlan_mac_obj *o, int *offset) { - REG_WR(bp, addr, U64_LO(mapping)); - REG_WR(bp, addr + 4, U64_HI(mapping)); + struct bnx2x_credit_pool_obj *mp = o->macs_pool; + + WARN_ON(!mp); + + return mp->get_entry(mp, offset); } -static inline void __storm_fill(struct bnx2x *bp, - u32 addr, size_t size, u32 val) +static bool bnx2x_get_credit_mac(struct bnx2x_vlan_mac_obj *o) { - int i; - for (i = 0; i < size/4; i++) - REG_WR(bp, addr + (i * 4), val); + struct bnx2x_credit_pool_obj *mp = o->macs_pool; + + WARN_ON(!mp); + + return mp->get(mp, 1); } -static inline void storm_memset_ustats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) +static bool bnx2x_get_cam_offset_vlan(struct bnx2x_vlan_mac_obj *o, int *offset) { - size_t size = sizeof(struct ustorm_per_client_stats); + struct bnx2x_credit_pool_obj *vp = o->vlans_pool; - u32 addr = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + WARN_ON(!vp); - __storm_fill(bp, addr, size, 0); + return vp->get_entry(vp, offset); } -static inline void storm_memset_tstats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) +static bool bnx2x_get_credit_vlan(struct bnx2x_vlan_mac_obj *o) { - size_t size = sizeof(struct tstorm_per_client_stats); + struct bnx2x_credit_pool_obj *vp = o->vlans_pool; - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + WARN_ON(!vp); - __storm_fill(bp, addr, size, 0); + return vp->get(vp, 1); } -static inline void storm_memset_xstats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) +static bool bnx2x_get_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o) { - size_t size = sizeof(struct xstorm_per_client_stats); + struct bnx2x_credit_pool_obj *mp = o->macs_pool; + struct bnx2x_credit_pool_obj *vp = o->vlans_pool; + + if (!mp->get(mp, 1)) + return false; - u32 addr = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + if (!vp->get(vp, 1)) { + mp->put(mp, 1); + return false; + } - __storm_fill(bp, addr, size, 0); + return true; } +static bool bnx2x_put_cam_offset_mac(struct bnx2x_vlan_mac_obj *o, int offset) +{ + struct bnx2x_credit_pool_obj *mp = o->macs_pool; + + return mp->put_entry(mp, offset); +} -static inline void storm_memset_spq_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) +static bool bnx2x_put_credit_mac(struct bnx2x_vlan_mac_obj *o) { - u32 addr = XSEM_REG_FAST_MEMORY + - XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); + struct bnx2x_credit_pool_obj *mp = o->macs_pool; - __storm_memset_dma_mapping(bp, addr, mapping); + return mp->put(mp, 1); } -static inline void storm_memset_xstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) +static bool bnx2x_put_cam_offset_vlan(struct bnx2x_vlan_mac_obj *o, int offset) { - size_t size = sizeof(struct stats_indication_flags); + struct bnx2x_credit_pool_obj *vp = o->vlans_pool; + + return vp->put_entry(vp, offset); +} - u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); +static bool bnx2x_put_credit_vlan(struct bnx2x_vlan_mac_obj *o) +{ + struct bnx2x_credit_pool_obj *vp = o->vlans_pool; - __storm_memset_struct(bp, addr, size, (u32 *)flags); + return vp->put(vp, 1); } -static inline void storm_memset_tstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) +static bool bnx2x_put_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o) { - size_t size = sizeof(struct stats_indication_flags); + struct bnx2x_credit_pool_obj *mp = o->macs_pool; + struct bnx2x_credit_pool_obj *vp = o->vlans_pool; + + if (!mp->put(mp, 1)) + return false; - u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); + if (!vp->put(vp, 1)) { + mp->get(mp, 1); + return false; + } - __storm_memset_struct(bp, addr, size, (u32 *)flags); + return true; } -static inline void storm_memset_ustats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) +/* check_add() callbacks */ +static int bnx2x_check_mac_add(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data) { - size_t size = sizeof(struct stats_indication_flags); + struct bnx2x_vlan_mac_registry_elem *pos; + + if (!is_valid_ether_addr(data->mac.mac)) + return -EINVAL; - u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); + /* Check if a requested MAC already exists */ + list_for_each_entry(pos, &o->head, link) + if (!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) + return -EEXIST; - __storm_memset_struct(bp, addr, size, (u32 *)flags); + return 0; } -static inline void storm_memset_cstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) +static int bnx2x_check_vlan_add(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data) { - size_t size = sizeof(struct stats_indication_flags); + struct bnx2x_vlan_mac_registry_elem *pos; - u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); + list_for_each_entry(pos, &o->head, link) + if (data->vlan.vlan == pos->u.vlan.vlan) + return -EEXIST; - __storm_memset_struct(bp, addr, size, (u32 *)flags); + return 0; } -static inline void storm_memset_xstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) +static int bnx2x_check_vlan_mac_add(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data) { - u32 addr = BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + struct bnx2x_vlan_mac_registry_elem *pos; + + list_for_each_entry(pos, &o->head, link) + if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && + (!memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac, + ETH_ALEN))) + return -EEXIST; - __storm_memset_dma_mapping(bp, addr, mapping); + return 0; } -static inline void storm_memset_tstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) + +/* check_del() callbacks */ +static struct bnx2x_vlan_mac_registry_elem * + bnx2x_check_mac_del(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data) { - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + struct bnx2x_vlan_mac_registry_elem *pos; + + list_for_each_entry(pos, &o->head, link) + if (!memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) + return pos; - __storm_memset_dma_mapping(bp, addr, mapping); + return NULL; } -static inline void storm_memset_ustats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) +static struct bnx2x_vlan_mac_registry_elem * + bnx2x_check_vlan_del(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data) { - u32 addr = BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + struct bnx2x_vlan_mac_registry_elem *pos; - __storm_memset_dma_mapping(bp, addr, mapping); + list_for_each_entry(pos, &o->head, link) + if (data->vlan.vlan == pos->u.vlan.vlan) + return pos; + + return NULL; } -static inline void storm_memset_cstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) +static struct bnx2x_vlan_mac_registry_elem * + bnx2x_check_vlan_mac_del(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data) { - u32 addr = BAR_CSTRORM_INTMEM + - CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + struct bnx2x_vlan_mac_registry_elem *pos; + + list_for_each_entry(pos, &o->head, link) + if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) && + (!memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac, + ETH_ALEN))) + return pos; - __storm_memset_dma_mapping(bp, addr, mapping); + return NULL; } -static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, - u16 pf_id) +/* check_move() callback */ +static bool bnx2x_check_move(struct bnx2x_vlan_mac_obj *src_o, + struct bnx2x_vlan_mac_obj *dst_o, + union bnx2x_classification_ramrod_data *data) { - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); + struct bnx2x_vlan_mac_registry_elem *pos; + int rc; + + /* Check if we can delete the requested configuration from the first + * object. + */ + pos = src_o->check_del(src_o, data); + + /* check if configuration can be added */ + rc = dst_o->check_add(dst_o, data); + + /* If this classification can not be added (is already set) + * or can't be deleted - return an error. + */ + if (rc || !pos) + return false; + + return true; } -static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, - u8 enable) +static bool bnx2x_check_move_always_err( + struct bnx2x_vlan_mac_obj *src_o, + struct bnx2x_vlan_mac_obj *dst_o, + union bnx2x_classification_ramrod_data *data) { - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), - enable); + return false; } -static inline void storm_memset_func_cfg(struct bnx2x *bp, - struct tstorm_eth_function_common_config *tcfg, - u16 abs_fid) + +static inline u8 bnx2x_vlan_mac_get_rx_tx_flag(struct bnx2x_vlan_mac_obj *o) { - size_t size = sizeof(struct tstorm_eth_function_common_config); + struct bnx2x_raw_obj *raw = &o->raw; + u8 rx_tx_flag = 0; - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); + if ((raw->obj_type == BNX2X_OBJ_TYPE_TX) || + (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) + rx_tx_flag |= ETH_CLASSIFY_CMD_HEADER_TX_CMD; - __storm_memset_struct(bp, addr, size, (u32 *)tcfg); + if ((raw->obj_type == BNX2X_OBJ_TYPE_RX) || + (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) + rx_tx_flag |= ETH_CLASSIFY_CMD_HEADER_RX_CMD; + + return rx_tx_flag; } -void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) +/* LLH CAM line allocations */ +enum { + LLH_CAM_ISCSI_ETH_LINE = 0, + LLH_CAM_ETH_LINE, + LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE / 2 +}; + +static inline void bnx2x_set_mac_in_nig(struct bnx2x *bp, + bool add, unsigned char *dev_addr, int index) { - struct tstorm_eth_function_common_config tcfg = {0}; - u16 rss_flgs; + u32 wb_data[2]; + u32 reg_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM : + NIG_REG_LLH0_FUNC_MEM; + + if (!IS_MF_SI(bp) || index > LLH_CAM_MAX_PF_LINE) + return; + + DP(BNX2X_MSG_SP, "Going to %s LLH configuration at entry %d\n", + (add ? "ADD" : "DELETE"), index); + + if (add) { + /* LLH_FUNC_MEM is a u64 WB register */ + reg_offset += 8*index; - /* tpa */ - if (p->func_flgs & FUNC_FLG_TPA) - tcfg.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; + wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) | + (dev_addr[4] << 8) | dev_addr[5]); + wb_data[1] = ((dev_addr[0] << 8) | dev_addr[1]); - /* set rss flags */ - rss_flgs = (p->rss->mode << - TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); + REG_WR_DMAE(bp, reg_offset, wb_data, 2); + } - if (p->rss->cap & RSS_IPV4_CAP) - rss_flgs |= RSS_IPV4_CAP_MASK; - if (p->rss->cap & RSS_IPV4_TCP_CAP) - rss_flgs |= RSS_IPV4_TCP_CAP_MASK; - if (p->rss->cap & RSS_IPV6_CAP) - rss_flgs |= RSS_IPV6_CAP_MASK; - if (p->rss->cap & RSS_IPV6_TCP_CAP) - rss_flgs |= RSS_IPV6_TCP_CAP_MASK; + REG_WR(bp, (BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM_ENABLE : + NIG_REG_LLH0_FUNC_MEM_ENABLE) + 4*index, add); +} - tcfg.config_flags |= rss_flgs; - tcfg.rss_result_mask = p->rss->result_mask; +/** + * bnx2x_vlan_mac_set_cmd_hdr_e2 - set a header in a single classify ramrod + * + * @bp: device handle + * @o: queue for which we want to configure this rule + * @add: if true the command is an ADD command, DEL otherwise + * @opcode: CLASSIFY_RULE_OPCODE_XXX + * @hdr: pointer to a header to setup + * + */ +static inline void bnx2x_vlan_mac_set_cmd_hdr_e2(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, bool add, int opcode, + struct eth_classify_cmd_header *hdr) +{ + struct bnx2x_raw_obj *raw = &o->raw; - storm_memset_func_cfg(bp, &tcfg, p->func_id); + hdr->client_id = raw->cl_id; + hdr->func_id = raw->func_id; - /* Enable the function in the FW */ - storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); - storm_memset_func_en(bp, p->func_id, 1); + /* Rx or/and Tx (internal switching) configuration ? */ + hdr->cmd_general_data |= + bnx2x_vlan_mac_get_rx_tx_flag(o); - /* statistics */ - if (p->func_flgs & FUNC_FLG_STATS) { - struct stats_indication_flags stats_flags = {0}; - stats_flags.collect_eth = 1; + if (add) + hdr->cmd_general_data |= ETH_CLASSIFY_CMD_HEADER_IS_ADD; - storm_memset_xstats_flags(bp, &stats_flags, p->func_id); - storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); + hdr->cmd_general_data |= + (opcode << ETH_CLASSIFY_CMD_HEADER_OPCODE_SHIFT); +} - storm_memset_tstats_flags(bp, &stats_flags, p->func_id); - storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); +/** + * bnx2x_vlan_mac_set_rdata_hdr_e2 - set the classify ramrod data header + * + * @cid: connection id + * @type: BNX2X_FILTER_XXX_PENDING + * @hdr: poiter to header to setup + * @rule_cnt: + * + * currently we always configure one rule and echo field to contain a CID and an + * opcode type. + */ +static inline void bnx2x_vlan_mac_set_rdata_hdr_e2(u32 cid, int type, + struct eth_classify_header *hdr, int rule_cnt) +{ + hdr->echo = (cid & BNX2X_SWCID_MASK) | (type << BNX2X_SWCID_SHIFT); + hdr->rule_cnt = (u8)rule_cnt; +} - storm_memset_ustats_flags(bp, &stats_flags, p->func_id); - storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); - storm_memset_cstats_flags(bp, &stats_flags, p->func_id); - storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); +/* hw_config() callbacks */ +static void bnx2x_set_one_mac_e2(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + struct bnx2x_exeq_elem *elem, int rule_idx, + int cam_offset) +{ + struct bnx2x_raw_obj *raw = &o->raw; + struct eth_classify_rules_ramrod_data *data = + (struct eth_classify_rules_ramrod_data *)(raw->rdata); + int rule_cnt = rule_idx + 1, cmd = elem->cmd_data.vlan_mac.cmd; + union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx]; + bool add = (cmd == BNX2X_VLAN_MAC_ADD) ? true : false; + unsigned long *vlan_mac_flags = &elem->cmd_data.vlan_mac.vlan_mac_flags; + u8 *mac = elem->cmd_data.vlan_mac.u.mac.mac; + + /* + * Set LLH CAM entry: currently only iSCSI and ETH macs are + * relevant. In addition, current implementation is tuned for a + * single ETH MAC. + * + * When multiple unicast ETH MACs PF configuration in switch + * independent mode is required (NetQ, multiple netdev MACs, + * etc.), consider better utilisation of 8 per function MAC + * entries in the LLH register. There is also + * NIG_REG_P[01]_LLH_FUNC_MEM2 registers that complete the + * total number of CAM entries to 16. + * + * Currently we won't configure NIG for MACs other than a primary ETH + * MAC and iSCSI L2 MAC. + * + * If this MAC is moving from one Queue to another, no need to change + * NIG configuration. + */ + if (cmd != BNX2X_VLAN_MAC_MOVE) { + if (test_bit(BNX2X_ISCSI_ETH_MAC, vlan_mac_flags)) + bnx2x_set_mac_in_nig(bp, add, mac, + LLH_CAM_ISCSI_ETH_LINE); + else if (test_bit(BNX2X_ETH_MAC, vlan_mac_flags)) + bnx2x_set_mac_in_nig(bp, add, mac, LLH_CAM_ETH_LINE); } - /* spq */ - if (p->func_flgs & FUNC_FLG_SPQ) { - storm_memset_spq_addr(bp, p->spq_map, p->func_id); - REG_WR(bp, XSEM_REG_FAST_MEMORY + - XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); + /* Reset the ramrod data buffer for the first rule */ + if (rule_idx == 0) + memset(data, 0, sizeof(*data)); + + /* Setup a command header */ + bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_MAC, + &rule_entry->mac.header); + + DP(BNX2X_MSG_SP, "About to %s MAC "BNX2X_MAC_FMT" for " + "Queue %d\n", (add ? "add" : "delete"), + BNX2X_MAC_PRN_LIST(mac), raw->cl_id); + + /* Set a MAC itself */ + bnx2x_set_fw_mac_addr(&rule_entry->mac.mac_msb, + &rule_entry->mac.mac_mid, + &rule_entry->mac.mac_lsb, mac); + + /* MOVE: Add a rule that will add this MAC to the target Queue */ + if (cmd == BNX2X_VLAN_MAC_MOVE) { + rule_entry++; + rule_cnt++; + + /* Setup ramrod data */ + bnx2x_vlan_mac_set_cmd_hdr_e2(bp, + elem->cmd_data.vlan_mac.target_obj, + true, CLASSIFY_RULE_OPCODE_MAC, + &rule_entry->mac.header); + + /* Set a MAC itself */ + bnx2x_set_fw_mac_addr(&rule_entry->mac.mac_msb, + &rule_entry->mac.mac_mid, + &rule_entry->mac.mac_lsb, mac); } + + /* Set the ramrod data header */ + /* TODO: take this to the higher level in order to prevent multiple + writing */ + bnx2x_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header, + rule_cnt); } -static void bnx2x_fill_cl_init_data(struct bnx2x *bp, - struct bnx2x_client_init_params *params, - u8 activate, - struct client_init_ramrod_data *data) +/** + * bnx2x_vlan_mac_set_rdata_hdr_e1x - set a header in a single classify ramrod + * + * @bp: device handle + * @o: queue + * @type: + * @cam_offset: offset in cam memory + * @hdr: pointer to a header to setup + * + * E1/E1H + */ +static inline void bnx2x_vlan_mac_set_rdata_hdr_e1x(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, int type, int cam_offset, + struct mac_configuration_hdr *hdr) { - /* Clear the buffer */ - memset(data, 0, sizeof(*data)); - - /* general */ - data->general.client_id = params->rxq_params.cl_id; - data->general.statistics_counter_id = params->rxq_params.stat_id; - data->general.statistics_en_flg = - (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; - data->general.is_fcoe_flg = - (params->ramrod_params.flags & CLIENT_IS_FCOE) ? 1 : 0; - data->general.activate_flg = activate; - data->general.sp_client_id = params->rxq_params.spcl_id; + struct bnx2x_raw_obj *r = &o->raw; - /* Rx data */ - data->rx.tpa_en_flg = - (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; - data->rx.vmqueue_mode_en_flg = 0; - data->rx.cache_line_alignment_log_size = - params->rxq_params.cache_line_log; - data->rx.enable_dynamic_hc = - (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; - data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; - data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; - data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; + hdr->length = 1; + hdr->offset = (u8)cam_offset; + hdr->client_id = 0xff; + hdr->echo = ((r->cid & BNX2X_SWCID_MASK) | (type << BNX2X_SWCID_SHIFT)); +} - /* We don't set drop flags */ - data->rx.drop_ip_cs_err_flg = 0; - data->rx.drop_tcp_cs_err_flg = 0; - data->rx.drop_ttl0_flg = 0; - data->rx.drop_udp_cs_err_flg = 0; +static inline void bnx2x_vlan_mac_set_cfg_entry_e1x(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, bool add, int opcode, u8 *mac, + u16 vlan_id, struct mac_configuration_entry *cfg_entry) +{ + struct bnx2x_raw_obj *r = &o->raw; + u32 cl_bit_vec = (1 << r->cl_id); + + cfg_entry->clients_bit_vector = cpu_to_le32(cl_bit_vec); + cfg_entry->pf_id = r->func_id; + cfg_entry->vlan_id = cpu_to_le16(vlan_id); + + if (add) { + SET_FLAG(cfg_entry->flags, MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + SET_FLAG(cfg_entry->flags, + MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE, opcode); + + /* Set a MAC in a ramrod data */ + bnx2x_set_fw_mac_addr(&cfg_entry->msb_mac_addr, + &cfg_entry->middle_mac_addr, + &cfg_entry->lsb_mac_addr, mac); + } else + SET_FLAG(cfg_entry->flags, MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); +} - data->rx.inner_vlan_removal_enable_flg = - (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; - data->rx.outer_vlan_removal_enable_flg = - (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; - data->rx.status_block_id = params->rxq_params.fw_sb_id; - data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; - data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); - data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); - data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); - data->rx.bd_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); - data->rx.bd_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); - data->rx.sge_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.sge_map)); - data->rx.sge_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.sge_map)); - data->rx.cqe_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); - data->rx.cqe_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); - data->rx.is_leading_rss = - (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; - data->rx.is_approx_mcast = data->rx.is_leading_rss; +static inline void bnx2x_vlan_mac_set_rdata_e1x(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, int type, int cam_offset, bool add, + u8 *mac, u16 vlan_id, int opcode, struct mac_configuration_cmd *config) +{ + struct mac_configuration_entry *cfg_entry = &config->config_table[0]; + struct bnx2x_raw_obj *raw = &o->raw; - /* Tx data */ - data->tx.enforce_security_flg = 0; /* VF specific */ - data->tx.tx_status_block_id = params->txq_params.fw_sb_id; - data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; - data->tx.mtu = 0; /* VF specific */ - data->tx.tx_bd_page_base.lo = - cpu_to_le32(U64_LO(params->txq_params.dscr_map)); - data->tx.tx_bd_page_base.hi = - cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + bnx2x_vlan_mac_set_rdata_hdr_e1x(bp, o, type, cam_offset, + &config->hdr); + bnx2x_vlan_mac_set_cfg_entry_e1x(bp, o, add, opcode, mac, vlan_id, + cfg_entry); - /* flow control data */ - data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); - data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); - data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); - data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); - data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); - data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); - data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); - - data->fc.safc_group_num = params->txq_params.cos; - data->fc.safc_group_en_flg = - (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; - data->fc.traffic_type = - (params->ramrod_params.flags & CLIENT_IS_FCOE) ? - LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; + DP(BNX2X_MSG_SP, "%s MAC "BNX2X_MAC_FMT" CLID %d CAM offset %d\n", + (add ? "setting" : "clearing"), + BNX2X_MAC_PRN_LIST(mac), raw->cl_id, cam_offset); } - -int bnx2x_setup_fw_client(struct bnx2x *bp, - struct bnx2x_client_init_params *params, - u8 activate, - struct client_init_ramrod_data *data, - dma_addr_t data_mapping) +/** + * bnx2x_set_one_mac_e1x - fill a single MAC rule ramrod data + * + * @bp: device handle + * @o: bnx2x_vlan_mac_obj + * @elem: bnx2x_exeq_elem + * @rule_idx: rule_idx + * @cam_offset: cam_offset + */ +static void bnx2x_set_one_mac_e1x(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + struct bnx2x_exeq_elem *elem, int rule_idx, + int cam_offset) { - u16 hc_usec; - int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; - int ramrod_flags = 0, rc; - - /* HC and context validation values */ - hc_usec = params->txq_params.hc_rate ? - 1000000 / params->txq_params.hc_rate : 0; - bnx2x_update_coalesce_sb_index(bp, - params->txq_params.fw_sb_id, - params->txq_params.sb_cq_index, - !(params->txq_params.flags & QUEUE_FLG_HC), - hc_usec); + struct bnx2x_raw_obj *raw = &o->raw; + struct mac_configuration_cmd *config = + (struct mac_configuration_cmd *)(raw->rdata); + /* + * 57710 and 57711 do not support MOVE command, + * so it's either ADD or DEL + */ + bool add = (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ? + true : false; - *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; + /* Reset the ramrod data buffer */ + memset(config, 0, sizeof(*config)); - hc_usec = params->rxq_params.hc_rate ? - 1000000 / params->rxq_params.hc_rate : 0; - bnx2x_update_coalesce_sb_index(bp, - params->rxq_params.fw_sb_id, - params->rxq_params.sb_cq_index, - !(params->rxq_params.flags & QUEUE_FLG_HC), - hc_usec); + bnx2x_vlan_mac_set_rdata_e1x(bp, o, BNX2X_FILTER_MAC_PENDING, + cam_offset, add, + elem->cmd_data.vlan_mac.u.mac.mac, 0, + ETH_VLAN_FILTER_ANY_VLAN, config); +} - bnx2x_set_ctx_validation(params->rxq_params.cxt, - params->rxq_params.cid); +static void bnx2x_set_one_vlan_e2(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + struct bnx2x_exeq_elem *elem, int rule_idx, + int cam_offset) +{ + struct bnx2x_raw_obj *raw = &o->raw; + struct eth_classify_rules_ramrod_data *data = + (struct eth_classify_rules_ramrod_data *)(raw->rdata); + int rule_cnt = rule_idx + 1; + union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx]; + int cmd = elem->cmd_data.vlan_mac.cmd; + bool add = (cmd == BNX2X_VLAN_MAC_ADD) ? true : false; + u16 vlan = elem->cmd_data.vlan_mac.u.vlan.vlan; + + /* Reset the ramrod data buffer for the first rule */ + if (rule_idx == 0) + memset(data, 0, sizeof(*data)); + + /* Set a rule header */ + bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_VLAN, + &rule_entry->vlan.header); + + DP(BNX2X_MSG_SP, "About to %s VLAN %d\n", (add ? "add" : "delete"), + vlan); + + /* Set a VLAN itself */ + rule_entry->vlan.vlan = cpu_to_le16(vlan); + + /* MOVE: Add a rule that will add this MAC to the target Queue */ + if (cmd == BNX2X_VLAN_MAC_MOVE) { + rule_entry++; + rule_cnt++; + + /* Setup ramrod data */ + bnx2x_vlan_mac_set_cmd_hdr_e2(bp, + elem->cmd_data.vlan_mac.target_obj, + true, CLASSIFY_RULE_OPCODE_VLAN, + &rule_entry->vlan.header); + + /* Set a VLAN itself */ + rule_entry->vlan.vlan = cpu_to_le16(vlan); + } - /* zero stats */ - if (params->txq_params.flags & QUEUE_FLG_STATS) - storm_memset_xstats_zero(bp, BP_PORT(bp), - params->txq_params.stat_id); + /* Set the ramrod data header */ + /* TODO: take this to the higher level in order to prevent multiple + writing */ + bnx2x_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header, + rule_cnt); +} - if (params->rxq_params.flags & QUEUE_FLG_STATS) { - storm_memset_ustats_zero(bp, BP_PORT(bp), - params->rxq_params.stat_id); - storm_memset_tstats_zero(bp, BP_PORT(bp), - params->rxq_params.stat_id); +static void bnx2x_set_one_vlan_mac_e2(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + struct bnx2x_exeq_elem *elem, + int rule_idx, int cam_offset) +{ + struct bnx2x_raw_obj *raw = &o->raw; + struct eth_classify_rules_ramrod_data *data = + (struct eth_classify_rules_ramrod_data *)(raw->rdata); + int rule_cnt = rule_idx + 1; + union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx]; + int cmd = elem->cmd_data.vlan_mac.cmd; + bool add = (cmd == BNX2X_VLAN_MAC_ADD) ? true : false; + u16 vlan = elem->cmd_data.vlan_mac.u.vlan_mac.vlan; + u8 *mac = elem->cmd_data.vlan_mac.u.vlan_mac.mac; + + + /* Reset the ramrod data buffer for the first rule */ + if (rule_idx == 0) + memset(data, 0, sizeof(*data)); + + /* Set a rule header */ + bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_PAIR, + &rule_entry->pair.header); + + /* Set VLAN and MAC themselvs */ + rule_entry->pair.vlan = cpu_to_le16(vlan); + bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, + &rule_entry->pair.mac_mid, + &rule_entry->pair.mac_lsb, mac); + + /* MOVE: Add a rule that will add this MAC to the target Queue */ + if (cmd == BNX2X_VLAN_MAC_MOVE) { + rule_entry++; + rule_cnt++; + + /* Setup ramrod data */ + bnx2x_vlan_mac_set_cmd_hdr_e2(bp, + elem->cmd_data.vlan_mac.target_obj, + true, CLASSIFY_RULE_OPCODE_PAIR, + &rule_entry->pair.header); + + /* Set a VLAN itself */ + rule_entry->pair.vlan = cpu_to_le16(vlan); + bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb, + &rule_entry->pair.mac_mid, + &rule_entry->pair.mac_lsb, mac); } - /* Fill the ramrod data */ - bnx2x_fill_cl_init_data(bp, params, activate, data); + /* Set the ramrod data header */ + /* TODO: take this to the higher level in order to prevent multiple + writing */ + bnx2x_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header, + rule_cnt); +} - /* SETUP ramrod. - * - * bnx2x_sp_post() takes a spin_lock thus no other explict memory - * barrier except from mmiowb() is needed to impose a - * proper ordering of memory operations. +/** + * bnx2x_set_one_vlan_mac_e1h - + * + * @bp: device handle + * @o: bnx2x_vlan_mac_obj + * @elem: bnx2x_exeq_elem + * @rule_idx: rule_idx + * @cam_offset: cam_offset + */ +static void bnx2x_set_one_vlan_mac_e1h(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + struct bnx2x_exeq_elem *elem, + int rule_idx, int cam_offset) +{ + struct bnx2x_raw_obj *raw = &o->raw; + struct mac_configuration_cmd *config = + (struct mac_configuration_cmd *)(raw->rdata); + /* + * 57710 and 57711 do not support MOVE command, + * so it's either ADD or DEL */ - mmiowb(); - + bool add = (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ? + true : false; - bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, - U64_HI(data_mapping), U64_LO(data_mapping), 0); + /* Reset the ramrod data buffer */ + memset(config, 0, sizeof(*config)); - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, - params->ramrod_params.index, - params->ramrod_params.pstate, - ramrod_flags); - return rc; + bnx2x_vlan_mac_set_rdata_e1x(bp, o, BNX2X_FILTER_VLAN_MAC_PENDING, + cam_offset, add, + elem->cmd_data.vlan_mac.u.vlan_mac.mac, + elem->cmd_data.vlan_mac.u.vlan_mac.vlan, + ETH_VLAN_FILTER_CLASSIFY, config); } -void bnx2x_push_indir_table(struct bnx2x *bp) -{ - int func = BP_FUNC(bp); +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + +/** + * bnx2x_vlan_mac_restore - reconfigure next MAC/VLAN/VLAN-MAC element + * + * @bp: device handle + * @p: command parameters + * @ppos: pointer to the cooky + * + * reconfigure next MAC/VLAN/VLAN-MAC element from the + * previously configured elements list. + * + * from command parameters only RAMROD_COMP_WAIT bit in ramrod_flags is taken + * into an account + * + * pointer to the cooky - that should be given back in the next call to make + * function handle the next element. If *ppos is set to NULL it will restart the + * iterator. If returned *ppos == NULL this means that the last element has been + * handled. + * + */ +static int bnx2x_vlan_mac_restore(struct bnx2x *bp, + struct bnx2x_vlan_mac_ramrod_params *p, + struct bnx2x_vlan_mac_registry_elem **ppos) +{ + struct bnx2x_vlan_mac_registry_elem *pos; + struct bnx2x_vlan_mac_obj *o = p->vlan_mac_obj; + + /* If list is empty - there is nothing to do here */ + if (list_empty(&o->head)) { + *ppos = NULL; + return 0; + } + + /* make a step... */ + if (*ppos == NULL) + *ppos = list_first_entry(&o->head, + struct bnx2x_vlan_mac_registry_elem, + link); + else + *ppos = list_next_entry(*ppos, link); + + pos = *ppos; + + /* If it's the last step - return NULL */ + if (list_is_last(&pos->link, &o->head)) + *ppos = NULL; + + /* Prepare a 'user_req' */ + memcpy(&p->user_req.u, &pos->u, sizeof(pos->u)); + + /* Set the command */ + p->user_req.cmd = BNX2X_VLAN_MAC_ADD; + + /* Set vlan_mac_flags */ + p->user_req.vlan_mac_flags = pos->vlan_mac_flags; + + /* Set a restore bit */ + __set_bit(RAMROD_RESTORE, &p->ramrod_flags); + + return bnx2x_config_vlan_mac(bp, p); +} + +/* + * bnx2x_exeq_get_mac/bnx2x_exeq_get_vlan/bnx2x_exeq_get_vlan_mac return a + * pointer to an element with a specific criteria and NULL if such an element + * hasn't been found. + */ +static struct bnx2x_exeq_elem *bnx2x_exeq_get_mac( + struct bnx2x_exe_queue_obj *o, + struct bnx2x_exeq_elem *elem) +{ + struct bnx2x_exeq_elem *pos; + struct bnx2x_mac_ramrod_data *data = &elem->cmd_data.vlan_mac.u.mac; + + /* Check pending for execution commands */ + list_for_each_entry(pos, &o->exe_queue, link) + if (!memcmp(&pos->cmd_data.vlan_mac.u.mac, data, + sizeof(*data)) && + (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd)) + return pos; + + return NULL; +} + +static struct bnx2x_exeq_elem *bnx2x_exeq_get_vlan( + struct bnx2x_exe_queue_obj *o, + struct bnx2x_exeq_elem *elem) +{ + struct bnx2x_exeq_elem *pos; + struct bnx2x_vlan_ramrod_data *data = &elem->cmd_data.vlan_mac.u.vlan; + + /* Check pending for execution commands */ + list_for_each_entry(pos, &o->exe_queue, link) + if (!memcmp(&pos->cmd_data.vlan_mac.u.vlan, data, + sizeof(*data)) && + (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd)) + return pos; + + return NULL; +} + +static struct bnx2x_exeq_elem *bnx2x_exeq_get_vlan_mac( + struct bnx2x_exe_queue_obj *o, + struct bnx2x_exeq_elem *elem) +{ + struct bnx2x_exeq_elem *pos; + struct bnx2x_vlan_mac_ramrod_data *data = + &elem->cmd_data.vlan_mac.u.vlan_mac; + + /* Check pending for execution commands */ + list_for_each_entry(pos, &o->exe_queue, link) + if (!memcmp(&pos->cmd_data.vlan_mac.u.vlan_mac, data, + sizeof(*data)) && + (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd)) + return pos; + + return NULL; +} + +/** + * bnx2x_validate_vlan_mac_add - check if an ADD command can be executed + * + * @bp: device handle + * @qo: bnx2x_qable_obj + * @elem: bnx2x_exeq_elem + * + * Checks that the requested configuration can be added. If yes and if + * requested, consume CAM credit. + * + * The 'validate' is run after the 'optimize'. + * + */ +static inline int bnx2x_validate_vlan_mac_add(struct bnx2x *bp, + union bnx2x_qable_obj *qo, + struct bnx2x_exeq_elem *elem) +{ + struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac; + struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; + int rc; + + /* Check the registry */ + rc = o->check_add(o, &elem->cmd_data.vlan_mac.u); + if (rc) { + DP(BNX2X_MSG_SP, "ADD command is not allowed considering " + "current registry state\n"); + return rc; + } + + /* + * Check if there is a pending ADD command for this + * MAC/VLAN/VLAN-MAC. Return an error if there is. + */ + if (exeq->get(exeq, elem)) { + DP(BNX2X_MSG_SP, "There is a pending ADD command already\n"); + return -EEXIST; + } + + /* + * TODO: Check the pending MOVE from other objects where this + * object is a destination object. + */ + + /* Consume the credit if not requested not to */ + if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, + &elem->cmd_data.vlan_mac.vlan_mac_flags) || + o->get_credit(o))) + return -EINVAL; + + return 0; +} + +/** + * bnx2x_validate_vlan_mac_del - check if the DEL command can be executed + * + * @bp: device handle + * @qo: quable object to check + * @elem: element that needs to be deleted + * + * Checks that the requested configuration can be deleted. If yes and if + * requested, returns a CAM credit. + * + * The 'validate' is run after the 'optimize'. + */ +static inline int bnx2x_validate_vlan_mac_del(struct bnx2x *bp, + union bnx2x_qable_obj *qo, + struct bnx2x_exeq_elem *elem) +{ + struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac; + struct bnx2x_vlan_mac_registry_elem *pos; + struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; + struct bnx2x_exeq_elem query_elem; + + /* If this classification can not be deleted (doesn't exist) + * - return a BNX2X_EXIST. + */ + pos = o->check_del(o, &elem->cmd_data.vlan_mac.u); + if (!pos) { + DP(BNX2X_MSG_SP, "DEL command is not allowed considering " + "current registry state\n"); + return -EEXIST; + } + + /* + * Check if there are pending DEL or MOVE commands for this + * MAC/VLAN/VLAN-MAC. Return an error if so. + */ + memcpy(&query_elem, elem, sizeof(query_elem)); + + /* Check for MOVE commands */ + query_elem.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_MOVE; + if (exeq->get(exeq, &query_elem)) { + BNX2X_ERR("There is a pending MOVE command already\n"); + return -EINVAL; + } + + /* Check for DEL commands */ + if (exeq->get(exeq, elem)) { + DP(BNX2X_MSG_SP, "There is a pending DEL command already\n"); + return -EEXIST; + } + + /* Return the credit to the credit pool if not requested not to */ + if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, + &elem->cmd_data.vlan_mac.vlan_mac_flags) || + o->put_credit(o))) { + BNX2X_ERR("Failed to return a credit\n"); + return -EINVAL; + } + + return 0; +} + +/** + * bnx2x_validate_vlan_mac_move - check if the MOVE command can be executed + * + * @bp: device handle + * @qo: quable object to check (source) + * @elem: element that needs to be moved + * + * Checks that the requested configuration can be moved. If yes and if + * requested, returns a CAM credit. + * + * The 'validate' is run after the 'optimize'. + */ +static inline int bnx2x_validate_vlan_mac_move(struct bnx2x *bp, + union bnx2x_qable_obj *qo, + struct bnx2x_exeq_elem *elem) +{ + struct bnx2x_vlan_mac_obj *src_o = &qo->vlan_mac; + struct bnx2x_vlan_mac_obj *dest_o = elem->cmd_data.vlan_mac.target_obj; + struct bnx2x_exeq_elem query_elem; + struct bnx2x_exe_queue_obj *src_exeq = &src_o->exe_queue; + struct bnx2x_exe_queue_obj *dest_exeq = &dest_o->exe_queue; + + /* + * Check if we can perform this operation based on the current registry + * state. + */ + if (!src_o->check_move(src_o, dest_o, &elem->cmd_data.vlan_mac.u)) { + DP(BNX2X_MSG_SP, "MOVE command is not allowed considering " + "current registry state\n"); + return -EINVAL; + } + + /* + * Check if there is an already pending DEL or MOVE command for the + * source object or ADD command for a destination object. Return an + * error if so. + */ + memcpy(&query_elem, elem, sizeof(query_elem)); + + /* Check DEL on source */ + query_elem.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_DEL; + if (src_exeq->get(src_exeq, &query_elem)) { + BNX2X_ERR("There is a pending DEL command on the source " + "queue already\n"); + return -EINVAL; + } + + /* Check MOVE on source */ + if (src_exeq->get(src_exeq, elem)) { + DP(BNX2X_MSG_SP, "There is a pending MOVE command already\n"); + return -EEXIST; + } + + /* Check ADD on destination */ + query_elem.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_ADD; + if (dest_exeq->get(dest_exeq, &query_elem)) { + BNX2X_ERR("There is a pending ADD command on the " + "destination queue already\n"); + return -EINVAL; + } + + /* Consume the credit if not requested not to */ + if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT_DEST, + &elem->cmd_data.vlan_mac.vlan_mac_flags) || + dest_o->get_credit(dest_o))) + return -EINVAL; + + if (!(test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, + &elem->cmd_data.vlan_mac.vlan_mac_flags) || + src_o->put_credit(src_o))) { + /* return the credit taken from dest... */ + dest_o->put_credit(dest_o); + return -EINVAL; + } + + return 0; +} + +static int bnx2x_validate_vlan_mac(struct bnx2x *bp, + union bnx2x_qable_obj *qo, + struct bnx2x_exeq_elem *elem) +{ + switch (elem->cmd_data.vlan_mac.cmd) { + case BNX2X_VLAN_MAC_ADD: + return bnx2x_validate_vlan_mac_add(bp, qo, elem); + case BNX2X_VLAN_MAC_DEL: + return bnx2x_validate_vlan_mac_del(bp, qo, elem); + case BNX2X_VLAN_MAC_MOVE: + return bnx2x_validate_vlan_mac_move(bp, qo, elem); + default: + return -EINVAL; + } +} + +/** + * bnx2x_wait_vlan_mac - passivly wait for 5 seconds until all work completes. + * + * @bp: device handle + * @o: bnx2x_vlan_mac_obj + * + */ +static int bnx2x_wait_vlan_mac(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o) +{ + int cnt = 5000, rc; + struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; + struct bnx2x_raw_obj *raw = &o->raw; + + while (cnt--) { + /* Wait for the current command to complete */ + rc = raw->wait_comp(bp, raw); + if (rc) + return rc; + + /* Wait until there are no pending commands */ + if (!bnx2x_exe_queue_empty(exeq)) + usleep_range(1000, 1000); + else + return 0; + } + + return -EBUSY; +} + +/** + * bnx2x_complete_vlan_mac - complete one VLAN-MAC ramrod + * + * @bp: device handle + * @o: bnx2x_vlan_mac_obj + * @cqe: + * @cont: if true schedule next execution chunk + * + */ +static int bnx2x_complete_vlan_mac(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + union event_ring_elem *cqe, + unsigned long *ramrod_flags) +{ + struct bnx2x_raw_obj *r = &o->raw; + int rc; + + /* Reset pending list */ + bnx2x_exe_queue_reset_pending(bp, &o->exe_queue); + + /* Clear pending */ + r->clear_pending(r); + + /* If ramrod failed this is most likely a SW bug */ + if (cqe->message.error) + return -EINVAL; + + /* Run the next bulk of pending commands if requeted */ + if (test_bit(RAMROD_CONT, ramrod_flags)) { + rc = bnx2x_exe_queue_step(bp, &o->exe_queue, ramrod_flags); + if (rc < 0) + return rc; + } + + /* If there is more work to do return PENDING */ + if (!bnx2x_exe_queue_empty(&o->exe_queue)) + return 1; + + return 0; +} + +/** + * bnx2x_optimize_vlan_mac - optimize ADD and DEL commands. + * + * @bp: device handle + * @o: bnx2x_qable_obj + * @elem: bnx2x_exeq_elem + */ +static int bnx2x_optimize_vlan_mac(struct bnx2x *bp, + union bnx2x_qable_obj *qo, + struct bnx2x_exeq_elem *elem) +{ + struct bnx2x_exeq_elem query, *pos; + struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac; + struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; + + memcpy(&query, elem, sizeof(query)); + + switch (elem->cmd_data.vlan_mac.cmd) { + case BNX2X_VLAN_MAC_ADD: + query.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_DEL; + break; + case BNX2X_VLAN_MAC_DEL: + query.cmd_data.vlan_mac.cmd = BNX2X_VLAN_MAC_ADD; + break; + default: + /* Don't handle anything other than ADD or DEL */ + return 0; + } + + /* If we found the appropriate element - delete it */ + pos = exeq->get(exeq, &query); + if (pos) { + + /* Return the credit of the optimized command */ + if (!test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT, + &pos->cmd_data.vlan_mac.vlan_mac_flags)) { + if ((query.cmd_data.vlan_mac.cmd == + BNX2X_VLAN_MAC_ADD) && !o->put_credit(o)) { + BNX2X_ERR("Failed to return the credit for the " + "optimized ADD command\n"); + return -EINVAL; + } else if (!o->get_credit(o)) { /* VLAN_MAC_DEL */ + BNX2X_ERR("Failed to recover the credit from " + "the optimized DEL command\n"); + return -EINVAL; + } + } + + DP(BNX2X_MSG_SP, "Optimizing %s command\n", + (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ? + "ADD" : "DEL"); + + list_del(&pos->link); + bnx2x_exe_queue_free_elem(bp, pos); + return 1; + } + + return 0; +} + +/** + * bnx2x_vlan_mac_get_registry_elem - prepare a registry element + * + * @bp: device handle + * @o: + * @elem: + * @restore: + * @re: + * + * prepare a registry element according to the current command request. + */ +static inline int bnx2x_vlan_mac_get_registry_elem( + struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + struct bnx2x_exeq_elem *elem, + bool restore, + struct bnx2x_vlan_mac_registry_elem **re) +{ + int cmd = elem->cmd_data.vlan_mac.cmd; + struct bnx2x_vlan_mac_registry_elem *reg_elem; + + /* Allocate a new registry element if needed. */ + if (!restore && + ((cmd == BNX2X_VLAN_MAC_ADD) || (cmd == BNX2X_VLAN_MAC_MOVE))) { + reg_elem = kzalloc(sizeof(*reg_elem), GFP_ATOMIC); + if (!reg_elem) + return -ENOMEM; + + /* Get a new CAM offset */ + if (!o->get_cam_offset(o, ®_elem->cam_offset)) { + /* + * This shell never happen, because we have checked the + * CAM availiability in the 'validate'. + */ + WARN_ON(1); + kfree(reg_elem); + return -EINVAL; + } + + DP(BNX2X_MSG_SP, "Got cam offset %d\n", reg_elem->cam_offset); + + /* Set a VLAN-MAC data */ + memcpy(®_elem->u, &elem->cmd_data.vlan_mac.u, + sizeof(reg_elem->u)); + + /* Copy the flags (needed for DEL and RESTORE flows) */ + reg_elem->vlan_mac_flags = + elem->cmd_data.vlan_mac.vlan_mac_flags; + } else /* DEL, RESTORE */ + reg_elem = o->check_del(o, &elem->cmd_data.vlan_mac.u); + + *re = reg_elem; + return 0; +} + +/** + * bnx2x_execute_vlan_mac - execute vlan mac command + * + * @bp: device handle + * @qo: + * @exe_chunk: + * @ramrod_flags: + * + * go and send a ramrod! + */ +static int bnx2x_execute_vlan_mac(struct bnx2x *bp, + union bnx2x_qable_obj *qo, + struct list_head *exe_chunk, + unsigned long *ramrod_flags) +{ + struct bnx2x_exeq_elem *elem; + struct bnx2x_vlan_mac_obj *o = &qo->vlan_mac, *cam_obj; + struct bnx2x_raw_obj *r = &o->raw; + int rc, idx = 0; + bool restore = test_bit(RAMROD_RESTORE, ramrod_flags); + bool drv_only = test_bit(RAMROD_DRV_CLR_ONLY, ramrod_flags); + struct bnx2x_vlan_mac_registry_elem *reg_elem; + int cmd; + + /* + * If DRIVER_ONLY execution is requested, cleanup a registry + * and exit. Otherwise send a ramrod to FW. + */ + if (!drv_only) { + WARN_ON(r->check_pending(r)); + + /* Set pending */ + r->set_pending(r); + + /* Fill tha ramrod data */ + list_for_each_entry(elem, exe_chunk, link) { + cmd = elem->cmd_data.vlan_mac.cmd; + /* + * We will add to the target object in MOVE command, so + * change the object for a CAM search. + */ + if (cmd == BNX2X_VLAN_MAC_MOVE) + cam_obj = elem->cmd_data.vlan_mac.target_obj; + else + cam_obj = o; + + rc = bnx2x_vlan_mac_get_registry_elem(bp, cam_obj, + elem, restore, + ®_elem); + if (rc) + goto error_exit; + + WARN_ON(!reg_elem); + + /* Push a new entry into the registry */ + if (!restore && + ((cmd == BNX2X_VLAN_MAC_ADD) || + (cmd == BNX2X_VLAN_MAC_MOVE))) + list_add(®_elem->link, &cam_obj->head); + + /* Configure a single command in a ramrod data buffer */ + o->set_one_rule(bp, o, elem, idx, + reg_elem->cam_offset); + + /* MOVE command consumes 2 entries in the ramrod data */ + if (cmd == BNX2X_VLAN_MAC_MOVE) + idx += 2; + else + idx++; + } + + /* Commit the data writes towards the memory */ + mb(); + + rc = bnx2x_sp_post(bp, o->ramrod_cmd, r->cid, + U64_HI(r->rdata_mapping), + U64_LO(r->rdata_mapping), + ETH_CONNECTION_TYPE); + if (rc) + goto error_exit; + } + + /* Now, when we are done with the ramrod - clean up the registry */ + list_for_each_entry(elem, exe_chunk, link) { + cmd = elem->cmd_data.vlan_mac.cmd; + if ((cmd == BNX2X_VLAN_MAC_DEL) || + (cmd == BNX2X_VLAN_MAC_MOVE)) { + reg_elem = o->check_del(o, &elem->cmd_data.vlan_mac.u); + + WARN_ON(!reg_elem); + + o->put_cam_offset(o, reg_elem->cam_offset); + list_del(®_elem->link); + kfree(reg_elem); + } + } + + if (!drv_only) + return 1; + else + return 0; + +error_exit: + r->clear_pending(r); + + /* Cleanup a registry in case of a failure */ + list_for_each_entry(elem, exe_chunk, link) { + cmd = elem->cmd_data.vlan_mac.cmd; + + if (cmd == BNX2X_VLAN_MAC_MOVE) + cam_obj = elem->cmd_data.vlan_mac.target_obj; + else + cam_obj = o; + + /* Delete all newly added above entries */ + if (!restore && + ((cmd == BNX2X_VLAN_MAC_ADD) || + (cmd == BNX2X_VLAN_MAC_MOVE))) { + reg_elem = o->check_del(cam_obj, + &elem->cmd_data.vlan_mac.u); + if (reg_elem) { + list_del(®_elem->link); + kfree(reg_elem); + } + } + } + + return rc; +} + +static inline int bnx2x_vlan_mac_push_new_cmd( + struct bnx2x *bp, + struct bnx2x_vlan_mac_ramrod_params *p) +{ + struct bnx2x_exeq_elem *elem; + struct bnx2x_vlan_mac_obj *o = p->vlan_mac_obj; + bool restore = test_bit(RAMROD_RESTORE, &p->ramrod_flags); + + /* Allocate the execution queue element */ + elem = bnx2x_exe_queue_alloc_elem(bp); + if (!elem) + return -ENOMEM; + + /* Set the command 'length' */ + switch (p->user_req.cmd) { + case BNX2X_VLAN_MAC_MOVE: + elem->cmd_len = 2; + break; + default: + elem->cmd_len = 1; + } + + /* Fill the object specific info */ + memcpy(&elem->cmd_data.vlan_mac, &p->user_req, sizeof(p->user_req)); + + /* Try to add a new command to the pending list */ + return bnx2x_exe_queue_add(bp, &o->exe_queue, elem, restore); +} + +/** + * bnx2x_config_vlan_mac - configure VLAN/MAC/VLAN_MAC filtering rules. + * + * @bp: device handle + * @p: + * + */ +int bnx2x_config_vlan_mac( + struct bnx2x *bp, + struct bnx2x_vlan_mac_ramrod_params *p) +{ + int rc = 0; + struct bnx2x_vlan_mac_obj *o = p->vlan_mac_obj; + unsigned long *ramrod_flags = &p->ramrod_flags; + bool cont = test_bit(RAMROD_CONT, ramrod_flags); + struct bnx2x_raw_obj *raw = &o->raw; + + /* + * Add new elements to the execution list for commands that require it. + */ + if (!cont) { + rc = bnx2x_vlan_mac_push_new_cmd(bp, p); + if (rc) + return rc; + } + + /* + * If nothing will be executed further in this iteration we want to + * return PENDING if there are pending commands + */ + if (!bnx2x_exe_queue_empty(&o->exe_queue)) + rc = 1; + + /* Execute commands if required */ + if (cont || test_bit(RAMROD_EXEC, ramrod_flags) || + test_bit(RAMROD_COMP_WAIT, ramrod_flags)) { + rc = bnx2x_exe_queue_step(bp, &o->exe_queue, ramrod_flags); + if (rc < 0) + return rc; + } + + /* + * RAMROD_COMP_WAIT is a superset of RAMROD_EXEC. If it was set + * then user want to wait until the last command is done. + */ + if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) { + /* + * Wait maximum for the current exe_queue length iterations plus + * one (for the current pending command). + */ + int max_iterations = bnx2x_exe_queue_length(&o->exe_queue) + 1; + + while (!bnx2x_exe_queue_empty(&o->exe_queue) && + max_iterations--) { + + /* Wait for the current command to complete */ + rc = raw->wait_comp(bp, raw); + if (rc) + return rc; + + /* Make a next step */ + rc = bnx2x_exe_queue_step(bp, &o->exe_queue, + ramrod_flags); + if (rc < 0) + return rc; + } + + return 0; + } + + return rc; +} + + + +/** + * bnx2x_vlan_mac_del_all - delete elements with given vlan_mac_flags spec + * + * @bp: device handle + * @o: + * @vlan_mac_flags: + * @ramrod_flags: execution flags to be used for this deletion + * + * if the last operation has completed successfully and there are no + * moreelements left, positive value if the last operation has completed + * successfully and there are more previously configured elements, negative + * value is current operation has failed. + */ +static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + unsigned long *vlan_mac_flags, + unsigned long *ramrod_flags) +{ + struct bnx2x_vlan_mac_registry_elem *pos = NULL; + int rc = 0; + struct bnx2x_vlan_mac_ramrod_params p; + struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; + struct bnx2x_exeq_elem *exeq_pos, *exeq_pos_n; + + /* Clear pending commands first */ + + spin_lock_bh(&exeq->lock); + + list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) { + if (exeq_pos->cmd_data.vlan_mac.vlan_mac_flags == + *vlan_mac_flags) + list_del(&exeq_pos->link); + } + + spin_unlock_bh(&exeq->lock); + + /* Prepare a command request */ + memset(&p, 0, sizeof(p)); + p.vlan_mac_obj = o; + p.ramrod_flags = *ramrod_flags; + p.user_req.cmd = BNX2X_VLAN_MAC_DEL; + + /* + * Add all but the last VLAN-MAC to the execution queue without actually + * execution anything. + */ + __clear_bit(RAMROD_COMP_WAIT, &p.ramrod_flags); + __clear_bit(RAMROD_EXEC, &p.ramrod_flags); + __clear_bit(RAMROD_CONT, &p.ramrod_flags); + + list_for_each_entry(pos, &o->head, link) { + if (pos->vlan_mac_flags == *vlan_mac_flags) { + p.user_req.vlan_mac_flags = pos->vlan_mac_flags; + memcpy(&p.user_req.u, &pos->u, sizeof(pos->u)); + rc = bnx2x_config_vlan_mac(bp, &p); + if (rc < 0) { + BNX2X_ERR("Failed to add a new DEL command\n"); + return rc; + } + } + } + + p.ramrod_flags = *ramrod_flags; + __set_bit(RAMROD_CONT, &p.ramrod_flags); + + return bnx2x_config_vlan_mac(bp, &p); +} + +static inline void bnx2x_init_raw_obj(struct bnx2x_raw_obj *raw, u8 cl_id, + u32 cid, u8 func_id, void *rdata, dma_addr_t rdata_mapping, int state, + unsigned long *pstate, bnx2x_obj_type type) +{ + raw->func_id = func_id; + raw->cid = cid; + raw->cl_id = cl_id; + raw->rdata = rdata; + raw->rdata_mapping = rdata_mapping; + raw->state = state; + raw->pstate = pstate; + raw->obj_type = type; + raw->check_pending = bnx2x_raw_check_pending; + raw->clear_pending = bnx2x_raw_clear_pending; + raw->set_pending = bnx2x_raw_set_pending; + raw->wait_comp = bnx2x_raw_wait; +} + +static inline void bnx2x_init_vlan_mac_common(struct bnx2x_vlan_mac_obj *o, + u8 cl_id, u32 cid, u8 func_id, void *rdata, dma_addr_t rdata_mapping, + int state, unsigned long *pstate, bnx2x_obj_type type, + struct bnx2x_credit_pool_obj *macs_pool, + struct bnx2x_credit_pool_obj *vlans_pool) +{ + INIT_LIST_HEAD(&o->head); + + o->macs_pool = macs_pool; + o->vlans_pool = vlans_pool; + + o->delete_all = bnx2x_vlan_mac_del_all; + o->restore = bnx2x_vlan_mac_restore; + o->complete = bnx2x_complete_vlan_mac; + o->wait = bnx2x_wait_vlan_mac; + + bnx2x_init_raw_obj(&o->raw, cl_id, cid, func_id, rdata, rdata_mapping, + state, pstate, type); +} + + +void bnx2x_init_mac_obj(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *mac_obj, + u8 cl_id, u32 cid, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, int state, + unsigned long *pstate, bnx2x_obj_type type, + struct bnx2x_credit_pool_obj *macs_pool) +{ + union bnx2x_qable_obj *qable_obj = (union bnx2x_qable_obj *)mac_obj; + + bnx2x_init_vlan_mac_common(mac_obj, cl_id, cid, func_id, rdata, + rdata_mapping, state, pstate, type, + macs_pool, NULL); + + /* CAM credit pool handling */ + mac_obj->get_credit = bnx2x_get_credit_mac; + mac_obj->put_credit = bnx2x_put_credit_mac; + mac_obj->get_cam_offset = bnx2x_get_cam_offset_mac; + mac_obj->put_cam_offset = bnx2x_put_cam_offset_mac; + + if (CHIP_IS_E1x(bp)) { + mac_obj->set_one_rule = bnx2x_set_one_mac_e1x; + mac_obj->check_del = bnx2x_check_mac_del; + mac_obj->check_add = bnx2x_check_mac_add; + mac_obj->check_move = bnx2x_check_move_always_err; + mac_obj->ramrod_cmd = RAMROD_CMD_ID_ETH_SET_MAC; + + /* Exe Queue */ + bnx2x_exe_queue_init(bp, + &mac_obj->exe_queue, 1, qable_obj, + bnx2x_validate_vlan_mac, + bnx2x_optimize_vlan_mac, + bnx2x_execute_vlan_mac, + bnx2x_exeq_get_mac); + } else { + mac_obj->set_one_rule = bnx2x_set_one_mac_e2; + mac_obj->check_del = bnx2x_check_mac_del; + mac_obj->check_add = bnx2x_check_mac_add; + mac_obj->check_move = bnx2x_check_move; + mac_obj->ramrod_cmd = + RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; + + /* Exe Queue */ + bnx2x_exe_queue_init(bp, + &mac_obj->exe_queue, CLASSIFY_RULES_COUNT, + qable_obj, bnx2x_validate_vlan_mac, + bnx2x_optimize_vlan_mac, + bnx2x_execute_vlan_mac, + bnx2x_exeq_get_mac); + } +} + +void bnx2x_init_vlan_obj(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *vlan_obj, + u8 cl_id, u32 cid, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, int state, + unsigned long *pstate, bnx2x_obj_type type, + struct bnx2x_credit_pool_obj *vlans_pool) +{ + union bnx2x_qable_obj *qable_obj = (union bnx2x_qable_obj *)vlan_obj; + + bnx2x_init_vlan_mac_common(vlan_obj, cl_id, cid, func_id, rdata, + rdata_mapping, state, pstate, type, NULL, + vlans_pool); + + vlan_obj->get_credit = bnx2x_get_credit_vlan; + vlan_obj->put_credit = bnx2x_put_credit_vlan; + vlan_obj->get_cam_offset = bnx2x_get_cam_offset_vlan; + vlan_obj->put_cam_offset = bnx2x_put_cam_offset_vlan; + + if (CHIP_IS_E1x(bp)) { + BNX2X_ERR("Do not support chips others than E2 and newer\n"); + BUG(); + } else { + vlan_obj->set_one_rule = bnx2x_set_one_vlan_e2; + vlan_obj->check_del = bnx2x_check_vlan_del; + vlan_obj->check_add = bnx2x_check_vlan_add; + vlan_obj->check_move = bnx2x_check_move; + vlan_obj->ramrod_cmd = + RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; + + /* Exe Queue */ + bnx2x_exe_queue_init(bp, + &vlan_obj->exe_queue, CLASSIFY_RULES_COUNT, + qable_obj, bnx2x_validate_vlan_mac, + bnx2x_optimize_vlan_mac, + bnx2x_execute_vlan_mac, + bnx2x_exeq_get_vlan); + } +} + +void bnx2x_init_vlan_mac_obj(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *vlan_mac_obj, + u8 cl_id, u32 cid, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, int state, + unsigned long *pstate, bnx2x_obj_type type, + struct bnx2x_credit_pool_obj *macs_pool, + struct bnx2x_credit_pool_obj *vlans_pool) +{ + union bnx2x_qable_obj *qable_obj = + (union bnx2x_qable_obj *)vlan_mac_obj; + + bnx2x_init_vlan_mac_common(vlan_mac_obj, cl_id, cid, func_id, rdata, + rdata_mapping, state, pstate, type, + macs_pool, vlans_pool); + + /* CAM pool handling */ + vlan_mac_obj->get_credit = bnx2x_get_credit_vlan_mac; + vlan_mac_obj->put_credit = bnx2x_put_credit_vlan_mac; + /* + * CAM offset is relevant for 57710 and 57711 chips only which have a + * single CAM for both MACs and VLAN-MAC pairs. So the offset + * will be taken from MACs' pool object only. + */ + vlan_mac_obj->get_cam_offset = bnx2x_get_cam_offset_mac; + vlan_mac_obj->put_cam_offset = bnx2x_put_cam_offset_mac; + + if (CHIP_IS_E1(bp)) { + BNX2X_ERR("Do not support chips others than E2\n"); + BUG(); + } else if (CHIP_IS_E1H(bp)) { + vlan_mac_obj->set_one_rule = bnx2x_set_one_vlan_mac_e1h; + vlan_mac_obj->check_del = bnx2x_check_vlan_mac_del; + vlan_mac_obj->check_add = bnx2x_check_vlan_mac_add; + vlan_mac_obj->check_move = bnx2x_check_move_always_err; + vlan_mac_obj->ramrod_cmd = RAMROD_CMD_ID_ETH_SET_MAC; + + /* Exe Queue */ + bnx2x_exe_queue_init(bp, + &vlan_mac_obj->exe_queue, 1, qable_obj, + bnx2x_validate_vlan_mac, + bnx2x_optimize_vlan_mac, + bnx2x_execute_vlan_mac, + bnx2x_exeq_get_vlan_mac); + } else { + vlan_mac_obj->set_one_rule = bnx2x_set_one_vlan_mac_e2; + vlan_mac_obj->check_del = bnx2x_check_vlan_mac_del; + vlan_mac_obj->check_add = bnx2x_check_vlan_mac_add; + vlan_mac_obj->check_move = bnx2x_check_move; + vlan_mac_obj->ramrod_cmd = + RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; + + /* Exe Queue */ + bnx2x_exe_queue_init(bp, + &vlan_mac_obj->exe_queue, + CLASSIFY_RULES_COUNT, + qable_obj, bnx2x_validate_vlan_mac, + bnx2x_optimize_vlan_mac, + bnx2x_execute_vlan_mac, + bnx2x_exeq_get_vlan_mac); + } + +} + +/* RX_MODE verbs: DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */ +static inline void __storm_memset_mac_filters(struct bnx2x *bp, + struct tstorm_eth_mac_filter_config *mac_filters, + u16 pf_id) +{ + size_t size = sizeof(struct tstorm_eth_mac_filter_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_MAC_FILTER_CONFIG_OFFSET(pf_id); + + __storm_memset_struct(bp, addr, size, (u32 *)mac_filters); +} + +static int bnx2x_set_rx_mode_e1x(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p) +{ + /* update the bp MAC filter structure */ + u32 mask = (1 << p->cl_id); + + struct tstorm_eth_mac_filter_config *mac_filters = + (struct tstorm_eth_mac_filter_config *)p->rdata; + + /* initial seeting is drop-all */ + u8 drop_all_ucast = 1, drop_all_mcast = 1; + u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; + u8 unmatched_unicast = 0; + + /* In e1x there we only take into account rx acceot flag since tx switching + * isn't enabled. */ + if (test_bit(BNX2X_ACCEPT_UNICAST, &p->rx_accept_flags)) + /* accept matched ucast */ + drop_all_ucast = 0; + + if (test_bit(BNX2X_ACCEPT_MULTICAST, &p->rx_accept_flags)) + /* accept matched mcast */ + drop_all_mcast = 0; + + if (test_bit(BNX2X_ACCEPT_ALL_UNICAST, &p->rx_accept_flags)) { + /* accept all mcast */ + drop_all_ucast = 0; + accp_all_ucast = 1; + } + if (test_bit(BNX2X_ACCEPT_ALL_MULTICAST, &p->rx_accept_flags)) { + /* accept all mcast */ + drop_all_mcast = 0; + accp_all_mcast = 1; + } + if (test_bit(BNX2X_ACCEPT_BROADCAST, &p->rx_accept_flags)) + /* accept (all) bcast */ + accp_all_bcast = 1; + if (test_bit(BNX2X_ACCEPT_UNMATCHED, &p->rx_accept_flags)) + /* accept unmatched unicasts */ + unmatched_unicast = 1; + + mac_filters->ucast_drop_all = drop_all_ucast ? + mac_filters->ucast_drop_all | mask : + mac_filters->ucast_drop_all & ~mask; + + mac_filters->mcast_drop_all = drop_all_mcast ? + mac_filters->mcast_drop_all | mask : + mac_filters->mcast_drop_all & ~mask; + + mac_filters->ucast_accept_all = accp_all_ucast ? + mac_filters->ucast_accept_all | mask : + mac_filters->ucast_accept_all & ~mask; + + mac_filters->mcast_accept_all = accp_all_mcast ? + mac_filters->mcast_accept_all | mask : + mac_filters->mcast_accept_all & ~mask; + + mac_filters->bcast_accept_all = accp_all_bcast ? + mac_filters->bcast_accept_all | mask : + mac_filters->bcast_accept_all & ~mask; + + mac_filters->unmatched_unicast = unmatched_unicast ? + mac_filters->unmatched_unicast | mask : + mac_filters->unmatched_unicast & ~mask; + + DP(BNX2X_MSG_SP, "drop_ucast 0x%x\ndrop_mcast 0x%x\n accp_ucast 0x%x\n" + "accp_mcast 0x%x\naccp_bcast 0x%x\n", + mac_filters->ucast_drop_all, + mac_filters->mcast_drop_all, + mac_filters->ucast_accept_all, + mac_filters->mcast_accept_all, + mac_filters->bcast_accept_all); + + /* write the MAC filter structure*/ + __storm_memset_mac_filters(bp, mac_filters, p->func_id); + + /* The operation is completed */ + clear_bit(p->state, p->pstate); + smp_mb__after_clear_bit(); + + return 0; +} + +/* Setup ramrod data */ +static inline void bnx2x_rx_mode_set_rdata_hdr_e2(u32 cid, + struct eth_classify_header *hdr, + u8 rule_cnt) +{ + hdr->echo = cid; + hdr->rule_cnt = rule_cnt; +} + +static inline void bnx2x_rx_mode_set_cmd_state_e2(struct bnx2x *bp, + unsigned long accept_flags, + struct eth_filter_rules_cmd *cmd, + bool clear_accept_all) +{ + u16 state; + + /* start with 'drop-all' */ + state = ETH_FILTER_RULES_CMD_UCAST_DROP_ALL | + ETH_FILTER_RULES_CMD_MCAST_DROP_ALL; + + if (accept_flags) { + if (test_bit(BNX2X_ACCEPT_UNICAST, &accept_flags)) + state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL; + + if (test_bit(BNX2X_ACCEPT_MULTICAST, &accept_flags)) + state &= ~ETH_FILTER_RULES_CMD_MCAST_DROP_ALL; + + if (test_bit(BNX2X_ACCEPT_ALL_UNICAST, &accept_flags)) { + state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL; + state |= ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL; + } + + if (test_bit(BNX2X_ACCEPT_ALL_MULTICAST, &accept_flags)) { + state |= ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL; + state &= ~ETH_FILTER_RULES_CMD_MCAST_DROP_ALL; + } + if (test_bit(BNX2X_ACCEPT_BROADCAST, &accept_flags)) + state |= ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL; + + if (test_bit(BNX2X_ACCEPT_UNMATCHED, &accept_flags)) { + state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL; + state |= ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED; + } + if (test_bit(BNX2X_ACCEPT_ANY_VLAN, &accept_flags)) + state |= ETH_FILTER_RULES_CMD_ACCEPT_ANY_VLAN; + } + + /* Clear ACCEPT_ALL_XXX flags for FCoE L2 Queue */ + if (clear_accept_all) { + state &= ~ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL; + state &= ~ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL; + state &= ~ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL; + state &= ~ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED; + } + + cmd->state = cpu_to_le16(state); + +} + +static int bnx2x_set_rx_mode_e2(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p) +{ + struct eth_filter_rules_ramrod_data *data = p->rdata; + int rc; + u8 rule_idx = 0; + + /* Reset the ramrod data buffer */ + memset(data, 0, sizeof(*data)); + + /* Setup ramrod data */ + + /* Tx (internal switching) */ + if (test_bit(RAMROD_TX, &p->ramrod_flags)) { + data->rules[rule_idx].client_id = p->cl_id; + data->rules[rule_idx].func_id = p->func_id; + + data->rules[rule_idx].cmd_general_data = + ETH_FILTER_RULES_CMD_TX_CMD; + + bnx2x_rx_mode_set_cmd_state_e2(bp, p->tx_accept_flags, + &(data->rules[rule_idx++]), false); + } + + /* Rx */ + if (test_bit(RAMROD_RX, &p->ramrod_flags)) { + data->rules[rule_idx].client_id = p->cl_id; + data->rules[rule_idx].func_id = p->func_id; + + data->rules[rule_idx].cmd_general_data = + ETH_FILTER_RULES_CMD_RX_CMD; + + bnx2x_rx_mode_set_cmd_state_e2(bp, p->rx_accept_flags, + &(data->rules[rule_idx++]), false); + } + + + /* + * If FCoE Queue configuration has been requested configure the Rx and + * internal switching modes for this queue in separate rules. + * + * FCoE queue shell never be set to ACCEPT_ALL packets of any sort: + * MCAST_ALL, UCAST_ALL, BCAST_ALL and UNMATCHED. + */ + if (test_bit(BNX2X_RX_MODE_FCOE_ETH, &p->rx_mode_flags)) { + /* Tx (internal switching) */ + if (test_bit(RAMROD_TX, &p->ramrod_flags)) { + data->rules[rule_idx].client_id = bnx2x_fcoe(bp, cl_id); + data->rules[rule_idx].func_id = p->func_id; + + data->rules[rule_idx].cmd_general_data = + ETH_FILTER_RULES_CMD_TX_CMD; + + bnx2x_rx_mode_set_cmd_state_e2(bp, p->tx_accept_flags, + &(data->rules[rule_idx++]), + true); + } + + /* Rx */ + if (test_bit(RAMROD_RX, &p->ramrod_flags)) { + data->rules[rule_idx].client_id = bnx2x_fcoe(bp, cl_id); + data->rules[rule_idx].func_id = p->func_id; + + data->rules[rule_idx].cmd_general_data = + ETH_FILTER_RULES_CMD_RX_CMD; + + bnx2x_rx_mode_set_cmd_state_e2(bp, p->rx_accept_flags, + &(data->rules[rule_idx++]), + true); + } + } + + /* + * Set the ramrod header (most importantly - number of rules to + * configure). + */ + bnx2x_rx_mode_set_rdata_hdr_e2(p->cid, &data->header, rule_idx); + + DP(BNX2X_MSG_SP, "About to configure %d rules, rx_accept_flags 0x%lx, " + "tx_accept_flags 0x%lx\n", + data->header.rule_cnt, p->rx_accept_flags, + p->tx_accept_flags); + + /* Commit writes towards the memory before sending a ramrod */ + mb(); + + /* Send a ramrod */ + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_FILTER_RULES, p->cid, + U64_HI(p->rdata_mapping), + U64_LO(p->rdata_mapping), + ETH_CONNECTION_TYPE); + if (rc) + return rc; + + /* Ramrod completion is pending */ + return 1; +} + +static int bnx2x_wait_rx_mode_comp_e2(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p) +{ + return bnx2x_state_wait(bp, p->state, p->pstate); +} + +static int bnx2x_empty_rx_mode_wait(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p) +{ + /* Do nothing */ + return 0; +} + +int bnx2x_config_rx_mode(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p) +{ + int rc; + + /* Configure the new classification in the chip */ + rc = p->rx_mode_obj->config_rx_mode(bp, p); + if (rc < 0) + return rc; + + /* Wait for a ramrod completion if was requested */ + if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) { + rc = p->rx_mode_obj->wait_comp(bp, p); + if (rc) + return rc; + } + + return rc; +} + +void bnx2x_init_rx_mode_obj(struct bnx2x *bp, + struct bnx2x_rx_mode_obj *o) +{ + if (CHIP_IS_E1x(bp)) { + o->wait_comp = bnx2x_empty_rx_mode_wait; + o->config_rx_mode = bnx2x_set_rx_mode_e1x; + } else { + o->wait_comp = bnx2x_wait_rx_mode_comp_e2; + o->config_rx_mode = bnx2x_set_rx_mode_e2; + } +} + +/********************* Multicast verbs: SET, CLEAR ****************************/ +static inline u8 bnx2x_mcast_bin_from_mac(u8 *mac) +{ + return (crc32c_le(0, mac, ETH_ALEN) >> 24) & 0xff; +} + +struct bnx2x_mcast_mac_elem { + struct list_head link; + u8 mac[ETH_ALEN]; + u8 pad[2]; /* For a natural alignment of the following buffer */ +}; + +struct bnx2x_pending_mcast_cmd { + struct list_head link; + int type; /* BNX2X_MCAST_CMD_X */ + union { + struct list_head macs_head; + u32 macs_num; /* Needed for DEL command */ + int next_bin; /* Needed for RESTORE flow with aprox match */ + } data; + + bool done; /* set to true, when the command has been handled, + * practically used in 57712 handling only, where one pending + * command may be handled in a few operations. As long as for + * other chips every operation handling is completed in a + * single ramrod, there is no need to utilize this field. + */ +}; + +static int bnx2x_mcast_wait(struct bnx2x *bp, + struct bnx2x_mcast_obj *o) +{ + if (bnx2x_state_wait(bp, o->sched_state, o->raw.pstate) || + o->raw.wait_comp(bp, &o->raw)) + return -EBUSY; + + return 0; +} + +static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + int total_sz; + struct bnx2x_pending_mcast_cmd *new_cmd; + struct bnx2x_mcast_mac_elem *cur_mac = NULL; + struct bnx2x_mcast_list_elem *pos; + int macs_list_len = ((cmd == BNX2X_MCAST_CMD_ADD) ? + p->mcast_list_len : 0); + + /* If the command is empty ("handle pending commands only"), break */ + if (!p->mcast_list_len) + return 0; + + total_sz = sizeof(*new_cmd) + + macs_list_len * sizeof(struct bnx2x_mcast_mac_elem); + + /* Add mcast is called under spin_lock, thus calling with GFP_ATOMIC */ + new_cmd = kzalloc(total_sz, GFP_ATOMIC); + + if (!new_cmd) + return -ENOMEM; + + DP(BNX2X_MSG_SP, "About to enqueue a new %d command. " + "macs_list_len=%d\n", cmd, macs_list_len); + + INIT_LIST_HEAD(&new_cmd->data.macs_head); + + new_cmd->type = cmd; + new_cmd->done = false; + + switch (cmd) { + case BNX2X_MCAST_CMD_ADD: + cur_mac = (struct bnx2x_mcast_mac_elem *) + ((u8 *)new_cmd + sizeof(*new_cmd)); + + /* Push the MACs of the current command into the pendig command + * MACs list: FIFO + */ + list_for_each_entry(pos, &p->mcast_list, link) { + memcpy(cur_mac->mac, pos->mac, ETH_ALEN); + list_add_tail(&cur_mac->link, &new_cmd->data.macs_head); + cur_mac++; + } + + break; + + case BNX2X_MCAST_CMD_DEL: + new_cmd->data.macs_num = p->mcast_list_len; + break; + + case BNX2X_MCAST_CMD_RESTORE: + new_cmd->data.next_bin = 0; + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd); + return -EINVAL; + } + + /* Push the new pending command to the tail of the pending list: FIFO */ + list_add_tail(&new_cmd->link, &o->pending_cmds_head); + + o->set_sched(o); + + return 1; +} + +/** + * bnx2x_mcast_get_next_bin - get the next set bin (index) + * + * @o: + * @last: index to start looking from (including) + * + * returns the next found (set) bin or a negative value if none is found. + */ +static inline int bnx2x_mcast_get_next_bin(struct bnx2x_mcast_obj *o, int last) +{ + int i, j, inner_start = last % BIT_VEC64_ELEM_SZ; + + for (i = last / BIT_VEC64_ELEM_SZ; i < BNX2X_MCAST_VEC_SZ; i++) { + if (o->registry.aprox_match.vec[i]) + for (j = inner_start; j < BIT_VEC64_ELEM_SZ; j++) { + int cur_bit = j + BIT_VEC64_ELEM_SZ * i; + if (BIT_VEC64_TEST_BIT(o->registry.aprox_match. + vec, cur_bit)) { + return cur_bit; + } + } + inner_start = 0; + } + + /* None found */ + return -1; +} + +/** + * bnx2x_mcast_clear_first_bin - find the first set bin and clear it + * + * @o: + * + * returns the index of the found bin or -1 if none is found + */ +static inline int bnx2x_mcast_clear_first_bin(struct bnx2x_mcast_obj *o) +{ + int cur_bit = bnx2x_mcast_get_next_bin(o, 0); + + if (cur_bit >= 0) + BIT_VEC64_CLEAR_BIT(o->registry.aprox_match.vec, cur_bit); + + return cur_bit; +} + +static inline u8 bnx2x_mcast_get_rx_tx_flag(struct bnx2x_mcast_obj *o) +{ + struct bnx2x_raw_obj *raw = &o->raw; + u8 rx_tx_flag = 0; + + if ((raw->obj_type == BNX2X_OBJ_TYPE_TX) || + (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) + rx_tx_flag |= ETH_MULTICAST_RULES_CMD_TX_CMD; + + if ((raw->obj_type == BNX2X_OBJ_TYPE_RX) || + (raw->obj_type == BNX2X_OBJ_TYPE_RX_TX)) + rx_tx_flag |= ETH_MULTICAST_RULES_CMD_RX_CMD; + + return rx_tx_flag; +} + +static void bnx2x_mcast_set_one_rule_e2(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, int idx, + union bnx2x_mcast_config_data *cfg_data, + int cmd) +{ + struct bnx2x_raw_obj *r = &o->raw; + struct eth_multicast_rules_ramrod_data *data = + (struct eth_multicast_rules_ramrod_data *)(r->rdata); + u8 func_id = r->func_id; + u8 rx_tx_add_flag = bnx2x_mcast_get_rx_tx_flag(o); + int bin; + + if ((cmd == BNX2X_MCAST_CMD_ADD) || (cmd == BNX2X_MCAST_CMD_RESTORE)) + rx_tx_add_flag |= ETH_MULTICAST_RULES_CMD_IS_ADD; + + data->rules[idx].cmd_general_data |= rx_tx_add_flag; + + /* Get a bin and update a bins' vector */ + switch (cmd) { + case BNX2X_MCAST_CMD_ADD: + bin = bnx2x_mcast_bin_from_mac(cfg_data->mac); + BIT_VEC64_SET_BIT(o->registry.aprox_match.vec, bin); + break; + + case BNX2X_MCAST_CMD_DEL: + /* If there were no more bins to clear + * (bnx2x_mcast_clear_first_bin() returns -1) then we would + * clear any (0xff) bin. + * See bnx2x_mcast_validate_e2() for explanation when it may + * happen. + */ + bin = bnx2x_mcast_clear_first_bin(o); + break; + + case BNX2X_MCAST_CMD_RESTORE: + bin = cfg_data->bin; + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd); + return; + } + + DP(BNX2X_MSG_SP, "%s bin %d\n", + ((rx_tx_add_flag & ETH_MULTICAST_RULES_CMD_IS_ADD) ? + "Setting" : "Clearing"), bin); + + data->rules[idx].bin_id = (u8)bin; + data->rules[idx].func_id = func_id; + data->rules[idx].engine_id = o->engine_id; +} + +/** + * bnx2x_mcast_handle_restore_cmd_e2 - restore configuration from the registry + * + * @bp: device handle + * @o: + * @start_bin: index in the registry to start from (including) + * @rdata_idx: index in the ramrod data to start from + * + * returns last handled bin index or -1 if all bins have been handled + */ +static inline int bnx2x_mcast_handle_restore_cmd_e2( + struct bnx2x *bp, struct bnx2x_mcast_obj *o , int start_bin, + int *rdata_idx) +{ + int cur_bin, cnt = *rdata_idx; + union bnx2x_mcast_config_data cfg_data = {0}; + + /* go through the registry and configure the bins from it */ + for (cur_bin = bnx2x_mcast_get_next_bin(o, start_bin); cur_bin >= 0; + cur_bin = bnx2x_mcast_get_next_bin(o, cur_bin + 1)) { + + cfg_data.bin = (u8)cur_bin; + o->set_one_rule(bp, o, cnt, &cfg_data, + BNX2X_MCAST_CMD_RESTORE); + + cnt++; + + DP(BNX2X_MSG_SP, "About to configure a bin %d\n", cur_bin); + + /* Break if we reached the maximum number + * of rules. + */ + if (cnt >= o->max_cmd_len) + break; + } + + *rdata_idx = cnt; + + return cur_bin; +} + +static inline void bnx2x_mcast_hdl_pending_add_e2(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, struct bnx2x_pending_mcast_cmd *cmd_pos, + int *line_idx) +{ + struct bnx2x_mcast_mac_elem *pmac_pos, *pmac_pos_n; + int cnt = *line_idx; + union bnx2x_mcast_config_data cfg_data = {0}; + + list_for_each_entry_safe(pmac_pos, pmac_pos_n, &cmd_pos->data.macs_head, + link) { + + cfg_data.mac = &pmac_pos->mac[0]; + o->set_one_rule(bp, o, cnt, &cfg_data, cmd_pos->type); + + cnt++; + + DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT + " mcast MAC\n", + BNX2X_MAC_PRN_LIST(pmac_pos->mac)); + + list_del(&pmac_pos->link); + + /* Break if we reached the maximum number + * of rules. + */ + if (cnt >= o->max_cmd_len) + break; + } + + *line_idx = cnt; + + /* if no more MACs to configure - we are done */ + if (list_empty(&cmd_pos->data.macs_head)) + cmd_pos->done = true; +} + +static inline void bnx2x_mcast_hdl_pending_del_e2(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, struct bnx2x_pending_mcast_cmd *cmd_pos, + int *line_idx) +{ + int cnt = *line_idx; + + while (cmd_pos->data.macs_num) { + o->set_one_rule(bp, o, cnt, NULL, cmd_pos->type); + + cnt++; + + cmd_pos->data.macs_num--; + + DP(BNX2X_MSG_SP, "Deleting MAC. %d left,cnt is %d\n", + cmd_pos->data.macs_num, cnt); + + /* Break if we reached the maximum + * number of rules. + */ + if (cnt >= o->max_cmd_len) + break; + } + + *line_idx = cnt; + + /* If we cleared all bins - we are done */ + if (!cmd_pos->data.macs_num) + cmd_pos->done = true; +} + +static inline void bnx2x_mcast_hdl_pending_restore_e2(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, struct bnx2x_pending_mcast_cmd *cmd_pos, + int *line_idx) +{ + cmd_pos->data.next_bin = o->hdl_restore(bp, o, cmd_pos->data.next_bin, + line_idx); + + if (cmd_pos->data.next_bin < 0) + /* If o->set_restore returned -1 we are done */ + cmd_pos->done = true; + else + /* Start from the next bin next time */ + cmd_pos->data.next_bin++; +} + +static inline int bnx2x_mcast_handle_pending_cmds_e2(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p) +{ + struct bnx2x_pending_mcast_cmd *cmd_pos, *cmd_pos_n; + int cnt = 0; + struct bnx2x_mcast_obj *o = p->mcast_obj; + + list_for_each_entry_safe(cmd_pos, cmd_pos_n, &o->pending_cmds_head, + link) { + switch (cmd_pos->type) { + case BNX2X_MCAST_CMD_ADD: + bnx2x_mcast_hdl_pending_add_e2(bp, o, cmd_pos, &cnt); + break; + + case BNX2X_MCAST_CMD_DEL: + bnx2x_mcast_hdl_pending_del_e2(bp, o, cmd_pos, &cnt); + break; + + case BNX2X_MCAST_CMD_RESTORE: + bnx2x_mcast_hdl_pending_restore_e2(bp, o, cmd_pos, + &cnt); + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd_pos->type); + return -EINVAL; + } + + /* If the command has been completed - remove it from the list + * and free the memory + */ + if (cmd_pos->done) { + list_del(&cmd_pos->link); + kfree(cmd_pos); + } + + /* Break if we reached the maximum number of rules */ + if (cnt >= o->max_cmd_len) + break; + } + + return cnt; +} + +static inline void bnx2x_mcast_hdl_add(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, struct bnx2x_mcast_ramrod_params *p, + int *line_idx) +{ + struct bnx2x_mcast_list_elem *mlist_pos; + union bnx2x_mcast_config_data cfg_data = {0}; + int cnt = *line_idx; + + list_for_each_entry(mlist_pos, &p->mcast_list, link) { + cfg_data.mac = mlist_pos->mac; + o->set_one_rule(bp, o, cnt, &cfg_data, BNX2X_MCAST_CMD_ADD); + + cnt++; + + DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT + " mcast MAC\n", + BNX2X_MAC_PRN_LIST(mlist_pos->mac)); + } + + *line_idx = cnt; +} + +static inline void bnx2x_mcast_hdl_del(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, struct bnx2x_mcast_ramrod_params *p, + int *line_idx) +{ + int cnt = *line_idx, i; + + for (i = 0; i < p->mcast_list_len; i++) { + o->set_one_rule(bp, o, cnt, NULL, BNX2X_MCAST_CMD_DEL); + + cnt++; + + DP(BNX2X_MSG_SP, "Deleting MAC. %d left\n", + p->mcast_list_len - i - 1); + } + + *line_idx = cnt; +} + +/** + * bnx2x_mcast_handle_current_cmd - + * + * @bp: device handle + * @p: + * @cmd: + * @start_cnt: first line in the ramrod data that may be used + * + * This function is called iff there is enough place for the current command in + * the ramrod data. + * Returns number of lines filled in the ramrod data in total. + */ +static inline int bnx2x_mcast_handle_current_cmd(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, int cmd, + int start_cnt) +{ + struct bnx2x_mcast_obj *o = p->mcast_obj; + int cnt = start_cnt; + + DP(BNX2X_MSG_SP, "p->mcast_list_len=%d\n", p->mcast_list_len); + + switch (cmd) { + case BNX2X_MCAST_CMD_ADD: + bnx2x_mcast_hdl_add(bp, o, p, &cnt); + break; + + case BNX2X_MCAST_CMD_DEL: + bnx2x_mcast_hdl_del(bp, o, p, &cnt); + break; + + case BNX2X_MCAST_CMD_RESTORE: + o->hdl_restore(bp, o, 0, &cnt); + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd); + return -EINVAL; + } + + /* The current command has been handled */ + p->mcast_list_len = 0; + + return cnt; +} + +static int bnx2x_mcast_validate_e2(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + struct bnx2x_mcast_obj *o = p->mcast_obj; + int reg_sz = o->get_registry_size(o); + + switch (cmd) { + /* DEL command deletes all currently configured MACs */ + case BNX2X_MCAST_CMD_DEL: + o->set_registry_size(o, 0); + /* Don't break */ + + /* RESTORE command will restore the entire multicast configuration */ + case BNX2X_MCAST_CMD_RESTORE: + /* Here we set the approximate amount of work to do, which in + * fact may be only less as some MACs in postponed ADD + * command(s) scheduled before this command may fall into + * the same bin and the actual number of bins set in the + * registry would be less than we estimated here. See + * bnx2x_mcast_set_one_rule_e2() for further details. + */ + p->mcast_list_len = reg_sz; + break; + + case BNX2X_MCAST_CMD_ADD: + case BNX2X_MCAST_CMD_CONT: + /* Here we assume that all new MACs will fall into new bins. + * However we will correct the real registry size after we + * handle all pending commands. + */ + o->set_registry_size(o, reg_sz + p->mcast_list_len); + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd); + return -EINVAL; + + } + + /* Increase the total number of MACs pending to be configured */ + o->total_pending_num += p->mcast_list_len; + + return 0; +} + +static void bnx2x_mcast_revert_e2(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int old_num_bins) +{ + struct bnx2x_mcast_obj *o = p->mcast_obj; + + o->set_registry_size(o, old_num_bins); + o->total_pending_num -= p->mcast_list_len; +} + +/** + * bnx2x_mcast_set_rdata_hdr_e2 - sets a header values + * + * @bp: device handle + * @p: + * @len: number of rules to handle + */ +static inline void bnx2x_mcast_set_rdata_hdr_e2(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + u8 len) +{ + struct bnx2x_raw_obj *r = &p->mcast_obj->raw; + struct eth_multicast_rules_ramrod_data *data = + (struct eth_multicast_rules_ramrod_data *)(r->rdata); + + data->header.echo = ((r->cid & BNX2X_SWCID_MASK) | + (BNX2X_FILTER_MCAST_PENDING << BNX2X_SWCID_SHIFT)); + data->header.rule_cnt = len; +} + +/** + * bnx2x_mcast_refresh_registry_e2 - recalculate the actual number of set bins + * + * @bp: device handle + * @o: + * + * Recalculate the actual number of set bins in the registry using Brian + * Kernighan's algorithm: it's execution complexity is as a number of set bins. + * + * returns 0 for the compliance with bnx2x_mcast_refresh_registry_e1(). + */ +static inline int bnx2x_mcast_refresh_registry_e2(struct bnx2x *bp, + struct bnx2x_mcast_obj *o) +{ + int i, cnt = 0; + u64 elem; + + for (i = 0; i < BNX2X_MCAST_VEC_SZ; i++) { + elem = o->registry.aprox_match.vec[i]; + for (; elem; cnt++) + elem &= elem - 1; + } + + o->set_registry_size(o, cnt); + + return 0; +} + +static int bnx2x_mcast_setup_e2(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + struct bnx2x_raw_obj *raw = &p->mcast_obj->raw; + struct bnx2x_mcast_obj *o = p->mcast_obj; + struct eth_multicast_rules_ramrod_data *data = + (struct eth_multicast_rules_ramrod_data *)(raw->rdata); + int cnt = 0, rc; + + /* Reset the ramrod data buffer */ + memset(data, 0, sizeof(*data)); + + cnt = bnx2x_mcast_handle_pending_cmds_e2(bp, p); + + /* If there are no more pending commands - clear SCHEDULED state */ + if (list_empty(&o->pending_cmds_head)) + o->clear_sched(o); + + /* The below may be true iff there was enough room in ramrod + * data for all pending commands and for the current + * command. Otherwise the current command would have been added + * to the pending commands and p->mcast_list_len would have been + * zeroed. + */ + if (p->mcast_list_len > 0) + cnt = bnx2x_mcast_handle_current_cmd(bp, p, cmd, cnt); + + /* We've pulled out some MACs - update the total number of + * outstanding. + */ + o->total_pending_num -= cnt; + + /* send a ramrod */ + WARN_ON(o->total_pending_num < 0); + WARN_ON(cnt > o->max_cmd_len); + + bnx2x_mcast_set_rdata_hdr_e2(bp, p, (u8)cnt); + + /* Update a registry size if there are no more pending operations. + * + * We don't want to change the value of the registry size if there are + * pending operations because we want it to always be equal to the + * exact or the approximate number (see bnx2x_mcast_validate_e2()) of + * set bins after the last requested operation in order to properly + * evaluate the size of the next DEL/RESTORE operation. + * + * Note that we update the registry itself during command(s) handling + * - see bnx2x_mcast_set_one_rule_e2(). That's because for 57712 we + * aggregate multiple commands (ADD/DEL/RESTORE) into one ramrod but + * with a limited amount of update commands (per MAC/bin) and we don't + * know in this scope what the actual state of bins configuration is + * going to be after this ramrod. + */ + if (!o->total_pending_num) + bnx2x_mcast_refresh_registry_e2(bp, o); + + /* Commit writes towards the memory before sending a ramrod */ + mb(); + + /* If CLEAR_ONLY was requested - don't send a ramrod and clear + * RAMROD_PENDING status immediately. + */ + if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { + raw->clear_pending(raw); + return 0; + } else { + /* Send a ramrod */ + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_MULTICAST_RULES, + raw->cid, U64_HI(raw->rdata_mapping), + U64_LO(raw->rdata_mapping), + ETH_CONNECTION_TYPE); + if (rc) + return rc; + + /* Ramrod completion is pending */ + return 1; + } +} + +static int bnx2x_mcast_validate_e1h(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + /* Mark, that there is a work to do */ + if ((cmd == BNX2X_MCAST_CMD_DEL) || (cmd == BNX2X_MCAST_CMD_RESTORE)) + p->mcast_list_len = 1; + + return 0; +} + +static void bnx2x_mcast_revert_e1h(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int old_num_bins) +{ + /* Do nothing */ +} + +#define BNX2X_57711_SET_MC_FILTER(filter, bit) \ +do { \ + (filter)[(bit) >> 5] |= (1 << ((bit) & 0x1f)); \ +} while (0) + +static inline void bnx2x_mcast_hdl_add_e1h(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, + struct bnx2x_mcast_ramrod_params *p, + u32 *mc_filter) +{ + struct bnx2x_mcast_list_elem *mlist_pos; + int bit; + + list_for_each_entry(mlist_pos, &p->mcast_list, link) { + bit = bnx2x_mcast_bin_from_mac(mlist_pos->mac); + BNX2X_57711_SET_MC_FILTER(mc_filter, bit); + + DP(BNX2X_MSG_SP, "About to configure " + BNX2X_MAC_FMT" mcast MAC, bin %d\n", + BNX2X_MAC_PRN_LIST(mlist_pos->mac), bit); + + /* bookkeeping... */ + BIT_VEC64_SET_BIT(o->registry.aprox_match.vec, + bit); + } +} + +static inline void bnx2x_mcast_hdl_restore_e1h(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, struct bnx2x_mcast_ramrod_params *p, + u32 *mc_filter) +{ + int bit; + + for (bit = bnx2x_mcast_get_next_bin(o, 0); + bit >= 0; + bit = bnx2x_mcast_get_next_bin(o, bit + 1)) { + BNX2X_57711_SET_MC_FILTER(mc_filter, bit); + DP(BNX2X_MSG_SP, "About to set bin %d\n", bit); + } +} + +/* On 57711 we write the multicast MACs' aproximate match + * table by directly into the TSTORM's internal RAM. So we don't + * really need to handle any tricks to make it work. + */ +static int bnx2x_mcast_setup_e1h(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + int i; + struct bnx2x_mcast_obj *o = p->mcast_obj; + struct bnx2x_raw_obj *r = &o->raw; + + /* If CLEAR_ONLY has been requested - clear the registry + * and clear a pending bit. + */ + if (!test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { + u32 mc_filter[MC_HASH_SIZE] = {0}; + + /* Set the multicast filter bits before writing it into + * the internal memory. + */ + switch (cmd) { + case BNX2X_MCAST_CMD_ADD: + bnx2x_mcast_hdl_add_e1h(bp, o, p, mc_filter); + break; + + case BNX2X_MCAST_CMD_DEL: + DP(BNX2X_MSG_SP, "Invalidating multicast " + "MACs configuration\n"); + + /* clear the registry */ + memset(o->registry.aprox_match.vec, 0, + sizeof(o->registry.aprox_match.vec)); + break; + + case BNX2X_MCAST_CMD_RESTORE: + bnx2x_mcast_hdl_restore_e1h(bp, o, p, mc_filter); + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd); + return -EINVAL; + } + + /* Set the mcast filter in the internal memory */ + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), mc_filter[i]); + } else + /* clear the registry */ + memset(o->registry.aprox_match.vec, 0, + sizeof(o->registry.aprox_match.vec)); + + /* We are done */ + r->clear_pending(r); + + return 0; +} + +static int bnx2x_mcast_validate_e1(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + struct bnx2x_mcast_obj *o = p->mcast_obj; + int reg_sz = o->get_registry_size(o); + + switch (cmd) { + /* DEL command deletes all currently configured MACs */ + case BNX2X_MCAST_CMD_DEL: + o->set_registry_size(o, 0); + /* Don't break */ + + /* RESTORE command will restore the entire multicast configuration */ + case BNX2X_MCAST_CMD_RESTORE: + p->mcast_list_len = reg_sz; + DP(BNX2X_MSG_SP, "Command %d, p->mcast_list_len=%d\n", + cmd, p->mcast_list_len); + break; + + case BNX2X_MCAST_CMD_ADD: + case BNX2X_MCAST_CMD_CONT: + /* Multicast MACs on 57710 are configured as unicast MACs and + * there is only a limited number of CAM entries for that + * matter. + */ + if (p->mcast_list_len > o->max_cmd_len) { + BNX2X_ERR("Can't configure more than %d multicast MACs" + "on 57710\n", o->max_cmd_len); + return -EINVAL; + } + /* Every configured MAC should be cleared if DEL command is + * called. Only the last ADD command is relevant as long as + * every ADD commands overrides the previous configuration. + */ + DP(BNX2X_MSG_SP, "p->mcast_list_len=%d\n", p->mcast_list_len); + if (p->mcast_list_len > 0) + o->set_registry_size(o, p->mcast_list_len); + + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd); + return -EINVAL; + + } + + /* We want to ensure that commands are executed one by one for 57710. + * Therefore each none-empty command will consume o->max_cmd_len. + */ + if (p->mcast_list_len) + o->total_pending_num += o->max_cmd_len; + + return 0; +} + +static void bnx2x_mcast_revert_e1(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int old_num_macs) +{ + struct bnx2x_mcast_obj *o = p->mcast_obj; + + o->set_registry_size(o, old_num_macs); + + /* If current command hasn't been handled yet and we are + * here means that it's meant to be dropped and we have to + * update the number of outstandling MACs accordingly. + */ + if (p->mcast_list_len) + o->total_pending_num -= o->max_cmd_len; +} + +static void bnx2x_mcast_set_one_rule_e1(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, int idx, + union bnx2x_mcast_config_data *cfg_data, + int cmd) +{ + struct bnx2x_raw_obj *r = &o->raw; + struct mac_configuration_cmd *data = + (struct mac_configuration_cmd *)(r->rdata); + + /* copy mac */ + if ((cmd == BNX2X_MCAST_CMD_ADD) || (cmd == BNX2X_MCAST_CMD_RESTORE)) { + bnx2x_set_fw_mac_addr(&data->config_table[idx].msb_mac_addr, + &data->config_table[idx].middle_mac_addr, + &data->config_table[idx].lsb_mac_addr, + cfg_data->mac); + + data->config_table[idx].vlan_id = 0; + data->config_table[idx].pf_id = r->func_id; + data->config_table[idx].clients_bit_vector = + cpu_to_le32(1 << r->cl_id); + + SET_FLAG(data->config_table[idx].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + } +} + +/** + * bnx2x_mcast_set_rdata_hdr_e1 - set header values in mac_configuration_cmd + * + * @bp: device handle + * @p: + * @len: number of rules to handle + */ +static inline void bnx2x_mcast_set_rdata_hdr_e1(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + u8 len) +{ + struct bnx2x_raw_obj *r = &p->mcast_obj->raw; + struct mac_configuration_cmd *data = + (struct mac_configuration_cmd *)(r->rdata); + + u8 offset = (CHIP_REV_IS_SLOW(bp) ? + BNX2X_MAX_EMUL_MULTI*(1 + r->func_id) : + BNX2X_MAX_MULTICAST*(1 + r->func_id)); + + data->hdr.offset = offset; + data->hdr.client_id = 0xff; + data->hdr.echo = ((r->cid & BNX2X_SWCID_MASK) | + (BNX2X_FILTER_MCAST_PENDING << BNX2X_SWCID_SHIFT)); + data->hdr.length = len; +} + +/** + * bnx2x_mcast_handle_restore_cmd_e1 - restore command for 57710 + * + * @bp: device handle + * @o: + * @start_idx: index in the registry to start from + * @rdata_idx: index in the ramrod data to start from + * + * restore command for 57710 is like all other commands - always a stand alone + * command - start_idx and rdata_idx will always be 0. This function will always + * succeed. + * returns -1 to comply with 57712 variant. + */ +static inline int bnx2x_mcast_handle_restore_cmd_e1( + struct bnx2x *bp, struct bnx2x_mcast_obj *o , int start_idx, + int *rdata_idx) +{ + struct bnx2x_mcast_mac_elem *elem; + int i = 0; + union bnx2x_mcast_config_data cfg_data = {0}; + + /* go through the registry and configure the MACs from it. */ + list_for_each_entry(elem, &o->registry.exact_match.macs, link) { + cfg_data.mac = &elem->mac[0]; + o->set_one_rule(bp, o, i, &cfg_data, BNX2X_MCAST_CMD_RESTORE); + + i++; + + DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT + " mcast MAC\n", + BNX2X_MAC_PRN_LIST(cfg_data.mac)); + } + + *rdata_idx = i; + + return -1; +} + + +static inline int bnx2x_mcast_handle_pending_cmds_e1( + struct bnx2x *bp, struct bnx2x_mcast_ramrod_params *p) +{ + struct bnx2x_pending_mcast_cmd *cmd_pos; + struct bnx2x_mcast_mac_elem *pmac_pos; + struct bnx2x_mcast_obj *o = p->mcast_obj; + union bnx2x_mcast_config_data cfg_data = {0}; + int cnt = 0; + + + /* If nothing to be done - return */ + if (list_empty(&o->pending_cmds_head)) + return 0; + + /* Handle the first command */ + cmd_pos = list_first_entry(&o->pending_cmds_head, + struct bnx2x_pending_mcast_cmd, link); + + switch (cmd_pos->type) { + case BNX2X_MCAST_CMD_ADD: + list_for_each_entry(pmac_pos, &cmd_pos->data.macs_head, link) { + cfg_data.mac = &pmac_pos->mac[0]; + o->set_one_rule(bp, o, cnt, &cfg_data, cmd_pos->type); + + cnt++; + + DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT + " mcast MAC\n", + BNX2X_MAC_PRN_LIST(pmac_pos->mac)); + } + break; + + case BNX2X_MCAST_CMD_DEL: + cnt = cmd_pos->data.macs_num; + DP(BNX2X_MSG_SP, "About to delete %d multicast MACs\n", cnt); + break; + + case BNX2X_MCAST_CMD_RESTORE: + o->hdl_restore(bp, o, 0, &cnt); + break; + + default: + BNX2X_ERR("Unknown command: %d\n", cmd_pos->type); + return -EINVAL; + } + + list_del(&cmd_pos->link); + kfree(cmd_pos); + + return cnt; +} + +/** + * bnx2x_get_fw_mac_addr - revert the bnx2x_set_fw_mac_addr(). + * + * @fw_hi: + * @fw_mid: + * @fw_lo: + * @mac: + */ +static inline void bnx2x_get_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid, + __le16 *fw_lo, u8 *mac) +{ + mac[1] = ((u8 *)fw_hi)[0]; + mac[0] = ((u8 *)fw_hi)[1]; + mac[3] = ((u8 *)fw_mid)[0]; + mac[2] = ((u8 *)fw_mid)[1]; + mac[5] = ((u8 *)fw_lo)[0]; + mac[4] = ((u8 *)fw_lo)[1]; +} + +/** + * bnx2x_mcast_refresh_registry_e1 - + * + * @bp: device handle + * @cnt: + * + * Check the ramrod data first entry flag to see if it's a DELETE or ADD command + * and update the registry correspondingly: if ADD - allocate a memory and add + * the entries to the registry (list), if DELETE - clear the registry and free + * the memory. + */ +static inline int bnx2x_mcast_refresh_registry_e1(struct bnx2x *bp, + struct bnx2x_mcast_obj *o) +{ + struct bnx2x_raw_obj *raw = &o->raw; + struct bnx2x_mcast_mac_elem *elem; + struct mac_configuration_cmd *data = + (struct mac_configuration_cmd *)(raw->rdata); + + /* If first entry contains a SET bit - the command was ADD, + * otherwise - DEL_ALL + */ + if (GET_FLAG(data->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE)) { + int i, len = data->hdr.length; + + /* Break if it was a RESTORE command */ + if (!list_empty(&o->registry.exact_match.macs)) + return 0; + + elem = kzalloc(sizeof(*elem)*len, GFP_ATOMIC); + if (!elem) { + BNX2X_ERR("Failed to allocate registry memory\n"); + return -ENOMEM; + } + + for (i = 0; i < len; i++, elem++) { + bnx2x_get_fw_mac_addr( + &data->config_table[i].msb_mac_addr, + &data->config_table[i].middle_mac_addr, + &data->config_table[i].lsb_mac_addr, + elem->mac); + DP(BNX2X_MSG_SP, "Adding registry entry for [" + BNX2X_MAC_FMT"]\n", + BNX2X_MAC_PRN_LIST(elem->mac)); + list_add_tail(&elem->link, + &o->registry.exact_match.macs); + } + } else { + elem = list_first_entry(&o->registry.exact_match.macs, + struct bnx2x_mcast_mac_elem, link); + DP(BNX2X_MSG_SP, "Deleting a registry\n"); + kfree(elem); + INIT_LIST_HEAD(&o->registry.exact_match.macs); + } + + return 0; +} + +static int bnx2x_mcast_setup_e1(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + struct bnx2x_mcast_obj *o = p->mcast_obj; + struct bnx2x_raw_obj *raw = &o->raw; + struct mac_configuration_cmd *data = + (struct mac_configuration_cmd *)(raw->rdata); + int cnt = 0, i, rc; + + /* Reset the ramrod data buffer */ + memset(data, 0, sizeof(*data)); + + /* First set all entries as invalid */ + for (i = 0; i < o->max_cmd_len ; i++) + SET_FLAG(data->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + /* Handle pending commands first */ + cnt = bnx2x_mcast_handle_pending_cmds_e1(bp, p); + + /* If there are no more pending commands - clear SCHEDULED state */ + if (list_empty(&o->pending_cmds_head)) + o->clear_sched(o); + + /* The below may be true iff there were no pending commands */ + if (!cnt) + cnt = bnx2x_mcast_handle_current_cmd(bp, p, cmd, 0); + + /* For 57710 every command has o->max_cmd_len length to ensure that + * commands are done one at a time. + */ + o->total_pending_num -= o->max_cmd_len; + + /* send a ramrod */ + + WARN_ON(cnt > o->max_cmd_len); + + /* Set ramrod header (in particular, a number of entries to update) */ + bnx2x_mcast_set_rdata_hdr_e1(bp, p, (u8)cnt); + + /* update a registry: we need the registry contents to be always up + * to date in order to be able to execute a RESTORE opcode. Here + * we use the fact that for 57710 we sent one command at a time + * hence we may take the registry update out of the command handling + * and do it in a simpler way here. + */ + rc = bnx2x_mcast_refresh_registry_e1(bp, o); + if (rc) + return rc; + + /* Commit writes towards the memory before sending a ramrod */ + mb(); + + /* If CLEAR_ONLY was requested - don't send a ramrod and clear + * RAMROD_PENDING status immediately. + */ + if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { + raw->clear_pending(raw); + return 0; + } else { + /* Send a ramrod */ + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, raw->cid, + U64_HI(raw->rdata_mapping), + U64_LO(raw->rdata_mapping), + ETH_CONNECTION_TYPE); + if (rc) + return rc; + + /* Ramrod completion is pending */ + return 1; + } + +} + +static int bnx2x_mcast_get_registry_size_exact(struct bnx2x_mcast_obj *o) +{ + return o->registry.exact_match.num_macs_set; +} + +static int bnx2x_mcast_get_registry_size_aprox(struct bnx2x_mcast_obj *o) +{ + return o->registry.aprox_match.num_bins_set; +} + +static void bnx2x_mcast_set_registry_size_exact(struct bnx2x_mcast_obj *o, + int n) +{ + o->registry.exact_match.num_macs_set = n; +} + +static void bnx2x_mcast_set_registry_size_aprox(struct bnx2x_mcast_obj *o, + int n) +{ + o->registry.aprox_match.num_bins_set = n; +} + +int bnx2x_config_mcast(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int cmd) +{ + struct bnx2x_mcast_obj *o = p->mcast_obj; + struct bnx2x_raw_obj *r = &o->raw; + int rc = 0, old_reg_size; + + /* This is needed to recover number of currently configured mcast macs + * in case of failure. + */ + old_reg_size = o->get_registry_size(o); + + /* Do some calculations and checks */ + rc = o->validate(bp, p, cmd); + if (rc) + return rc; + + /* Return if there is no work to do */ + if ((!p->mcast_list_len) && (!o->check_sched(o))) + return 0; + + DP(BNX2X_MSG_SP, "o->total_pending_num=%d p->mcast_list_len=%d " + "o->max_cmd_len=%d\n", o->total_pending_num, + p->mcast_list_len, o->max_cmd_len); + + /* Enqueue the current command to the pending list if we can't complete + * it in the current iteration + */ + if (r->check_pending(r) || + ((o->max_cmd_len > 0) && (o->total_pending_num > o->max_cmd_len))) { + rc = o->enqueue_cmd(bp, p->mcast_obj, p, cmd); + if (rc < 0) + goto error_exit1; + + /* As long as the current command is in a command list we + * don't need to handle it separately. + */ + p->mcast_list_len = 0; + } + + if (!r->check_pending(r)) { + + /* Set 'pending' state */ + r->set_pending(r); + + /* Configure the new classification in the chip */ + rc = o->config_mcast(bp, p, cmd); + if (rc < 0) + goto error_exit2; + + /* Wait for a ramrod completion if was requested */ + if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) + rc = o->wait_comp(bp, o); + } + + return rc; + +error_exit2: + r->clear_pending(r); + +error_exit1: + o->revert(bp, p, old_reg_size); + + return rc; +} + +static void bnx2x_mcast_clear_sched(struct bnx2x_mcast_obj *o) +{ + smp_mb__before_clear_bit(); + clear_bit(o->sched_state, o->raw.pstate); + smp_mb__after_clear_bit(); +} + +static void bnx2x_mcast_set_sched(struct bnx2x_mcast_obj *o) +{ + smp_mb__before_clear_bit(); + set_bit(o->sched_state, o->raw.pstate); + smp_mb__after_clear_bit(); +} + +static bool bnx2x_mcast_check_sched(struct bnx2x_mcast_obj *o) +{ + return !!test_bit(o->sched_state, o->raw.pstate); +} + +static bool bnx2x_mcast_check_pending(struct bnx2x_mcast_obj *o) +{ + return o->raw.check_pending(&o->raw) || o->check_sched(o); +} + +void bnx2x_init_mcast_obj(struct bnx2x *bp, + struct bnx2x_mcast_obj *mcast_obj, + u8 mcast_cl_id, u32 mcast_cid, u8 func_id, + u8 engine_id, void *rdata, dma_addr_t rdata_mapping, + int state, unsigned long *pstate, bnx2x_obj_type type) +{ + memset(mcast_obj, 0, sizeof(*mcast_obj)); + + bnx2x_init_raw_obj(&mcast_obj->raw, mcast_cl_id, mcast_cid, func_id, + rdata, rdata_mapping, state, pstate, type); + + mcast_obj->engine_id = engine_id; + + INIT_LIST_HEAD(&mcast_obj->pending_cmds_head); + + mcast_obj->sched_state = BNX2X_FILTER_MCAST_SCHED; + mcast_obj->check_sched = bnx2x_mcast_check_sched; + mcast_obj->set_sched = bnx2x_mcast_set_sched; + mcast_obj->clear_sched = bnx2x_mcast_clear_sched; + + if (CHIP_IS_E1(bp)) { + mcast_obj->config_mcast = bnx2x_mcast_setup_e1; + mcast_obj->enqueue_cmd = bnx2x_mcast_enqueue_cmd; + mcast_obj->hdl_restore = + bnx2x_mcast_handle_restore_cmd_e1; + mcast_obj->check_pending = bnx2x_mcast_check_pending; + + if (CHIP_REV_IS_SLOW(bp)) + mcast_obj->max_cmd_len = BNX2X_MAX_EMUL_MULTI; + else + mcast_obj->max_cmd_len = BNX2X_MAX_MULTICAST; + + mcast_obj->wait_comp = bnx2x_mcast_wait; + mcast_obj->set_one_rule = bnx2x_mcast_set_one_rule_e1; + mcast_obj->validate = bnx2x_mcast_validate_e1; + mcast_obj->revert = bnx2x_mcast_revert_e1; + mcast_obj->get_registry_size = + bnx2x_mcast_get_registry_size_exact; + mcast_obj->set_registry_size = + bnx2x_mcast_set_registry_size_exact; + + /* 57710 is the only chip that uses the exact match for mcast + * at the moment. + */ + INIT_LIST_HEAD(&mcast_obj->registry.exact_match.macs); + + } else if (CHIP_IS_E1H(bp)) { + mcast_obj->config_mcast = bnx2x_mcast_setup_e1h; + mcast_obj->enqueue_cmd = NULL; + mcast_obj->hdl_restore = NULL; + mcast_obj->check_pending = bnx2x_mcast_check_pending; + + /* 57711 doesn't send a ramrod, so it has unlimited credit + * for one command. + */ + mcast_obj->max_cmd_len = -1; + mcast_obj->wait_comp = bnx2x_mcast_wait; + mcast_obj->set_one_rule = NULL; + mcast_obj->validate = bnx2x_mcast_validate_e1h; + mcast_obj->revert = bnx2x_mcast_revert_e1h; + mcast_obj->get_registry_size = + bnx2x_mcast_get_registry_size_aprox; + mcast_obj->set_registry_size = + bnx2x_mcast_set_registry_size_aprox; + } else { + mcast_obj->config_mcast = bnx2x_mcast_setup_e2; + mcast_obj->enqueue_cmd = bnx2x_mcast_enqueue_cmd; + mcast_obj->hdl_restore = + bnx2x_mcast_handle_restore_cmd_e2; + mcast_obj->check_pending = bnx2x_mcast_check_pending; + /* TODO: There should be a proper HSI define for this number!!! + */ + mcast_obj->max_cmd_len = 16; + mcast_obj->wait_comp = bnx2x_mcast_wait; + mcast_obj->set_one_rule = bnx2x_mcast_set_one_rule_e2; + mcast_obj->validate = bnx2x_mcast_validate_e2; + mcast_obj->revert = bnx2x_mcast_revert_e2; + mcast_obj->get_registry_size = + bnx2x_mcast_get_registry_size_aprox; + mcast_obj->set_registry_size = + bnx2x_mcast_set_registry_size_aprox; + } +} + +/*************************** Credit handling **********************************/ + +/** + * atomic_add_ifless - add if the result is less than a given value. + * + * @v: pointer of type atomic_t + * @a: the amount to add to v... + * @u: ...if (v + a) is less than u. + * + * returns true if (v + a) was less than u, and false otherwise. + * + */ +static inline bool __atomic_add_ifless(atomic_t *v, int a, int u) +{ + int c, old; + + c = atomic_read(v); + for (;;) { + if (unlikely(c + a >= u)) + return false; + + old = atomic_cmpxchg((v), c, c + a); + if (likely(old == c)) + break; + c = old; + } + + return true; +} + +/** + * atomic_dec_ifmoe - dec if the result is more or equal than a given value. + * + * @v: pointer of type atomic_t + * @a: the amount to dec from v... + * @u: ...if (v - a) is more or equal than u. + * + * returns true if (v - a) was more or equal than u, and false + * otherwise. + */ +static inline bool __atomic_dec_ifmoe(atomic_t *v, int a, int u) +{ + int c, old; + + c = atomic_read(v); + for (;;) { + if (unlikely(c - a < u)) + return false; + + old = atomic_cmpxchg((v), c, c - a); + if (likely(old == c)) + break; + c = old; + } + + return true; +} + +static bool bnx2x_credit_pool_get(struct bnx2x_credit_pool_obj *o, int cnt) +{ + bool rc; + + smp_mb(); + rc = __atomic_dec_ifmoe(&o->credit, cnt, 0); + smp_mb(); + + return rc; +} + +static bool bnx2x_credit_pool_put(struct bnx2x_credit_pool_obj *o, int cnt) +{ + bool rc; + + smp_mb(); + + /* Don't let to refill if credit + cnt > pool_sz */ + rc = __atomic_add_ifless(&o->credit, cnt, o->pool_sz + 1); + + smp_mb(); + + return rc; +} + +static int bnx2x_credit_pool_check(struct bnx2x_credit_pool_obj *o) +{ + int cur_credit; + + smp_mb(); + cur_credit = atomic_read(&o->credit); + + return cur_credit; +} + +static bool bnx2x_credit_pool_always_true(struct bnx2x_credit_pool_obj *o, + int cnt) +{ + return true; +} + + +static bool bnx2x_credit_pool_get_entry( + struct bnx2x_credit_pool_obj *o, + int *offset) +{ + int idx, vec, i; + + *offset = -1; + + /* Find "internal cam-offset" then add to base for this object... */ + for (vec = 0; vec < BNX2X_POOL_VEC_SIZE; vec++) { + + /* Skip the current vector if there are no free entries in it */ + if (!o->pool_mirror[vec]) + continue; + + /* If we've got here we are going to find a free entry */ + for (idx = vec * BNX2X_POOL_VEC_SIZE, i = 0; + i < BIT_VEC64_ELEM_SZ; idx++, i++) + + if (BIT_VEC64_TEST_BIT(o->pool_mirror, idx)) { + /* Got one!! */ + BIT_VEC64_CLEAR_BIT(o->pool_mirror, idx); + *offset = o->base_pool_offset + idx; + return true; + } + } + + return false; +} + +static bool bnx2x_credit_pool_put_entry( + struct bnx2x_credit_pool_obj *o, + int offset) +{ + if (offset < o->base_pool_offset) + return false; + + offset -= o->base_pool_offset; + + if (offset >= o->pool_sz) + return false; + + /* Return the entry to the pool */ + BIT_VEC64_SET_BIT(o->pool_mirror, offset); + + return true; +} + +static bool bnx2x_credit_pool_put_entry_always_true( + struct bnx2x_credit_pool_obj *o, + int offset) +{ + return true; +} + +static bool bnx2x_credit_pool_get_entry_always_true( + struct bnx2x_credit_pool_obj *o, + int *offset) +{ + *offset = -1; + return true; +} +/** + * bnx2x_init_credit_pool - initialize credit pool internals. + * + * @p: + * @base: Base entry in the CAM to use. + * @credit: pool size. + * + * If base is negative no CAM entries handling will be performed. + * If credit is negative pool operations will always succeed (unlimited pool). + * + */ +static inline void bnx2x_init_credit_pool(struct bnx2x_credit_pool_obj *p, + int base, int credit) +{ + /* Zero the object first */ + memset(p, 0, sizeof(*p)); + + /* Set the table to all 1s */ + memset(&p->pool_mirror, 0xff, sizeof(p->pool_mirror)); + + /* Init a pool as full */ + atomic_set(&p->credit, credit); + + /* The total poll size */ + p->pool_sz = credit; + + p->base_pool_offset = base; + + /* Commit the change */ + smp_mb(); + + p->check = bnx2x_credit_pool_check; + + /* if pool credit is negative - disable the checks */ + if (credit >= 0) { + p->put = bnx2x_credit_pool_put; + p->get = bnx2x_credit_pool_get; + p->put_entry = bnx2x_credit_pool_put_entry; + p->get_entry = bnx2x_credit_pool_get_entry; + } else { + p->put = bnx2x_credit_pool_always_true; + p->get = bnx2x_credit_pool_always_true; + p->put_entry = bnx2x_credit_pool_put_entry_always_true; + p->get_entry = bnx2x_credit_pool_get_entry_always_true; + } + + /* If base is negative - disable entries handling */ + if (base < 0) { + p->put_entry = bnx2x_credit_pool_put_entry_always_true; + p->get_entry = bnx2x_credit_pool_get_entry_always_true; + } +} + +void bnx2x_init_mac_credit_pool(struct bnx2x *bp, + struct bnx2x_credit_pool_obj *p, u8 func_id, + u8 func_num) +{ +/* TODO: this will be defined in consts as well... */ +#define BNX2X_CAM_SIZE_EMUL 5 + + int cam_sz; + + if (CHIP_IS_E1(bp)) { + /* In E1, Multicast is saved in cam... */ + if (!CHIP_REV_IS_SLOW(bp)) + cam_sz = (MAX_MAC_CREDIT_E1 / 2) - BNX2X_MAX_MULTICAST; + else + cam_sz = BNX2X_CAM_SIZE_EMUL - BNX2X_MAX_EMUL_MULTI; + + bnx2x_init_credit_pool(p, func_id * cam_sz, cam_sz); + + } else if (CHIP_IS_E1H(bp)) { + /* CAM credit is equaly divided between all active functions + * on the PORT!. + */ + if ((func_num > 0)) { + if (!CHIP_REV_IS_SLOW(bp)) + cam_sz = (MAX_MAC_CREDIT_E1H / (2*func_num)); + else + cam_sz = BNX2X_CAM_SIZE_EMUL; + bnx2x_init_credit_pool(p, func_id * cam_sz, cam_sz); + } else { + /* this should never happen! Block MAC operations. */ + bnx2x_init_credit_pool(p, 0, 0); + } + + } else { + + /* + * CAM credit is equaly divided between all active functions + * on the PATH. + */ + if ((func_num > 0)) { + if (!CHIP_REV_IS_SLOW(bp)) + cam_sz = (MAX_MAC_CREDIT_E2 / func_num); + else + cam_sz = BNX2X_CAM_SIZE_EMUL; + + /* + * No need for CAM entries handling for 57712 and + * newer. + */ + bnx2x_init_credit_pool(p, -1, cam_sz); + } else { + /* this should never happen! Block MAC operations. */ + bnx2x_init_credit_pool(p, 0, 0); + } + + } +} + +void bnx2x_init_vlan_credit_pool(struct bnx2x *bp, + struct bnx2x_credit_pool_obj *p, + u8 func_id, + u8 func_num) +{ + if (CHIP_IS_E1x(bp)) { + /* + * There is no VLAN credit in HW on 57710 and 57711 only + * MAC / MAC-VLAN can be set + */ + bnx2x_init_credit_pool(p, 0, -1); + } else { + /* + * CAM credit is equaly divided between all active functions + * on the PATH. + */ + if (func_num > 0) { + int credit = MAX_VLAN_CREDIT_E2 / func_num; + bnx2x_init_credit_pool(p, func_id * credit, credit); + } else + /* this should never happen! Block VLAN operations. */ + bnx2x_init_credit_pool(p, 0, 0); + } +} + +/****************** RSS Configuration ******************/ +/** + * bnx2x_debug_print_ind_table - prints the indirection table configuration. + * + * @bp: driver hanlde + * @p: pointer to rss configuration + * + * Prints it when NETIF_MSG_IFUP debug level is configured. + */ +static inline void bnx2x_debug_print_ind_table(struct bnx2x *bp, + struct bnx2x_config_rss_params *p) +{ int i; - if (bp->multi_mode == ETH_RSS_MODE_DISABLED) - return; + DP(BNX2X_MSG_SP, "Setting indirection table to:\n"); + DP(BNX2X_MSG_SP, "0x0000: "); + for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) { + DP_CONT(BNX2X_MSG_SP, "0x%02x ", p->ind_table[i]); + + /* Print 4 bytes in a line */ + if ((i + 1 < T_ETH_INDIRECTION_TABLE_SIZE) && + (((i + 1) & 0x3) == 0)) { + DP_CONT(BNX2X_MSG_SP, "\n"); + DP(BNX2X_MSG_SP, "0x%04x: ", i + 1); + } + } + + DP_CONT(BNX2X_MSG_SP, "\n"); +} + +/** + * bnx2x_setup_rss - configure RSS + * + * @bp: device handle + * @p: rss configuration + * + * sends on UPDATE ramrod for that matter. + */ +static int bnx2x_setup_rss(struct bnx2x *bp, + struct bnx2x_config_rss_params *p) +{ + struct bnx2x_rss_config_obj *o = p->rss_obj; + struct bnx2x_raw_obj *r = &o->raw; + struct eth_rss_update_ramrod_data *data = + (struct eth_rss_update_ramrod_data *)(r->rdata); + u8 rss_mode = 0; + int rc; + + memset(data, 0, sizeof(*data)); + + DP(BNX2X_MSG_SP, "Configuring RSS\n"); + + /* Set an echo field */ + data->echo = (r->cid & BNX2X_SWCID_MASK) | + (r->state << BNX2X_SWCID_SHIFT); + + /* RSS mode */ + if (test_bit(BNX2X_RSS_MODE_DISABLED, &p->rss_flags)) + rss_mode = ETH_RSS_MODE_DISABLED; + else if (test_bit(BNX2X_RSS_MODE_REGULAR, &p->rss_flags)) + rss_mode = ETH_RSS_MODE_REGULAR; + else if (test_bit(BNX2X_RSS_MODE_VLAN_PRI, &p->rss_flags)) + rss_mode = ETH_RSS_MODE_VLAN_PRI; + else if (test_bit(BNX2X_RSS_MODE_E1HOV_PRI, &p->rss_flags)) + rss_mode = ETH_RSS_MODE_E1HOV_PRI; + else if (test_bit(BNX2X_RSS_MODE_IP_DSCP, &p->rss_flags)) + rss_mode = ETH_RSS_MODE_IP_DSCP; + + data->rss_mode = rss_mode; + + DP(BNX2X_MSG_SP, "rss_mode=%d\n", rss_mode); + + /* RSS capabilities */ + if (test_bit(BNX2X_RSS_IPV4, &p->rss_flags)) + data->capabilities |= + ETH_RSS_UPDATE_RAMROD_DATA_IPV4_CAPABILITY; + + if (test_bit(BNX2X_RSS_IPV4_TCP, &p->rss_flags)) + data->capabilities |= + ETH_RSS_UPDATE_RAMROD_DATA_IPV4_TCP_CAPABILITY; + + if (test_bit(BNX2X_RSS_IPV6, &p->rss_flags)) + data->capabilities |= + ETH_RSS_UPDATE_RAMROD_DATA_IPV6_CAPABILITY; + + if (test_bit(BNX2X_RSS_IPV6_TCP, &p->rss_flags)) + data->capabilities |= + ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY; + + /* Hashing mask */ + data->rss_result_mask = p->rss_result_mask; + + /* RSS engine ID */ + data->rss_engine_id = o->engine_id; + + DP(BNX2X_MSG_SP, "rss_engine_id=%d\n", data->rss_engine_id); + + /* Indirection table */ + memcpy(data->indirection_table, p->ind_table, + T_ETH_INDIRECTION_TABLE_SIZE); + + /* Remember the last configuration */ + memcpy(o->ind_table, p->ind_table, T_ETH_INDIRECTION_TABLE_SIZE); + + /* Print the indirection table */ + if (netif_msg_ifup(bp)) + bnx2x_debug_print_ind_table(bp, p); + + /* RSS keys */ + if (test_bit(BNX2X_RSS_SET_SRCH, &p->rss_flags)) { + memcpy(&data->rss_key[0], &p->rss_key[0], + sizeof(data->rss_key)); + data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY; + } + + /* Commit writes towards the memory before sending a ramrod */ + mb(); + + /* Send a ramrod */ + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_RSS_UPDATE, r->cid, + U64_HI(r->rdata_mapping), + U64_LO(r->rdata_mapping), + ETH_CONNECTION_TYPE); + + if (rc < 0) + return rc; + + return 1; +} + +void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj, + u8 *ind_table) +{ + memcpy(ind_table, rss_obj->ind_table, sizeof(rss_obj->ind_table)); +} + +int bnx2x_config_rss(struct bnx2x *bp, + struct bnx2x_config_rss_params *p) +{ + int rc; + struct bnx2x_rss_config_obj *o = p->rss_obj; + struct bnx2x_raw_obj *r = &o->raw; + + /* Do nothing if only driver cleanup was requested */ + if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) + return 0; + + r->set_pending(r); + + rc = o->config_rss(bp, p); + if (rc < 0) { + r->clear_pending(r); + return rc; + } + + if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) + rc = r->wait_comp(bp, r); + + return rc; +} + + +void bnx2x_init_rss_config_obj(struct bnx2x *bp, + struct bnx2x_rss_config_obj *rss_obj, + u8 cl_id, u32 cid, u8 func_id, u8 engine_id, + void *rdata, dma_addr_t rdata_mapping, + int state, unsigned long *pstate, + bnx2x_obj_type type) +{ + bnx2x_init_raw_obj(&rss_obj->raw, cl_id, cid, func_id, rdata, + rdata_mapping, state, pstate, type); + + rss_obj->engine_id = engine_id; + rss_obj->config_rss = bnx2x_setup_rss; +} + +/********************** Queue state object ***********************************/ + +/** + * bnx2x_queue_state_change - perform Queue state change transition + * + * @bp: device handle + * @params: parameters to perform the transition + * + * returns 0 in case of successfully completed transition, negative error + * code in case of failure, positive (EBUSY) value if there is a completion + * to that is still pending (possible only if RAMROD_COMP_WAIT is + * not set in params->ramrod_flags for asynchronous commands). + * + */ +int bnx2x_queue_state_change(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + int rc, pending_bit; + unsigned long *pending = &o->pending; + + /* Check that the requested transition is legal */ + if (o->check_transition(bp, o, params)) + return -EINVAL; + + /* Set "pending" bit */ + pending_bit = o->set_pending(o, params); + + /* Don't send a command if only driver cleanup was requested */ + if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) + o->complete_cmd(bp, o, pending_bit); + else { + /* Send a ramrod */ + rc = o->send_cmd(bp, params); + if (rc) { + o->next_state = BNX2X_Q_STATE_MAX; + clear_bit(pending_bit, pending); + smp_mb__after_clear_bit(); + return rc; + } + + if (test_bit(RAMROD_COMP_WAIT, ¶ms->ramrod_flags)) { + rc = o->wait_comp(bp, o, pending_bit); + if (rc) + return rc; + + return 0; + } + } + + return !!test_bit(pending_bit, pending); +} + + +static int bnx2x_queue_set_pending(struct bnx2x_queue_sp_obj *obj, + struct bnx2x_queue_state_params *params) +{ + enum bnx2x_queue_cmd cmd = params->cmd, bit; + + /* ACTIVATE and DEACTIVATE commands are implemented on top of + * UPDATE command. + */ + if ((cmd == BNX2X_Q_CMD_ACTIVATE) || + (cmd == BNX2X_Q_CMD_DEACTIVATE)) + bit = BNX2X_Q_CMD_UPDATE; + else + bit = cmd; + + set_bit(bit, &obj->pending); + return bit; +} + +static int bnx2x_queue_wait_comp(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *o, + enum bnx2x_queue_cmd cmd) +{ + return bnx2x_state_wait(bp, cmd, &o->pending); +} + +/** + * bnx2x_queue_comp_cmd - complete the state change command. + * + * @bp: device handle + * @o: + * @cmd: + * + * Checks that the arrived completion is expected. + */ +static int bnx2x_queue_comp_cmd(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *o, + enum bnx2x_queue_cmd cmd) +{ + unsigned long cur_pending = o->pending; + + if (!test_and_clear_bit(cmd, &cur_pending)) { + BNX2X_ERR("Bad MC reply %d for queue %d in state %d " + "pending 0x%lx, next_state %d\n", cmd, o->cid, + o->state, cur_pending, o->next_state); + return -EINVAL; + } + + DP(BNX2X_MSG_SP, "Completing command %d for queue %d, " + "setting state to %d\n", cmd, o->cid, o->next_state); + + o->state = o->next_state; + o->next_state = BNX2X_Q_STATE_MAX; + + /* It's important that o->state and o->next_state are + * updated before o->pending. + */ + wmb(); + + clear_bit(cmd, &o->pending); + smp_mb__after_clear_bit(); + + return 0; +} + +static void bnx2x_q_fill_setup_data_e2(struct bnx2x *bp, + struct bnx2x_queue_state_params *cmd_params, + struct client_init_ramrod_data *data) +{ + struct bnx2x_queue_setup_params *params = &cmd_params->params.setup; + + /* Rx data */ + + /* IPv6 TPA supported for E2 and above only */ + data->rx.tpa_en |= test_bit(BNX2X_Q_FLG_TPA, ¶ms->flags) * + CLIENT_INIT_RX_DATA_TPA_EN_IPV6; +} + +static void bnx2x_q_fill_setup_data_cmn(struct bnx2x *bp, + struct bnx2x_queue_state_params *cmd_params, + struct client_init_ramrod_data *data) +{ + struct bnx2x_queue_sp_obj *o = cmd_params->q_obj; + struct bnx2x_queue_setup_params *params = &cmd_params->params.setup; + + + /* general */ + data->general.client_id = o->cl_id; + + if (test_bit(BNX2X_Q_FLG_STATS, ¶ms->flags)) { + data->general.statistics_counter_id = + params->gen_params.stat_id; + data->general.statistics_en_flg = 1; + data->general.statistics_zero_flg = + test_bit(BNX2X_Q_FLG_ZERO_STATS, ¶ms->flags); + } else + data->general.statistics_counter_id = + DISABLE_STATISTIC_COUNTER_ID_VALUE; + + data->general.is_fcoe_flg = test_bit(BNX2X_Q_FLG_FCOE, ¶ms->flags); + data->general.activate_flg = test_bit(BNX2X_Q_FLG_ACTIVE, + ¶ms->flags); + data->general.sp_client_id = params->gen_params.spcl_id; + data->general.mtu = cpu_to_le16(params->gen_params.mtu); + data->general.func_id = o->func_id; + + + data->general.cos = params->txq_params.cos; + + data->general.traffic_type = + test_bit(BNX2X_Q_FLG_FCOE, ¶ms->flags) ? + LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; + + /* Rx data */ + data->rx.tpa_en = test_bit(BNX2X_Q_FLG_TPA, ¶ms->flags) * + CLIENT_INIT_RX_DATA_TPA_EN_IPV4; + data->rx.vmqueue_mode_en_flg = 0; + + data->rx.cache_line_alignment_log_size = + params->rxq_params.cache_line_log; + data->rx.enable_dynamic_hc = + test_bit(BNX2X_Q_FLG_DHC, ¶ms->flags); + data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; + data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; + data->rx.max_agg_size = cpu_to_le16(params->rxq_params.tpa_agg_sz); + + /* Always start in DROP_ALL mode */ + data->rx.state = cpu_to_le16(CLIENT_INIT_RX_DATA_UCAST_DROP_ALL | + CLIENT_INIT_RX_DATA_MCAST_DROP_ALL); + + /* We don't set drop flags */ + data->rx.drop_ip_cs_err_flg = 0; + data->rx.drop_tcp_cs_err_flg = 0; + data->rx.drop_ttl0_flg = 0; + data->rx.drop_udp_cs_err_flg = 0; + data->rx.inner_vlan_removal_enable_flg = + test_bit(BNX2X_Q_FLG_VLAN, ¶ms->flags); + data->rx.outer_vlan_removal_enable_flg = + test_bit(BNX2X_Q_FLG_OV, ¶ms->flags); + data->rx.status_block_id = params->rxq_params.fw_sb_id; + data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; + data->rx.max_tpa_queues = params->rxq_params.max_tpa_queues; + data->rx.max_bytes_on_bd = cpu_to_le16(params->rxq_params.buf_sz); + data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); + data->rx.bd_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); + data->rx.bd_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); + data->rx.sge_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.sge_map)); + data->rx.sge_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.sge_map)); + data->rx.cqe_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); + data->rx.cqe_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); + data->rx.is_leading_rss = test_bit(BNX2X_Q_FLG_LEADING_RSS, + ¶ms->flags); + + if (test_bit(BNX2X_Q_FLG_MCAST, ¶ms->flags)) { + data->rx.approx_mcast_engine_id = o->func_id; + data->rx.is_approx_mcast = 1; + } + + data->rx.rss_engine_id = params->rxq_params.rss_engine_id; + + /* flow control data */ + data->rx.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); + data->rx.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); + data->rx.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); + data->rx.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); + data->rx.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); + data->rx.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); + data->rx.rx_cos_mask = cpu_to_le16(params->pause.pri_map); + + /* silent vlan removal */ + data->rx.silent_vlan_removal_flg = + test_bit(BNX2X_Q_FLG_SILENT_VLAN_REM, ¶ms->flags); + data->rx.silent_vlan_value = + cpu_to_le16(params->rxq_params.silent_removal_value); + data->rx.silent_vlan_mask = + cpu_to_le16(params->rxq_params.silent_removal_mask); + + /* Tx data */ + data->tx.enforce_security_flg = + test_bit(BNX2X_Q_FLG_TX_SEC, ¶ms->flags); + data->tx.default_vlan = + cpu_to_le16(params->txq_params.default_vlan); + data->tx.default_vlan_flg = + test_bit(BNX2X_Q_FLG_DEF_VLAN, ¶ms->flags); + data->tx.tx_switching_flg = + test_bit(BNX2X_Q_FLG_TX_SWITCH, ¶ms->flags); + data->tx.anti_spoofing_flg = + test_bit(BNX2X_Q_FLG_ANTI_SPOOF, ¶ms->flags); + data->tx.tx_status_block_id = params->txq_params.fw_sb_id; + data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; + data->tx.tss_leading_client_id = params->txq_params.tss_leading_cl_id; + + data->tx.tx_bd_page_base.lo = + cpu_to_le32(U64_LO(params->txq_params.dscr_map)); + data->tx.tx_bd_page_base.hi = + cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + + /* Don't configure any Tx switching mode during queue SETUP */ + data->tx.state = 0; +} + + +/** + * bnx2x_q_init - init HW/FW queue + * + * @bp: device handle + * @params: + * + * HW/FW initial Queue configuration: + * - HC: Rx and Tx + * - CDU context validation + * + */ +static inline int bnx2x_q_init(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + struct bnx2x_queue_init_params *init = ¶ms->params.init; + u16 hc_usec; + + /* Tx HC configuration */ + if (test_bit(BNX2X_Q_TYPE_HAS_TX, &o->type) && + test_bit(BNX2X_Q_FLG_HC, &init->tx.flags)) { + hc_usec = init->tx.hc_rate ? 1000000 / init->tx.hc_rate : 0; + + bnx2x_update_coalesce_sb_index(bp, init->tx.fw_sb_id, + init->tx.sb_cq_index, + !test_bit(BNX2X_Q_FLG_HC_EN, &init->tx.flags), + hc_usec); + } + + /* Rx HC configuration */ + if (test_bit(BNX2X_Q_TYPE_HAS_RX, &o->type) && + test_bit(BNX2X_Q_FLG_HC, &init->rx.flags)) { + hc_usec = init->rx.hc_rate ? 1000000 / init->rx.hc_rate : 0; + + bnx2x_update_coalesce_sb_index(bp, init->rx.fw_sb_id, + init->rx.sb_cq_index, + !test_bit(BNX2X_Q_FLG_HC_EN, &init->rx.flags), + hc_usec); + } + + /* Set CDU context validation values */ + bnx2x_set_ctx_validation(bp, init->cxt, o->cid); + + /* As no ramrod is sent, complete the command immediately */ + o->complete_cmd(bp, o, BNX2X_Q_CMD_INIT); + + mmiowb(); + smp_mb(); + + return 0; +} + +static inline int bnx2x_q_send_setup_e1x(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + struct client_init_ramrod_data *rdata = + (struct client_init_ramrod_data *)o->rdata; + dma_addr_t data_mapping = o->rdata_mapping; + int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; + + /* Clear the ramrod data */ + memset(rdata, 0, sizeof(*rdata)); + + /* Fill the ramrod data */ + bnx2x_q_fill_setup_data_cmn(bp, params, rdata); + + mb(); + + return bnx2x_sp_post(bp, ramrod, o->cid, U64_HI(data_mapping), + U64_LO(data_mapping), ETH_CONNECTION_TYPE); +} + +static inline int bnx2x_q_send_setup_e2(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + struct client_init_ramrod_data *rdata = + (struct client_init_ramrod_data *)o->rdata; + dma_addr_t data_mapping = o->rdata_mapping; + int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; + + /* Clear the ramrod data */ + memset(rdata, 0, sizeof(*rdata)); + + /* Fill the ramrod data */ + bnx2x_q_fill_setup_data_cmn(bp, params, rdata); + bnx2x_q_fill_setup_data_e2(bp, params, rdata); + + mb(); + + return bnx2x_sp_post(bp, ramrod, o->cid, U64_HI(data_mapping), + U64_LO(data_mapping), ETH_CONNECTION_TYPE); +} + +static void bnx2x_q_fill_update_data(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *obj, + struct bnx2x_queue_update_params *params, + struct client_update_ramrod_data *data) +{ + /* Client ID of the client to update */ + data->client_id = obj->cl_id; + + /* Function ID of the client to update */ + data->func_id = obj->func_id; + + /* Default VLAN value */ + data->default_vlan = cpu_to_le16(params->def_vlan); + + /* Inner VLAN stripping */ + data->inner_vlan_removal_enable_flg = + test_bit(BNX2X_Q_UPDATE_IN_VLAN_REM, ¶ms->update_flags); + data->inner_vlan_removal_change_flg = + test_bit(BNX2X_Q_UPDATE_IN_VLAN_REM_CHNG, + ¶ms->update_flags); + + /* Outer VLAN sripping */ + data->outer_vlan_removal_enable_flg = + test_bit(BNX2X_Q_UPDATE_OUT_VLAN_REM, ¶ms->update_flags); + data->outer_vlan_removal_change_flg = + test_bit(BNX2X_Q_UPDATE_OUT_VLAN_REM_CHNG, + ¶ms->update_flags); + + /* Drop packets that have source MAC that doesn't belong to this + * Queue. + */ + data->anti_spoofing_enable_flg = + test_bit(BNX2X_Q_UPDATE_ANTI_SPOOF, ¶ms->update_flags); + data->anti_spoofing_change_flg = + test_bit(BNX2X_Q_UPDATE_ANTI_SPOOF_CHNG, ¶ms->update_flags); + + /* Activate/Deactivate */ + data->activate_flg = + test_bit(BNX2X_Q_UPDATE_ACTIVATE, ¶ms->update_flags); + data->activate_change_flg = + test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, ¶ms->update_flags); + + /* Enable default VLAN */ + data->default_vlan_enable_flg = + test_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN, ¶ms->update_flags); + data->default_vlan_change_flg = + test_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG, + ¶ms->update_flags); + + /* silent vlan removal */ + data->silent_vlan_change_flg = + test_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG, + ¶ms->update_flags); + data->silent_vlan_removal_flg = + test_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM, ¶ms->update_flags); + data->silent_vlan_value = cpu_to_le16(params->silent_removal_value); + data->silent_vlan_mask = cpu_to_le16(params->silent_removal_mask); +} + +static inline int bnx2x_q_send_update(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + struct client_update_ramrod_data *rdata = + (struct client_update_ramrod_data *)o->rdata; + dma_addr_t data_mapping = o->rdata_mapping; + + /* Clear the ramrod data */ + memset(rdata, 0, sizeof(*rdata)); + + /* Fill the ramrod data */ + bnx2x_q_fill_update_data(bp, o, ¶ms->params.update, rdata); + + mb(); + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, o->cid, + U64_HI(data_mapping), + U64_LO(data_mapping), ETH_CONNECTION_TYPE); +} + +/** + * bnx2x_q_send_deactivate - send DEACTIVATE command + * + * @bp: device handle + * @params: + * + * implemented using the UPDATE command. + */ +static inline int bnx2x_q_send_deactivate(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_update_params *update = ¶ms->params.update; + + memset(update, 0, sizeof(*update)); + + __set_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, &update->update_flags); + + return bnx2x_q_send_update(bp, params); +} + +/** + * bnx2x_q_send_activate - send ACTIVATE command + * + * @bp: device handle + * @params: + * + * implemented using the UPDATE command. + */ +static inline int bnx2x_q_send_activate(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_update_params *update = ¶ms->params.update; + + memset(update, 0, sizeof(*update)); + + __set_bit(BNX2X_Q_UPDATE_ACTIVATE, &update->update_flags); + __set_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, &update->update_flags); + + return bnx2x_q_send_update(bp, params); +} + +static inline int bnx2x_q_send_update_tpa(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + /* TODO: Not implemented yet. */ + return -1; +} + +static inline int bnx2x_q_send_halt(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, o->cid, 0, o->cl_id, + ETH_CONNECTION_TYPE); +} + +static inline int bnx2x_q_send_cfc_del(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, o->cid, 0, 0, + NONE_CONNECTION_TYPE); +} + +static inline int bnx2x_q_send_terminate(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, o->cid, 0, 0, + ETH_CONNECTION_TYPE); +} + +static inline int bnx2x_q_send_empty(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_EMPTY, o->cid, 0, 0, + ETH_CONNECTION_TYPE); +} + +static inline int bnx2x_queue_send_cmd_cmn(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + switch (params->cmd) { + case BNX2X_Q_CMD_INIT: + return bnx2x_q_init(bp, params); + case BNX2X_Q_CMD_DEACTIVATE: + return bnx2x_q_send_deactivate(bp, params); + case BNX2X_Q_CMD_ACTIVATE: + return bnx2x_q_send_activate(bp, params); + case BNX2X_Q_CMD_UPDATE: + return bnx2x_q_send_update(bp, params); + case BNX2X_Q_CMD_UPDATE_TPA: + return bnx2x_q_send_update_tpa(bp, params); + case BNX2X_Q_CMD_HALT: + return bnx2x_q_send_halt(bp, params); + case BNX2X_Q_CMD_CFC_DEL: + return bnx2x_q_send_cfc_del(bp, params); + case BNX2X_Q_CMD_TERMINATE: + return bnx2x_q_send_terminate(bp, params); + case BNX2X_Q_CMD_EMPTY: + return bnx2x_q_send_empty(bp, params); + default: + BNX2X_ERR("Unknown command: %d\n", params->cmd); + return -EINVAL; + } +} + +static int bnx2x_queue_send_cmd_e1x(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + switch (params->cmd) { + case BNX2X_Q_CMD_SETUP: + return bnx2x_q_send_setup_e1x(bp, params); + case BNX2X_Q_CMD_INIT: + case BNX2X_Q_CMD_DEACTIVATE: + case BNX2X_Q_CMD_ACTIVATE: + case BNX2X_Q_CMD_UPDATE: + case BNX2X_Q_CMD_UPDATE_TPA: + case BNX2X_Q_CMD_HALT: + case BNX2X_Q_CMD_CFC_DEL: + case BNX2X_Q_CMD_TERMINATE: + case BNX2X_Q_CMD_EMPTY: + return bnx2x_queue_send_cmd_cmn(bp, params); + default: + BNX2X_ERR("Unknown command: %d\n", params->cmd); + return -EINVAL; + } +} + +static int bnx2x_queue_send_cmd_e2(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + switch (params->cmd) { + case BNX2X_Q_CMD_SETUP: + return bnx2x_q_send_setup_e2(bp, params); + case BNX2X_Q_CMD_INIT: + case BNX2X_Q_CMD_DEACTIVATE: + case BNX2X_Q_CMD_ACTIVATE: + case BNX2X_Q_CMD_UPDATE: + case BNX2X_Q_CMD_UPDATE_TPA: + case BNX2X_Q_CMD_HALT: + case BNX2X_Q_CMD_CFC_DEL: + case BNX2X_Q_CMD_TERMINATE: + case BNX2X_Q_CMD_EMPTY: + return bnx2x_queue_send_cmd_cmn(bp, params); + default: + BNX2X_ERR("Unknown command: %d\n", params->cmd); + return -EINVAL; + } +} + +/** + * bnx2x_queue_chk_transition - check state machine of a regular Queue + * + * @bp: device handle + * @o: + * @params: + * + * (not Forwarding) + * It both checks if the requested command is legal in a current + * state and, if it's legal, sets a `next_state' in the object + * that will be used in the completion flow to set the `state' + * of the object. + * + * returns 0 if a requested command is a legal transition, + * -EINVAL otherwise. + */ +static int bnx2x_queue_chk_transition(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *o, + struct bnx2x_queue_state_params *params) +{ + enum bnx2x_q_state state = o->state, next_state = BNX2X_Q_STATE_MAX; + enum bnx2x_queue_cmd cmd = params->cmd; + + switch (state) { + case BNX2X_Q_STATE_RESET: + if (cmd == BNX2X_Q_CMD_INIT) + next_state = BNX2X_Q_STATE_INITIALIZED; + + break; + case BNX2X_Q_STATE_INITIALIZED: + if (cmd == BNX2X_Q_CMD_SETUP) { + if (test_bit(BNX2X_Q_FLG_ACTIVE, + ¶ms->params.setup.flags)) + next_state = BNX2X_Q_STATE_ACTIVE; + else + next_state = BNX2X_Q_STATE_INACTIVE; + } + + break; + case BNX2X_Q_STATE_ACTIVE: + if (cmd == BNX2X_Q_CMD_DEACTIVATE) + next_state = BNX2X_Q_STATE_INACTIVE; + + else if ((cmd == BNX2X_Q_CMD_EMPTY) || + (cmd == BNX2X_Q_CMD_UPDATE_TPA)) + next_state = BNX2X_Q_STATE_ACTIVE; + + else if (cmd == BNX2X_Q_CMD_HALT) + next_state = BNX2X_Q_STATE_STOPPED; + + else if (cmd == BNX2X_Q_CMD_UPDATE) { + struct bnx2x_queue_update_params *update_params = + ¶ms->params.update; + + /* If "active" state change is requested, update the + * state accordingly. + */ + if (test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, + &update_params->update_flags) && + !test_bit(BNX2X_Q_UPDATE_ACTIVATE, + &update_params->update_flags)) + next_state = BNX2X_Q_STATE_INACTIVE; + else + next_state = BNX2X_Q_STATE_ACTIVE; + } + + break; + case BNX2X_Q_STATE_INACTIVE: + if (cmd == BNX2X_Q_CMD_ACTIVATE) + next_state = BNX2X_Q_STATE_ACTIVE; + + else if ((cmd == BNX2X_Q_CMD_EMPTY) || + (cmd == BNX2X_Q_CMD_UPDATE_TPA)) + next_state = BNX2X_Q_STATE_INACTIVE; + + else if (cmd == BNX2X_Q_CMD_HALT) + next_state = BNX2X_Q_STATE_STOPPED; + + else if (cmd == BNX2X_Q_CMD_UPDATE) { + struct bnx2x_queue_update_params *update_params = + ¶ms->params.update; + + /* If "active" state change is requested, update the + * state accordingly. + */ + if (test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, + &update_params->update_flags) && + test_bit(BNX2X_Q_UPDATE_ACTIVATE, + &update_params->update_flags)) + next_state = BNX2X_Q_STATE_ACTIVE; + else + next_state = BNX2X_Q_STATE_INACTIVE; + } + + break; + case BNX2X_Q_STATE_STOPPED: + if (cmd == BNX2X_Q_CMD_TERMINATE) + next_state = BNX2X_Q_STATE_TERMINATED; + + break; + case BNX2X_Q_STATE_TERMINATED: + if (cmd == BNX2X_Q_CMD_CFC_DEL) + next_state = BNX2X_Q_STATE_RESET; + + break; + default: + BNX2X_ERR("Illegal state: %d\n", state); + } + + /* Transition is assured */ + if (next_state != BNX2X_Q_STATE_MAX) { + DP(BNX2X_MSG_SP, "Good state transition: %d(%d)->%d\n", + state, cmd, next_state); + o->next_state = next_state; + return 0; + } + + DP(BNX2X_MSG_SP, "Bad state transition request: %d %d\n", state, cmd); + + return -EINVAL; +} + +void bnx2x_init_queue_obj(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *obj, + u8 cl_id, u32 cid, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, unsigned long type) +{ + memset(obj, 0, sizeof(*obj)); + + obj->cid = cid; + obj->cl_id = cl_id; + obj->func_id = func_id; + obj->rdata = rdata; + obj->rdata_mapping = rdata_mapping; + obj->type = type; + obj->next_state = BNX2X_Q_STATE_MAX; + + if (CHIP_IS_E1x(bp)) + obj->send_cmd = bnx2x_queue_send_cmd_e1x; + else + obj->send_cmd = bnx2x_queue_send_cmd_e2; + + obj->check_transition = bnx2x_queue_chk_transition; + + obj->complete_cmd = bnx2x_queue_comp_cmd; + obj->wait_comp = bnx2x_queue_wait_comp; + obj->set_pending = bnx2x_queue_set_pending; +} + +/********************** Function state object *********************************/ + +static int bnx2x_func_wait_comp(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o, + enum bnx2x_func_cmd cmd) +{ + return bnx2x_state_wait(bp, cmd, &o->pending); +} + +/** + * bnx2x_func_state_change_comp - complete the state machine transition + * + * @bp: device handle + * @o: + * @cmd: + * + * Called on state change transition. Completes the state + * machine transition only - no HW interaction. + */ +static inline int bnx2x_func_state_change_comp(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o, + enum bnx2x_func_cmd cmd) +{ + unsigned long cur_pending = o->pending; + + if (!test_and_clear_bit(cmd, &cur_pending)) { + BNX2X_ERR("Bad MC reply %d for func %d in state %d " + "pending 0x%lx, next_state %d\n", cmd, BP_FUNC(bp), + o->state, cur_pending, o->next_state); + return -EINVAL; + } + + DP(BNX2X_MSG_SP, "Completing command %d for func %d, setting state to " + "%d\n", cmd, BP_FUNC(bp), o->next_state); + + o->state = o->next_state; + o->next_state = BNX2X_F_STATE_MAX; + + /* It's important that o->state and o->next_state are + * updated before o->pending. + */ + wmb(); + + clear_bit(cmd, &o->pending); + smp_mb__after_clear_bit(); + + return 0; +} + +/** + * bnx2x_func_comp_cmd - complete the state change command + * + * @bp: device handle + * @o: + * @cmd: + * + * Checks that the arrived completion is expected. + */ +static int bnx2x_func_comp_cmd(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o, + enum bnx2x_func_cmd cmd) +{ + /* Complete the state machine part first, check if it's a + * legal completion. + */ + int rc = bnx2x_func_state_change_comp(bp, o, cmd); + return rc; +} + +/** + * bnx2x_func_chk_transition - perform function state machine transition + * + * @bp: device handle + * @o: + * @params: + * + * It both checks if the requested command is legal in a current + * state and, if it's legal, sets a `next_state' in the object + * that will be used in the completion flow to set the `state' + * of the object. + * + * returns 0 if a requested command is a legal transition, + * -EINVAL otherwise. + */ +static int bnx2x_func_chk_transition(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o, + struct bnx2x_func_state_params *params) +{ + enum bnx2x_func_state state = o->state, next_state = BNX2X_F_STATE_MAX; + enum bnx2x_func_cmd cmd = params->cmd; + + switch (state) { + case BNX2X_F_STATE_RESET: + if (cmd == BNX2X_F_CMD_HW_INIT) + next_state = BNX2X_F_STATE_INITIALIZED; + + break; + case BNX2X_F_STATE_INITIALIZED: + if (cmd == BNX2X_F_CMD_START) + next_state = BNX2X_F_STATE_STARTED; + + else if (cmd == BNX2X_F_CMD_HW_RESET) + next_state = BNX2X_F_STATE_RESET; + + break; + case BNX2X_F_STATE_STARTED: + if (cmd == BNX2X_F_CMD_STOP) + next_state = BNX2X_F_STATE_INITIALIZED; + + break; + default: + BNX2X_ERR("Unknown state: %d\n", state); + } + + /* Transition is assured */ + if (next_state != BNX2X_F_STATE_MAX) { + DP(BNX2X_MSG_SP, "Good function state transition: %d(%d)->%d\n", + state, cmd, next_state); + o->next_state = next_state; + return 0; + } + + DP(BNX2X_MSG_SP, "Bad function state transition request: %d %d\n", + state, cmd); + + return -EINVAL; +} + +/** + * bnx2x_func_init_func - performs HW init at function stage + * + * @bp: device handle + * @drv: + * + * Init HW when the current phase is + * FW_MSG_CODE_DRV_LOAD_FUNCTION: initialize only FUNCTION-only + * HW blocks. + */ +static inline int bnx2x_func_init_func(struct bnx2x *bp, + const struct bnx2x_func_sp_drv_ops *drv) +{ + return drv->init_hw_func(bp); +} + +/** + * bnx2x_func_init_port - performs HW init at port stage + * + * @bp: device handle + * @drv: + * + * Init HW when the current phase is + * FW_MSG_CODE_DRV_LOAD_PORT: initialize PORT-only and + * FUNCTION-only HW blocks. + * + */ +static inline int bnx2x_func_init_port(struct bnx2x *bp, + const struct bnx2x_func_sp_drv_ops *drv) +{ + int rc = drv->init_hw_port(bp); + if (rc) + return rc; + + return bnx2x_func_init_func(bp, drv); +} + +/** + * bnx2x_func_init_cmn_chip - performs HW init at chip-common stage + * + * @bp: device handle + * @drv: + * + * Init HW when the current phase is + * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: initialize COMMON_CHIP, + * PORT-only and FUNCTION-only HW blocks. + */ +static inline int bnx2x_func_init_cmn_chip(struct bnx2x *bp, + const struct bnx2x_func_sp_drv_ops *drv) +{ + int rc = drv->init_hw_cmn_chip(bp); + if (rc) + return rc; + + return bnx2x_func_init_port(bp, drv); +} + +/** + * bnx2x_func_init_cmn - performs HW init at common stage + * + * @bp: device handle + * @drv: + * + * Init HW when the current phase is + * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: initialize COMMON, + * PORT-only and FUNCTION-only HW blocks. + */ +static inline int bnx2x_func_init_cmn(struct bnx2x *bp, + const struct bnx2x_func_sp_drv_ops *drv) +{ + int rc = drv->init_hw_cmn(bp); + if (rc) + return rc; + + return bnx2x_func_init_port(bp, drv); +} + +static int bnx2x_func_hw_init(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + u32 load_code = params->params.hw_init.load_phase; + struct bnx2x_func_sp_obj *o = params->f_obj; + const struct bnx2x_func_sp_drv_ops *drv = o->drv; + int rc = 0; + + DP(BNX2X_MSG_SP, "function %d load_code %x\n", + BP_ABS_FUNC(bp), load_code); + + /* Prepare buffers for unzipping the FW */ + rc = drv->gunzip_init(bp); + if (rc) + return rc; + + /* Prepare FW */ + rc = drv->init_fw(bp); + if (rc) { + BNX2X_ERR("Error loading firmware\n"); + goto fw_init_err; + } + + /* Handle the beginning of COMMON_XXX pases separatelly... */ + switch (load_code) { + case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: + rc = bnx2x_func_init_cmn_chip(bp, drv); + if (rc) + goto init_hw_err; + + break; + case FW_MSG_CODE_DRV_LOAD_COMMON: + rc = bnx2x_func_init_cmn(bp, drv); + if (rc) + goto init_hw_err; + + break; + case FW_MSG_CODE_DRV_LOAD_PORT: + rc = bnx2x_func_init_port(bp, drv); + if (rc) + goto init_hw_err; + + break; + case FW_MSG_CODE_DRV_LOAD_FUNCTION: + rc = bnx2x_func_init_func(bp, drv); + if (rc) + goto init_hw_err; + + break; + default: + BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code); + rc = -EINVAL; + } + +init_hw_err: + drv->release_fw(bp); + +fw_init_err: + drv->gunzip_end(bp); + + /* In case of success, complete the comand immediatelly: no ramrods + * have been sent. + */ + if (!rc) + o->complete_cmd(bp, o, BNX2X_F_CMD_HW_INIT); + + return rc; +} + +/** + * bnx2x_func_reset_func - reset HW at function stage + * + * @bp: device handle + * @drv: + * + * Reset HW at FW_MSG_CODE_DRV_UNLOAD_FUNCTION stage: reset only + * FUNCTION-only HW blocks. + */ +static inline void bnx2x_func_reset_func(struct bnx2x *bp, + const struct bnx2x_func_sp_drv_ops *drv) +{ + drv->reset_hw_func(bp); +} + +/** + * bnx2x_func_reset_port - reser HW at port stage + * + * @bp: device handle + * @drv: + * + * Reset HW at FW_MSG_CODE_DRV_UNLOAD_PORT stage: reset + * FUNCTION-only and PORT-only HW blocks. + * + * !!!IMPORTANT!!! + * + * It's important to call reset_port before reset_func() as the last thing + * reset_func does is pf_disable() thus disabling PGLUE_B, which + * makes impossible any DMAE transactions. + */ +static inline void bnx2x_func_reset_port(struct bnx2x *bp, + const struct bnx2x_func_sp_drv_ops *drv) +{ + drv->reset_hw_port(bp); + bnx2x_func_reset_func(bp, drv); +} + +/** + * bnx2x_func_reset_cmn - reser HW at common stage + * + * @bp: device handle + * @drv: + * + * Reset HW at FW_MSG_CODE_DRV_UNLOAD_COMMON and + * FW_MSG_CODE_DRV_UNLOAD_COMMON_CHIP stages: reset COMMON, + * COMMON_CHIP, FUNCTION-only and PORT-only HW blocks. + */ +static inline void bnx2x_func_reset_cmn(struct bnx2x *bp, + const struct bnx2x_func_sp_drv_ops *drv) +{ + bnx2x_func_reset_port(bp, drv); + drv->reset_hw_cmn(bp); +} + + +static inline int bnx2x_func_hw_reset(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + u32 reset_phase = params->params.hw_reset.reset_phase; + struct bnx2x_func_sp_obj *o = params->f_obj; + const struct bnx2x_func_sp_drv_ops *drv = o->drv; + + DP(BNX2X_MSG_SP, "function %d reset_phase %x\n", BP_ABS_FUNC(bp), + reset_phase); + + switch (reset_phase) { + case FW_MSG_CODE_DRV_UNLOAD_COMMON: + bnx2x_func_reset_cmn(bp, drv); + break; + case FW_MSG_CODE_DRV_UNLOAD_PORT: + bnx2x_func_reset_port(bp, drv); + break; + case FW_MSG_CODE_DRV_UNLOAD_FUNCTION: + bnx2x_func_reset_func(bp, drv); + break; + default: + BNX2X_ERR("Unknown reset_phase (0x%x) from MCP\n", + reset_phase); + break; + } + + /* Complete the comand immediatelly: no ramrods have been sent. */ + o->complete_cmd(bp, o, BNX2X_F_CMD_HW_RESET); + + return 0; +} + +static inline int bnx2x_func_send_start(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + struct bnx2x_func_sp_obj *o = params->f_obj; + struct function_start_data *rdata = + (struct function_start_data *)o->rdata; + dma_addr_t data_mapping = o->rdata_mapping; + struct bnx2x_func_start_params *start_params = ¶ms->params.start; + + memset(rdata, 0, sizeof(*rdata)); + + /* Fill the ramrod data with provided parameters */ + rdata->function_mode = cpu_to_le16(start_params->mf_mode); + rdata->sd_vlan_tag = start_params->sd_vlan_tag; + rdata->path_id = BP_PATH(bp); + rdata->network_cos_mode = start_params->network_cos_mode; + + mb(); + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, + U64_HI(data_mapping), + U64_LO(data_mapping), NONE_CONNECTION_TYPE); +} + +static inline int bnx2x_func_send_stop(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0, 0, + NONE_CONNECTION_TYPE); +} + +static int bnx2x_func_send_cmd(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + switch (params->cmd) { + case BNX2X_F_CMD_HW_INIT: + return bnx2x_func_hw_init(bp, params); + case BNX2X_F_CMD_START: + return bnx2x_func_send_start(bp, params); + case BNX2X_F_CMD_STOP: + return bnx2x_func_send_stop(bp, params); + case BNX2X_F_CMD_HW_RESET: + return bnx2x_func_hw_reset(bp, params); + default: + BNX2X_ERR("Unknown command: %d\n", params->cmd); + return -EINVAL; + } +} + +void bnx2x_init_func_obj(struct bnx2x *bp, + struct bnx2x_func_sp_obj *obj, + void *rdata, dma_addr_t rdata_mapping, + struct bnx2x_func_sp_drv_ops *drv_iface) +{ + memset(obj, 0, sizeof(*obj)); + + mutex_init(&obj->one_pending_mutex); + + obj->rdata = rdata; + obj->rdata_mapping = rdata_mapping; + + obj->send_cmd = bnx2x_func_send_cmd; + obj->check_transition = bnx2x_func_chk_transition; + obj->complete_cmd = bnx2x_func_comp_cmd; + obj->wait_comp = bnx2x_func_wait_comp; + + obj->drv = drv_iface; +} + +/** + * bnx2x_func_state_change - perform Function state change transition + * + * @bp: device handle + * @params: parameters to perform the transaction + * + * returns 0 in case of successfully completed transition, + * negative error code in case of failure, positive + * (EBUSY) value if there is a completion to that is + * still pending (possible only if RAMROD_COMP_WAIT is + * not set in params->ramrod_flags for asynchronous + * commands). + */ +int bnx2x_func_state_change(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + struct bnx2x_func_sp_obj *o = params->f_obj; + int rc; + enum bnx2x_func_cmd cmd = params->cmd; + unsigned long *pending = &o->pending; + + mutex_lock(&o->one_pending_mutex); + + /* Check that the requested transition is legal */ + if (o->check_transition(bp, o, params)) { + mutex_unlock(&o->one_pending_mutex); + return -EINVAL; + } + + /* Set "pending" bit */ + set_bit(cmd, pending); + + /* Don't send a command if only driver cleanup was requested */ + if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { + bnx2x_func_state_change_comp(bp, o, cmd); + mutex_unlock(&o->one_pending_mutex); + } else { + /* Send a ramrod */ + rc = o->send_cmd(bp, params); + + mutex_unlock(&o->one_pending_mutex); + + if (rc) { + o->next_state = BNX2X_F_STATE_MAX; + clear_bit(cmd, pending); + smp_mb__after_clear_bit(); + return rc; + } + + if (test_bit(RAMROD_COMP_WAIT, ¶ms->ramrod_flags)) { + rc = o->wait_comp(bp, o, cmd); + if (rc) + return rc; + + return 0; + } + } - for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) - REG_WR8(bp, BAR_TSTRORM_INTMEM + - TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, - bp->fp->cl_id + bp->rx_indir_table[i]); + return !!test_bit(cmd, pending); } diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h index f9b755e4a10..86eaa80721e 100644 --- a/drivers/net/bnx2x/bnx2x_sp.h +++ b/drivers/net/bnx2x/bnx2x_sp.h @@ -1,43 +1,1235 @@ -#ifndef BNX2X_SP -#define BNX2X_SP - -#include "bnx2x_reg.h" - -/* MAC configuration */ -void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 is_bcast); - -/* Multicast */ -void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp); -void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp); -int bnx2x_set_e1_mc_list(struct bnx2x *bp); -int bnx2x_set_e1h_mc_list(struct bnx2x *bp); - -/* Rx mode */ -void bnx2x_set_storm_rx_mode(struct bnx2x *bp); -void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters); - -/* RSS configuration */ -void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p); -void bnx2x_push_indir_table(struct bnx2x *bp); - -/* Queue configuration */ -static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) -{ - /* ustorm cxt validation */ - cxt->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); - /* xcontext validation */ - cxt->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); -} - -int bnx2x_setup_fw_client(struct bnx2x *bp, - struct bnx2x_client_init_params *params, - u8 activate, - struct client_init_ramrod_data *data, - dma_addr_t data_mapping); -#endif /* BNX2X_SP */ +/* bnx2x_sp.h: Broadcom Everest network driver. + * + * Copyright 2011 Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available + * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + * + * Maintained by: Eilon Greenstein + * Written by: Vladislav Zolotarov + * + */ +#ifndef BNX2X_SP_VERBS +#define BNX2X_SP_VERBS + +struct bnx2x; +struct eth_context; + +/* Bits representing general command's configuration */ +enum { + RAMROD_TX, + RAMROD_RX, + /* Wait until all pending commands complete */ + RAMROD_COMP_WAIT, + /* Don't send a ramrod, only update a registry */ + RAMROD_DRV_CLR_ONLY, + /* Configure HW according to the current object state */ + RAMROD_RESTORE, + /* Execute the next command now */ + RAMROD_EXEC, + /* + * Don't add a new command and continue execution of posponed + * commands. If not set a new command will be added to the + * pending commands list. + */ + RAMROD_CONT, +}; + +typedef enum { + BNX2X_OBJ_TYPE_RX, + BNX2X_OBJ_TYPE_TX, + BNX2X_OBJ_TYPE_RX_TX, +} bnx2x_obj_type; + +/* Filtering states */ +enum { + BNX2X_FILTER_MAC_PENDING, + BNX2X_FILTER_VLAN_PENDING, + BNX2X_FILTER_VLAN_MAC_PENDING, + BNX2X_FILTER_RX_MODE_PENDING, + BNX2X_FILTER_RX_MODE_SCHED, + BNX2X_FILTER_ISCSI_ETH_START_SCHED, + BNX2X_FILTER_ISCSI_ETH_STOP_SCHED, + BNX2X_FILTER_FCOE_ETH_START_SCHED, + BNX2X_FILTER_FCOE_ETH_STOP_SCHED, + BNX2X_FILTER_MCAST_PENDING, + BNX2X_FILTER_MCAST_SCHED, + BNX2X_FILTER_RSS_CONF_PENDING, +}; + +struct bnx2x_raw_obj { + u8 func_id; + + /* Queue params */ + u8 cl_id; + u32 cid; + + /* Ramrod data buffer params */ + void *rdata; + dma_addr_t rdata_mapping; + + /* Ramrod state params */ + int state; /* "ramrod is pending" state bit */ + unsigned long *pstate; /* pointer to state buffer */ + + bnx2x_obj_type obj_type; + + int (*wait_comp)(struct bnx2x *bp, + struct bnx2x_raw_obj *o); + + bool (*check_pending)(struct bnx2x_raw_obj *o); + void (*clear_pending)(struct bnx2x_raw_obj *o); + void (*set_pending)(struct bnx2x_raw_obj *o); +}; + +/************************* VLAN-MAC commands related parameters ***************/ +struct bnx2x_mac_ramrod_data { + u8 mac[ETH_ALEN]; +}; + +struct bnx2x_vlan_ramrod_data { + u16 vlan; +}; + +struct bnx2x_vlan_mac_ramrod_data { + u8 mac[ETH_ALEN]; + u16 vlan; +}; + +union bnx2x_classification_ramrod_data { + struct bnx2x_mac_ramrod_data mac; + struct bnx2x_vlan_ramrod_data vlan; + struct bnx2x_vlan_mac_ramrod_data vlan_mac; +}; + +/* VLAN_MAC commands */ +enum bnx2x_vlan_mac_cmd { + BNX2X_VLAN_MAC_ADD, + BNX2X_VLAN_MAC_DEL, + BNX2X_VLAN_MAC_MOVE, +}; + +struct bnx2x_vlan_mac_data { + /* Requested command: BNX2X_VLAN_MAC_XX */ + enum bnx2x_vlan_mac_cmd cmd; + /* + * used to contain the data related vlan_mac_flags bits from + * ramrod parameters. + */ + unsigned long vlan_mac_flags; + + /* Needed for MOVE command */ + struct bnx2x_vlan_mac_obj *target_obj; + + union bnx2x_classification_ramrod_data u; +}; + +/*************************** Exe Queue obj ************************************/ +union bnx2x_exe_queue_cmd_data { + struct bnx2x_vlan_mac_data vlan_mac; + + struct { + /* TODO */ + } mcast; +}; + +struct bnx2x_exeq_elem { + struct list_head link; + + /* Length of this element in the exe_chunk. */ + int cmd_len; + + union bnx2x_exe_queue_cmd_data cmd_data; +}; + +union bnx2x_qable_obj; + +union bnx2x_exeq_comp_elem { + union event_ring_elem *elem; +}; + +struct bnx2x_exe_queue_obj; + +typedef int (*exe_q_validate)(struct bnx2x *bp, + union bnx2x_qable_obj *o, + struct bnx2x_exeq_elem *elem); + +/** + * @return positive is entry was optimized, 0 - if not, negative + * in case of an error. + */ +typedef int (*exe_q_optimize)(struct bnx2x *bp, + union bnx2x_qable_obj *o, + struct bnx2x_exeq_elem *elem); +typedef int (*exe_q_execute)(struct bnx2x *bp, + union bnx2x_qable_obj *o, + struct list_head *exe_chunk, + unsigned long *ramrod_flags); +typedef struct bnx2x_exeq_elem * + (*exe_q_get)(struct bnx2x_exe_queue_obj *o, + struct bnx2x_exeq_elem *elem); + +struct bnx2x_exe_queue_obj { + /* + * Commands pending for an execution. + */ + struct list_head exe_queue; + + /* + * Commands pending for an completion. + */ + struct list_head pending_comp; + + spinlock_t lock; + + /* Maximum length of commands' list for one execution */ + int exe_chunk_len; + + union bnx2x_qable_obj *owner; + + /****** Virtual functions ******/ + /** + * Called before commands execution for commands that are really + * going to be executed (after 'optimize'). + * + * Must run under exe_queue->lock + */ + exe_q_validate validate; + + + /** + * This will try to cancel the current pending commands list + * considering the new command. + * + * Must run under exe_queue->lock + */ + exe_q_optimize optimize; + + /** + * Run the next commands chunk (owner specific). + */ + exe_q_execute execute; + + /** + * Return the exe_queue element containing the specific command + * if any. Otherwise return NULL. + */ + exe_q_get get; +}; +/***************** Classification verbs: Set/Del MAC/VLAN/VLAN-MAC ************/ +/* + * Element in the VLAN_MAC registry list having all currenty configured + * rules. + */ +struct bnx2x_vlan_mac_registry_elem { + struct list_head link; + + /* + * Used to store the cam offset used for the mac/vlan/vlan-mac. + * Relevant for 57710 and 57711 only. VLANs and MACs share the + * same CAM for these chips. + */ + int cam_offset; + + /* Needed for DEL and RESTORE flows */ + unsigned long vlan_mac_flags; + + union bnx2x_classification_ramrod_data u; +}; + +/* Bits representing VLAN_MAC commands specific flags */ +enum { + BNX2X_UC_LIST_MAC, + BNX2X_ETH_MAC, + BNX2X_ISCSI_ETH_MAC, + BNX2X_NETQ_ETH_MAC, + BNX2X_DONT_CONSUME_CAM_CREDIT, + BNX2X_DONT_CONSUME_CAM_CREDIT_DEST, +}; + +struct bnx2x_vlan_mac_ramrod_params { + /* Object to run the command from */ + struct bnx2x_vlan_mac_obj *vlan_mac_obj; + + /* General command flags: COMP_WAIT, etc. */ + unsigned long ramrod_flags; + + /* Command specific configuration request */ + struct bnx2x_vlan_mac_data user_req; +}; + +struct bnx2x_vlan_mac_obj { + struct bnx2x_raw_obj raw; + + /* Bookkeeping list: will prevent the addition of already existing + * entries. + */ + struct list_head head; + + /* TODO: Add it's initialization in the init functions */ + struct bnx2x_exe_queue_obj exe_queue; + + /* MACs credit pool */ + struct bnx2x_credit_pool_obj *macs_pool; + + /* VLANs credit pool */ + struct bnx2x_credit_pool_obj *vlans_pool; + + /* RAMROD command to be used */ + int ramrod_cmd; + + /** + * Checks if ADD-ramrod with the given params may be performed. + * + * @return zero if the element may be added + */ + + int (*check_add)(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data); + + /** + * Checks if DEL-ramrod with the given params may be performed. + * + * @return true if the element may be deleted + */ + struct bnx2x_vlan_mac_registry_elem * + (*check_del)(struct bnx2x_vlan_mac_obj *o, + union bnx2x_classification_ramrod_data *data); + + /** + * Checks if DEL-ramrod with the given params may be performed. + * + * @return true if the element may be deleted + */ + bool (*check_move)(struct bnx2x_vlan_mac_obj *src_o, + struct bnx2x_vlan_mac_obj *dst_o, + union bnx2x_classification_ramrod_data *data); + + /** + * Update the relevant credit object(s) (consume/return + * correspondingly). + */ + bool (*get_credit)(struct bnx2x_vlan_mac_obj *o); + bool (*put_credit)(struct bnx2x_vlan_mac_obj *o); + bool (*get_cam_offset)(struct bnx2x_vlan_mac_obj *o, int *offset); + bool (*put_cam_offset)(struct bnx2x_vlan_mac_obj *o, int offset); + + /** + * Configures one rule in the ramrod data buffer. + */ + void (*set_one_rule)(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + struct bnx2x_exeq_elem *elem, int rule_idx, + int cam_offset); + + /** + * Delete all configured elements having the given + * vlan_mac_flags specification. Assumes no pending for + * execution commands. Will schedule all all currently + * configured MACs/VLANs/VLAN-MACs matching the vlan_mac_flags + * specification for deletion and will use the given + * ramrod_flags for the last DEL operation. + * + * @param bp + * @param o + * @param ramrod_flags RAMROD_XX flags + * + * @return 0 if the last operation has completed successfully + * and there are no more elements left, positive value + * if there are pending for completion commands, + * negative value in case of failure. + */ + int (*delete_all)(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *o, + unsigned long *vlan_mac_flags, + unsigned long *ramrod_flags); + + /** + * Reconfigures the next MAC/VLAN/VLAN-MAC element from the previously + * configured elements list. + * + * @param bp + * @param p Command parameters (RAMROD_COMP_WAIT bit in + * ramrod_flags is only taken into an account) + * @param ppos a pointer to the cooky that should be given back in the + * next call to make function handle the next element. If + * *ppos is set to NULL it will restart the iterator. + * If returned *ppos == NULL this means that the last + * element has been handled. + * + * @return int + */ + int (*restore)(struct bnx2x *bp, + struct bnx2x_vlan_mac_ramrod_params *p, + struct bnx2x_vlan_mac_registry_elem **ppos); + + /** + * Should be called on a completion arival. + * + * @param bp + * @param o + * @param cqe Completion element we are handling + * @param ramrod_flags if RAMROD_CONT is set the next bulk of + * pending commands will be executed. + * RAMROD_DRV_CLR_ONLY and RAMROD_RESTORE + * may also be set if needed. + * + * @return 0 if there are neither pending nor waiting for + * completion commands. Positive value if there are + * pending for execution or for completion commands. + * Negative value in case of an error (including an + * error in the cqe). + */ + int (*complete)(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o, + union event_ring_elem *cqe, + unsigned long *ramrod_flags); + + /** + * Wait for completion of all commands. Don't schedule new ones, + * just wait. It assumes that the completion code will schedule + * for new commands. + */ + int (*wait)(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o); +}; + +/** RX_MODE verbs:DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */ + +/* RX_MODE ramrod spesial flags: set in rx_mode_flags field in + * a bnx2x_rx_mode_ramrod_params. + */ +enum { + BNX2X_RX_MODE_FCOE_ETH, + BNX2X_RX_MODE_ISCSI_ETH, +}; + +enum { + BNX2X_ACCEPT_UNICAST, + BNX2X_ACCEPT_MULTICAST, + BNX2X_ACCEPT_ALL_UNICAST, + BNX2X_ACCEPT_ALL_MULTICAST, + BNX2X_ACCEPT_BROADCAST, + BNX2X_ACCEPT_UNMATCHED, + BNX2X_ACCEPT_ANY_VLAN +}; + +struct bnx2x_rx_mode_ramrod_params { + struct bnx2x_rx_mode_obj *rx_mode_obj; + unsigned long *pstate; + int state; + u8 cl_id; + u32 cid; + u8 func_id; + unsigned long ramrod_flags; + unsigned long rx_mode_flags; + + /* + * rdata is either a pointer to eth_filter_rules_ramrod_data(e2) or to + * a tstorm_eth_mac_filter_config (e1x). + */ + void *rdata; + dma_addr_t rdata_mapping; + + /* Rx mode settings */ + unsigned long rx_accept_flags; + + /* internal switching settings */ + unsigned long tx_accept_flags; +}; + +struct bnx2x_rx_mode_obj { + int (*config_rx_mode)(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p); + + int (*wait_comp)(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p); +}; + +/********************** Set multicast group ***********************************/ + +struct bnx2x_mcast_list_elem { + struct list_head link; + u8 *mac; +}; + +union bnx2x_mcast_config_data { + u8 *mac; + u8 bin; /* used in a RESTORE flow */ +}; + +struct bnx2x_mcast_ramrod_params { + struct bnx2x_mcast_obj *mcast_obj; + + /* Relevant options are RAMROD_COMP_WAIT and RAMROD_DRV_CLR_ONLY */ + unsigned long ramrod_flags; + + struct list_head mcast_list; /* list of struct bnx2x_mcast_list_elem */ + /** TODO: + * - rename it to macs_num. + * - Add a new command type for handling pending commands + * (remove "zero semantics"). + * + * Length of mcast_list. If zero and ADD_CONT command - post + * pending commands. + */ + int mcast_list_len; +}; + +enum { + BNX2X_MCAST_CMD_ADD, + BNX2X_MCAST_CMD_CONT, + BNX2X_MCAST_CMD_DEL, + BNX2X_MCAST_CMD_RESTORE, +}; + +struct bnx2x_mcast_obj { + struct bnx2x_raw_obj raw; + + union { + struct { + #define BNX2X_MCAST_BINS_NUM 256 + #define BNX2X_MCAST_VEC_SZ (BNX2X_MCAST_BINS_NUM / 64) + u64 vec[BNX2X_MCAST_VEC_SZ]; + + /** Number of BINs to clear. Should be updated + * immediately when a command arrives in order to + * properly create DEL commands. + */ + int num_bins_set; + } aprox_match; + + struct { + struct list_head macs; + int num_macs_set; + } exact_match; + } registry; + + /* Pending commands */ + struct list_head pending_cmds_head; + + /* A state that is set in raw.pstate, when there are pending commands */ + int sched_state; + + /* Maximal number of mcast MACs configured in one command */ + int max_cmd_len; + + /* Total number of currently pending MACs to configure: both + * in the pending commands list and in the current command. + */ + int total_pending_num; + + u8 engine_id; + + /** + * @param cmd command to execute (BNX2X_MCAST_CMD_X, see above) + */ + int (*config_mcast)(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, int cmd); + + /** + * Fills the ramrod data during the RESTORE flow. + * + * @param bp + * @param o + * @param start_idx Registry index to start from + * @param rdata_idx Index in the ramrod data to start from + * + * @return -1 if we handled the whole registry or index of the last + * handled registry element. + */ + int (*hdl_restore)(struct bnx2x *bp, struct bnx2x_mcast_obj *o, + int start_bin, int *rdata_idx); + + int (*enqueue_cmd)(struct bnx2x *bp, struct bnx2x_mcast_obj *o, + struct bnx2x_mcast_ramrod_params *p, int cmd); + + void (*set_one_rule)(struct bnx2x *bp, + struct bnx2x_mcast_obj *o, int idx, + union bnx2x_mcast_config_data *cfg_data, int cmd); + + /** Checks if there are more mcast MACs to be set or a previous + * command is still pending. + */ + bool (*check_pending)(struct bnx2x_mcast_obj *o); + + /** + * Set/Clear/Check SCHEDULED state of the object + */ + void (*set_sched)(struct bnx2x_mcast_obj *o); + void (*clear_sched)(struct bnx2x_mcast_obj *o); + bool (*check_sched)(struct bnx2x_mcast_obj *o); + + /* Wait until all pending commands complete */ + int (*wait_comp)(struct bnx2x *bp, struct bnx2x_mcast_obj *o); + + /** + * Handle the internal object counters needed for proper + * commands handling. Checks that the provided parameters are + * feasible. + */ + int (*validate)(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, int cmd); + + /** + * Restore the values of internal counters in case of a failure. + */ + void (*revert)(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, + int old_num_bins); + + int (*get_registry_size)(struct bnx2x_mcast_obj *o); + void (*set_registry_size)(struct bnx2x_mcast_obj *o, int n); +}; + +/*************************** Credit handling **********************************/ +struct bnx2x_credit_pool_obj { + + /* Current amount of credit in the pool */ + atomic_t credit; + + /* Maximum allowed credit. put() will check against it. */ + int pool_sz; + + /* + * Allocate a pool table statically. + * + * Currently the mamimum allowed size is MAX_MAC_CREDIT_E2(272) + * + * The set bit in the table will mean that the entry is available. + */ +#define BNX2X_POOL_VEC_SIZE (MAX_MAC_CREDIT_E2 / 64) + u64 pool_mirror[BNX2X_POOL_VEC_SIZE]; + + /* Base pool offset (initialized differently */ + int base_pool_offset; + + /** + * Get the next free pool entry. + * + * @return true if there was a free entry in the pool + */ + bool (*get_entry)(struct bnx2x_credit_pool_obj *o, int *entry); + + /** + * Return the entry back to the pool. + * + * @return true if entry is legal and has been successfully + * returned to the pool. + */ + bool (*put_entry)(struct bnx2x_credit_pool_obj *o, int entry); + + /** + * Get the requested amount of credit from the pool. + * + * @param cnt Amount of requested credit + * @return true if the operation is successful + */ + bool (*get)(struct bnx2x_credit_pool_obj *o, int cnt); + + /** + * Returns the credit to the pool. + * + * @param cnt Amount of credit to return + * @return true if the operation is successful + */ + bool (*put)(struct bnx2x_credit_pool_obj *o, int cnt); + + /** + * Reads the current amount of credit. + */ + int (*check)(struct bnx2x_credit_pool_obj *o); +}; + +/*************************** RSS configuration ********************************/ +enum { + /* RSS_MODE bits are mutually exclusive */ + BNX2X_RSS_MODE_DISABLED, + BNX2X_RSS_MODE_REGULAR, + BNX2X_RSS_MODE_VLAN_PRI, + BNX2X_RSS_MODE_E1HOV_PRI, + BNX2X_RSS_MODE_IP_DSCP, + + BNX2X_RSS_SET_SRCH, /* Setup searcher, E1x specific flag */ + + BNX2X_RSS_IPV4, + BNX2X_RSS_IPV4_TCP, + BNX2X_RSS_IPV6, + BNX2X_RSS_IPV6_TCP, +}; + +struct bnx2x_config_rss_params { + struct bnx2x_rss_config_obj *rss_obj; + + /* may have RAMROD_COMP_WAIT set only */ + unsigned long ramrod_flags; + + /* BNX2X_RSS_X bits */ + unsigned long rss_flags; + + /* Number hash bits to take into an account */ + u8 rss_result_mask; + + /* Indirection table */ + u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE]; + + /* RSS hash values */ + u32 rss_key[10]; + + /* valid only iff BNX2X_RSS_UPDATE_TOE is set */ + u16 toe_rss_bitmap; +}; + +struct bnx2x_rss_config_obj { + struct bnx2x_raw_obj raw; + + /* RSS engine to use */ + u8 engine_id; + + /* Last configured indirection table */ + u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE]; + + int (*config_rss)(struct bnx2x *bp, + struct bnx2x_config_rss_params *p); +}; + +/*********************** Queue state update ***********************************/ + +/* UPDATE command options */ +enum { + BNX2X_Q_UPDATE_IN_VLAN_REM, + BNX2X_Q_UPDATE_IN_VLAN_REM_CHNG, + BNX2X_Q_UPDATE_OUT_VLAN_REM, + BNX2X_Q_UPDATE_OUT_VLAN_REM_CHNG, + BNX2X_Q_UPDATE_ANTI_SPOOF, + BNX2X_Q_UPDATE_ANTI_SPOOF_CHNG, + BNX2X_Q_UPDATE_ACTIVATE, + BNX2X_Q_UPDATE_ACTIVATE_CHNG, + BNX2X_Q_UPDATE_DEF_VLAN_EN, + BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG, + BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG, + BNX2X_Q_UPDATE_SILENT_VLAN_REM +}; + +/* Allowed Queue states */ +enum bnx2x_q_state { + BNX2X_Q_STATE_RESET, + BNX2X_Q_STATE_INITIALIZED, + BNX2X_Q_STATE_ACTIVE, + BNX2X_Q_STATE_INACTIVE, + BNX2X_Q_STATE_STOPPED, + BNX2X_Q_STATE_TERMINATED, + BNX2X_Q_STATE_FLRED, + BNX2X_Q_STATE_MAX, +}; + +/* Allowed commands */ +enum bnx2x_queue_cmd { + BNX2X_Q_CMD_INIT, + BNX2X_Q_CMD_SETUP, + BNX2X_Q_CMD_DEACTIVATE, + BNX2X_Q_CMD_ACTIVATE, + BNX2X_Q_CMD_UPDATE, + BNX2X_Q_CMD_UPDATE_TPA, + BNX2X_Q_CMD_HALT, + BNX2X_Q_CMD_CFC_DEL, + BNX2X_Q_CMD_TERMINATE, + BNX2X_Q_CMD_EMPTY, + BNX2X_Q_CMD_MAX, +}; + +/* queue SETUP + INIT flags */ +enum { + BNX2X_Q_FLG_TPA, + BNX2X_Q_FLG_STATS, + BNX2X_Q_FLG_ZERO_STATS, + BNX2X_Q_FLG_ACTIVE, + BNX2X_Q_FLG_OV, + BNX2X_Q_FLG_VLAN, + BNX2X_Q_FLG_COS, + BNX2X_Q_FLG_HC, + BNX2X_Q_FLG_HC_EN, + BNX2X_Q_FLG_DHC, + BNX2X_Q_FLG_FCOE, + BNX2X_Q_FLG_LEADING_RSS, + BNX2X_Q_FLG_MCAST, + BNX2X_Q_FLG_DEF_VLAN, + BNX2X_Q_FLG_TX_SWITCH, + BNX2X_Q_FLG_TX_SEC, + BNX2X_Q_FLG_ANTI_SPOOF, + BNX2X_Q_FLG_SILENT_VLAN_REM +}; + +/* Queue type options: queue type may be a compination of below. */ +enum bnx2x_q_type { + /** TODO: Consider moving both these flags into the init() + * ramrod params. + */ + BNX2X_Q_TYPE_HAS_RX, + BNX2X_Q_TYPE_HAS_TX, +}; + +struct bnx2x_queue_init_params { + struct { + unsigned long flags; + u16 hc_rate; + u8 fw_sb_id; + u8 sb_cq_index; + } tx; + + struct { + unsigned long flags; + u16 hc_rate; + u8 fw_sb_id; + u8 sb_cq_index; + } rx; + + /* CID context in the host memory */ + struct eth_context *cxt; +}; + +struct bnx2x_queue_update_params { + unsigned long update_flags; /* BNX2X_Q_UPDATE_XX bits */ + u16 def_vlan; + u16 silent_removal_value; + u16 silent_removal_mask; +}; + +struct rxq_pause_params { + u16 bd_th_lo; + u16 bd_th_hi; + u16 rcq_th_lo; + u16 rcq_th_hi; + u16 sge_th_lo; /* valid iff BNX2X_Q_FLG_TPA */ + u16 sge_th_hi; /* valid iff BNX2X_Q_FLG_TPA */ + u16 pri_map; +}; + +/* general */ +struct bnx2x_general_setup_params { + /* valid iff BNX2X_Q_FLG_STATS */ + u8 stat_id; + + u8 spcl_id; + u16 mtu; +}; + +struct bnx2x_rxq_setup_params { + /* dma */ + dma_addr_t dscr_map; + dma_addr_t sge_map; + dma_addr_t rcq_map; + dma_addr_t rcq_np_map; + + u16 drop_flags; + u16 buf_sz; + u8 fw_sb_id; + u8 cl_qzone_id; + + /* valid iff BNX2X_Q_FLG_TPA */ + u16 tpa_agg_sz; + u16 sge_buf_sz; + u8 max_sges_pkt; + u8 max_tpa_queues; + u8 rss_engine_id; + + u8 cache_line_log; + + u8 sb_cq_index; + + /* valid iff BXN2X_Q_FLG_SILENT_VLAN_REM */ + u16 silent_removal_value; + u16 silent_removal_mask; +}; + +struct bnx2x_txq_setup_params { + /* dma */ + dma_addr_t dscr_map; + + u8 fw_sb_id; + u8 sb_cq_index; + u8 cos; /* valid iff BNX2X_Q_FLG_COS */ + u16 traffic_type; + /* equals to the leading rss client id, used for TX classification*/ + u8 tss_leading_cl_id; + + /* valid iff BNX2X_Q_FLG_DEF_VLAN */ + u16 default_vlan; +}; + +struct bnx2x_queue_setup_params { + struct rxq_pause_params pause; + struct bnx2x_general_setup_params gen_params; + struct bnx2x_rxq_setup_params rxq_params; + struct bnx2x_txq_setup_params txq_params; + unsigned long flags; +}; + + +struct bnx2x_queue_state_params { + struct bnx2x_queue_sp_obj *q_obj; + + /* Current command */ + enum bnx2x_queue_cmd cmd; + + /* may have RAMROD_COMP_WAIT set only */ + unsigned long ramrod_flags; + + /* Params according to the current command */ + union { + struct bnx2x_queue_update_params update; + struct bnx2x_queue_setup_params setup; + struct bnx2x_queue_init_params init; + } params; +}; + +struct bnx2x_queue_sp_obj { + u32 cid; + u8 cl_id; + u8 func_id; + + enum bnx2x_q_state state, next_state; + + /* bits from enum bnx2x_q_type */ + unsigned long type; + + /* BNX2X_Q_CMD_XX bits. This object implements "one + * pending" paradigm but for debug and tracing purposes it's + * more convinient to have different bits for different + * commands. + */ + unsigned long pending; + + /* Buffer to use as a ramrod data and its mapping */ + void *rdata; + dma_addr_t rdata_mapping; + + /** + * Performs one state change according to the given parameters. + * + * @return 0 in case of success and negative value otherwise. + */ + int (*send_cmd)(struct bnx2x *bp, + struct bnx2x_queue_state_params *params); + + /** + * Sets the pending bit according to the requested transition. + */ + int (*set_pending)(struct bnx2x_queue_sp_obj *o, + struct bnx2x_queue_state_params *params); + + /** + * Checks that the requested state transition is legal. + */ + int (*check_transition)(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *o, + struct bnx2x_queue_state_params *params); + + /** + * Completes the pending command. + */ + int (*complete_cmd)(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *o, + enum bnx2x_queue_cmd); + + int (*wait_comp)(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *o, + enum bnx2x_queue_cmd cmd); +}; + +/********************** Function state update *********************************/ +/* Allowed Function states */ +enum bnx2x_func_state { + BNX2X_F_STATE_RESET, + BNX2X_F_STATE_INITIALIZED, + BNX2X_F_STATE_STARTED, + BNX2X_F_STATE_MAX, +}; + +/* Allowed Function commands */ +enum bnx2x_func_cmd { + BNX2X_F_CMD_HW_INIT, + BNX2X_F_CMD_START, + BNX2X_F_CMD_STOP, + BNX2X_F_CMD_HW_RESET, + BNX2X_F_CMD_MAX, +}; + +struct bnx2x_func_hw_init_params { + /* A load phase returned by MCP. + * + * May be: + * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP + * FW_MSG_CODE_DRV_LOAD_COMMON + * FW_MSG_CODE_DRV_LOAD_PORT + * FW_MSG_CODE_DRV_LOAD_FUNCTION + */ + u32 load_phase; +}; + +struct bnx2x_func_hw_reset_params { + /* A load phase returned by MCP. + * + * May be: + * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP + * FW_MSG_CODE_DRV_LOAD_COMMON + * FW_MSG_CODE_DRV_LOAD_PORT + * FW_MSG_CODE_DRV_LOAD_FUNCTION + */ + u32 reset_phase; +}; + +struct bnx2x_func_start_params { + /* Multi Function mode: + * - Single Function + * - Switch Dependent + * - Switch Independent + */ + u16 mf_mode; + + /* Switch Dependent mode outer VLAN tag */ + u16 sd_vlan_tag; + + /* Function cos mode */ + u8 network_cos_mode; +}; + +struct bnx2x_func_state_params { + struct bnx2x_func_sp_obj *f_obj; + + /* Current command */ + enum bnx2x_func_cmd cmd; + + /* may have RAMROD_COMP_WAIT set only */ + unsigned long ramrod_flags; + + /* Params according to the current command */ + union { + struct bnx2x_func_hw_init_params hw_init; + struct bnx2x_func_hw_reset_params hw_reset; + struct bnx2x_func_start_params start; + } params; +}; + +struct bnx2x_func_sp_drv_ops { + /* Init tool + runtime initialization: + * - Common Chip + * - Common (per Path) + * - Port + * - Function phases + */ + int (*init_hw_cmn_chip)(struct bnx2x *bp); + int (*init_hw_cmn)(struct bnx2x *bp); + int (*init_hw_port)(struct bnx2x *bp); + int (*init_hw_func)(struct bnx2x *bp); + + /* Reset Function HW: Common, Port, Function phases. */ + void (*reset_hw_cmn)(struct bnx2x *bp); + void (*reset_hw_port)(struct bnx2x *bp); + void (*reset_hw_func)(struct bnx2x *bp); + + /* Init/Free GUNZIP resources */ + int (*gunzip_init)(struct bnx2x *bp); + void (*gunzip_end)(struct bnx2x *bp); + + /* Prepare/Release FW resources */ + int (*init_fw)(struct bnx2x *bp); + void (*release_fw)(struct bnx2x *bp); +}; + +struct bnx2x_func_sp_obj { + enum bnx2x_func_state state, next_state; + + /* BNX2X_FUNC_CMD_XX bits. This object implements "one + * pending" paradigm but for debug and tracing purposes it's + * more convinient to have different bits for different + * commands. + */ + unsigned long pending; + + /* Buffer to use as a ramrod data and its mapping */ + void *rdata; + dma_addr_t rdata_mapping; + + /* this mutex validates that when pending flag is taken, the next + * ramrod to be sent will be the one set the pending bit + */ + struct mutex one_pending_mutex; + + /* Driver interface */ + struct bnx2x_func_sp_drv_ops *drv; + + /** + * Performs one state change according to the given parameters. + * + * @return 0 in case of success and negative value otherwise. + */ + int (*send_cmd)(struct bnx2x *bp, + struct bnx2x_func_state_params *params); + + /** + * Checks that the requested state transition is legal. + */ + int (*check_transition)(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o, + struct bnx2x_func_state_params *params); + + /** + * Completes the pending command. + */ + int (*complete_cmd)(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o, + enum bnx2x_func_cmd cmd); + + int (*wait_comp)(struct bnx2x *bp, struct bnx2x_func_sp_obj *o, + enum bnx2x_func_cmd cmd); +}; + +/********************** Interfaces ********************************************/ +/* Queueable objects set */ +union bnx2x_qable_obj { + struct bnx2x_vlan_mac_obj vlan_mac; +}; +/************** Function state update *********/ +void bnx2x_init_func_obj(struct bnx2x *bp, + struct bnx2x_func_sp_obj *obj, + void *rdata, dma_addr_t rdata_mapping, + struct bnx2x_func_sp_drv_ops *drv_iface); + +int bnx2x_func_state_change(struct bnx2x *bp, + struct bnx2x_func_state_params *params); + +/******************* Queue State **************/ +void bnx2x_init_queue_obj(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *obj, u8 cl_id, u32 cid, + u8 func_id, void *rdata, dma_addr_t rdata_mapping, + unsigned long type); + +int bnx2x_queue_state_change(struct bnx2x *bp, + struct bnx2x_queue_state_params *params); + +/********************* VLAN-MAC ****************/ +void bnx2x_init_mac_obj(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *mac_obj, + u8 cl_id, u32 cid, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, int state, + unsigned long *pstate, bnx2x_obj_type type, + struct bnx2x_credit_pool_obj *macs_pool); + +void bnx2x_init_vlan_obj(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *vlan_obj, + u8 cl_id, u32 cid, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, int state, + unsigned long *pstate, bnx2x_obj_type type, + struct bnx2x_credit_pool_obj *vlans_pool); + +void bnx2x_init_vlan_mac_obj(struct bnx2x *bp, + struct bnx2x_vlan_mac_obj *vlan_mac_obj, + u8 cl_id, u32 cid, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, int state, + unsigned long *pstate, bnx2x_obj_type type, + struct bnx2x_credit_pool_obj *macs_pool, + struct bnx2x_credit_pool_obj *vlans_pool); + +int bnx2x_config_vlan_mac(struct bnx2x *bp, + struct bnx2x_vlan_mac_ramrod_params *p); + +int bnx2x_vlan_mac_move(struct bnx2x *bp, + struct bnx2x_vlan_mac_ramrod_params *p, + struct bnx2x_vlan_mac_obj *dest_o); + +/********************* RX MODE ****************/ + +void bnx2x_init_rx_mode_obj(struct bnx2x *bp, + struct bnx2x_rx_mode_obj *o); + +/** + * Send and RX_MODE ramrod according to the provided parameters. + * + * @param bp + * @param p Command parameters + * + * @return 0 - if operation was successfull and there is no pending completions, + * positive number - if there are pending completions, + * negative - if there were errors + */ +int bnx2x_config_rx_mode(struct bnx2x *bp, + struct bnx2x_rx_mode_ramrod_params *p); + +/****************** MULTICASTS ****************/ + +void bnx2x_init_mcast_obj(struct bnx2x *bp, + struct bnx2x_mcast_obj *mcast_obj, + u8 mcast_cl_id, u32 mcast_cid, u8 func_id, + u8 engine_id, void *rdata, dma_addr_t rdata_mapping, + int state, unsigned long *pstate, + bnx2x_obj_type type); + +/** + * Configure multicast MACs list. May configure a new list + * provided in p->mcast_list (BNX2X_MCAST_CMD_ADD), clean up + * (BNX2X_MCAST_CMD_DEL) or restore (BNX2X_MCAST_CMD_RESTORE) a current + * configuration, continue to execute the pending commands + * (BNX2X_MCAST_CMD_CONT). + * + * If previous command is still pending or if number of MACs to + * configure is more that maximum number of MACs in one command, + * the current command will be enqueued to the tail of the + * pending commands list. + * + * @param bp + * @param p + * @param command to execute: BNX2X_MCAST_CMD_X + * + * @return 0 is operation was sucessfull and there are no pending completions, + * negative if there were errors, positive if there are pending + * completions. + */ +int bnx2x_config_mcast(struct bnx2x *bp, + struct bnx2x_mcast_ramrod_params *p, int cmd); + +/****************** CREDIT POOL ****************/ +void bnx2x_init_mac_credit_pool(struct bnx2x *bp, + struct bnx2x_credit_pool_obj *p, u8 func_id, + u8 func_num); +void bnx2x_init_vlan_credit_pool(struct bnx2x *bp, + struct bnx2x_credit_pool_obj *p, u8 func_id, + u8 func_num); + + +/****************** RSS CONFIGURATION ****************/ +void bnx2x_init_rss_config_obj(struct bnx2x *bp, + struct bnx2x_rss_config_obj *rss_obj, + u8 cl_id, u32 cid, u8 func_id, u8 engine_id, + void *rdata, dma_addr_t rdata_mapping, + int state, unsigned long *pstate, + bnx2x_obj_type type); + +/** + * Updates RSS configuration according to provided parameters. + * + * @param bp + * @param p + * + * @return 0 in case of success + */ +int bnx2x_config_rss(struct bnx2x *bp, + struct bnx2x_config_rss_params *p); + +/** + * Return the current ind_table configuration. + * + * @param bp + * @param ind_table buffer to fill with the current indirection + * table content. Should be at least + * T_ETH_INDIRECTION_TABLE_SIZE bytes long. + */ +void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj, + u8 *ind_table); + +#endif /* BNX2X_SP_VERBS */ diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index e535bfa0894..54c07f557ad 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -14,120 +14,11 @@ * Statistics and Link management by Yitchak Gertner * */ -#include "bnx2x_cmn.h" #include "bnx2x_stats.h" +#include "bnx2x_cmn.h" -/* Statistics */ -/**************************************************************************** -* Macros -****************************************************************************/ - -/* sum[hi:lo] += add[hi:lo] */ -#define ADD_64(s_hi, a_hi, s_lo, a_lo) \ - do { \ - s_lo += a_lo; \ - s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ - } while (0) - -/* difference = minuend - subtrahend */ -#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ - do { \ - if (m_lo < s_lo) { \ - /* underflow */ \ - d_hi = m_hi - s_hi; \ - if (d_hi > 0) { \ - /* we can 'loan' 1 */ \ - d_hi--; \ - d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ - } else { \ - /* m_hi <= s_hi */ \ - d_hi = 0; \ - d_lo = 0; \ - } \ - } else { \ - /* m_lo >= s_lo */ \ - if (m_hi < s_hi) { \ - d_hi = 0; \ - d_lo = 0; \ - } else { \ - /* m_hi >= s_hi */ \ - d_hi = m_hi - s_hi; \ - d_lo = m_lo - s_lo; \ - } \ - } \ - } while (0) - -#define UPDATE_STAT64(s, t) \ - do { \ - DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \ - diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \ - pstats->mac_stx[0].t##_hi = new->s##_hi; \ - pstats->mac_stx[0].t##_lo = new->s##_lo; \ - ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \ - pstats->mac_stx[1].t##_lo, diff.lo); \ - } while (0) - -#define UPDATE_STAT64_NIG(s, t) \ - do { \ - DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \ - diff.lo, new->s##_lo, old->s##_lo); \ - ADD_64(estats->t##_hi, diff.hi, \ - estats->t##_lo, diff.lo); \ - } while (0) - -/* sum[hi:lo] += add */ -#define ADD_EXTEND_64(s_hi, s_lo, a) \ - do { \ - s_lo += a; \ - s_hi += (s_lo < a) ? 1 : 0; \ - } while (0) - -#define UPDATE_EXTEND_STAT(s) \ - do { \ - ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \ - pstats->mac_stx[1].s##_lo, \ - new->s); \ - } while (0) - -#define UPDATE_EXTEND_TSTAT(s, t) \ - do { \ - diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \ - old_tclient->s = tclient->s; \ - ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) - -#define UPDATE_EXTEND_USTAT(s, t) \ - do { \ - diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ - old_uclient->s = uclient->s; \ - ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) - -#define UPDATE_EXTEND_XSTAT(s, t) \ - do { \ - diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \ - old_xclient->s = xclient->s; \ - ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) - -/* minuend -= subtrahend */ -#define SUB_64(m_hi, s_hi, m_lo, s_lo) \ - do { \ - DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ - } while (0) - -/* minuend[hi:lo] -= subtrahend */ -#define SUB_EXTEND_64(m_hi, m_lo, s) \ - do { \ - SUB_64(m_hi, 0, m_lo, s); \ - } while (0) - -#define SUB_EXTEND_USTAT(s, t) \ - do { \ - diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ - SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) +/* Statistics */ /* * General service functions @@ -149,12 +40,16 @@ static inline long bnx2x_hilo(u32 *hiref) * Init service functions */ - +/* Post the next statistics ramrod. Protect it with the spin in + * order to ensure the strict order between statistics ramrods + * (each ramrod has a sequence number passed in a + * bp->fw_stats_req->hdr.drv_stats_counter and ramrods must be + * sent in order). + */ static void bnx2x_storm_stats_post(struct bnx2x *bp) { if (!bp->stats_pending) { - struct common_query_ramrod_data ramrod_data = {0}; - int i, rc; + int rc; spin_lock_bh(&bp->stats_lock); @@ -163,14 +58,19 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) return; } - ramrod_data.drv_counter = bp->stats_counter++; - ramrod_data.collect_port = bp->port.pmf ? 1 : 0; - for_each_eth_queue(bp, i) - ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); + bp->fw_stats_req->hdr.drv_stats_counter = + cpu_to_le16(bp->stats_counter++); + DP(NETIF_MSG_TIMER, "Sending statistics ramrod %d\n", + bp->fw_stats_req->hdr.drv_stats_counter); + + + + /* send FW stats ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, - ((u32 *)&ramrod_data)[1], - ((u32 *)&ramrod_data)[0], 1); + U64_HI(bp->fw_stats_req_mapping), + U64_LO(bp->fw_stats_req_mapping), + NONE_CONNECTION_TYPE); if (rc == 0) bp->stats_pending = 1; @@ -230,7 +130,7 @@ static int bnx2x_stats_comp(struct bnx2x *bp) break; } cnt--; - msleep(1); + usleep_range(1000, 1000); } return 1; } @@ -338,69 +238,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, true, DMAE_COMP_GRC); - if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { - - mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM : - NIG_REG_INGRESS_BMAC0_MEM); - - /* BIGMAC_REGISTER_TX_STAT_GTPKT .. - BIGMAC_REGISTER_TX_STAT_GTBYT */ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - if (CHIP_IS_E1x(bp)) { - dmae->src_addr_lo = (mac_addr + - BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; - dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - - BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; - } else { - dmae->src_addr_lo = (mac_addr + - BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; - dmae->len = (8 + BIGMAC2_REGISTER_TX_STAT_GTBYT - - BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; - } - - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - /* BIGMAC_REGISTER_RX_STAT_GR64 .. - BIGMAC_REGISTER_RX_STAT_GRIPJ */ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_hi = 0; - if (CHIP_IS_E1x(bp)) { - dmae->src_addr_lo = (mac_addr + - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; - dmae->dst_addr_lo = - U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac1_stats, rx_stat_gr64_lo)); - dmae->dst_addr_hi = - U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac1_stats, rx_stat_gr64_lo)); - dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; - } else { - dmae->src_addr_lo = - (mac_addr + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; - dmae->dst_addr_lo = - U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac2_stats, rx_stat_gr64_lo)); - dmae->dst_addr_hi = - U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac2_stats, rx_stat_gr64_lo)); - dmae->len = (8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ - - BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; - } - - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { - + /* EMAC is special */ + if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0); /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/ @@ -445,46 +284,122 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_hi = 0; dmae->comp_val = 1; + } else { + u32 tx_src_addr_lo, rx_src_addr_lo; + u16 rx_len, tx_len; + + /* configure the params according to MAC type */ + switch (bp->link_vars.mac_type) { + case MAC_TYPE_BMAC: + mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM); + + /* BIGMAC_REGISTER_TX_STAT_GTPKT .. + BIGMAC_REGISTER_TX_STAT_GTBYT */ + if (CHIP_IS_E1x(bp)) { + tx_src_addr_lo = (mac_addr + + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + tx_len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + rx_src_addr_lo = (mac_addr + + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + rx_len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + } else { + tx_src_addr_lo = (mac_addr + + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + tx_len = (8 + BIGMAC2_REGISTER_TX_STAT_GTBYT - + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + rx_src_addr_lo = (mac_addr + + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + rx_len = (8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ - + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + } + break; + + case MAC_TYPE_UMAC: /* handled by MSTAT */ + case MAC_TYPE_XMAC: /* handled by MSTAT */ + default: + mac_addr = port ? GRCBASE_MSTAT1 : GRCBASE_MSTAT0; + tx_src_addr_lo = (mac_addr + + MSTAT_REG_TX_STAT_GTXPOK_LO) >> 2; + rx_src_addr_lo = (mac_addr + + MSTAT_REG_RX_STAT_GR64_LO) >> 2; + tx_len = sizeof(bp->slowpath-> + mac_stats.mstat_stats.stats_tx) >> 2; + rx_len = sizeof(bp->slowpath-> + mac_stats.mstat_stats.stats_rx) >> 2; + break; + } + + /* TX stats */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = tx_src_addr_lo; + dmae->src_addr_hi = 0; + dmae->len = tx_len; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + /* RX stats */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_hi = 0; + dmae->src_addr_lo = rx_src_addr_lo; + dmae->dst_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, mac_stats) + (tx_len << 2)); + dmae->dst_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, mac_stats) + (tx_len << 2)); + dmae->len = rx_len; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; } /* NIG */ + if (!CHIP_IS_E3(bp)) { + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 : + NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt0_lo)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt0_lo)); + dmae->len = (2*sizeof(u32)) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : + NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt1_lo)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt1_lo)); + dmae->len = (2*sizeof(u32)) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + } + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_PCI); dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : NIG_REG_STAT0_BRB_DISCARD) >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats)); dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats)); dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 : - NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt0_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt0_lo)); - dmae->len = (2*sizeof(u32)) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, - true, DMAE_COMP_PCI); - dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : - NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt1_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt1_lo)); - dmae->len = (2*sizeof(u32)) >> 2; dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); dmae->comp_val = DMAE_COMP_VAL; @@ -566,7 +481,8 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); @@ -580,13 +496,13 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) tx_stat_etherstatspkts512octetsto1023octets); UPDATE_STAT64(tx_stat_gt1518, tx_stat_etherstatspkts1024octetsto1522octets); - UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); - UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); - UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); - UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383); UPDATE_STAT64(tx_stat_gterr, tx_stat_dot3statsinternalmactransmiterrors); - UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl); } else { struct bmac2_stats *new = bnx2x_sp(bp, mac_stats.bmac2_stats); @@ -600,7 +516,7 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_mac_xpf); UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); @@ -614,19 +530,96 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) tx_stat_etherstatspkts512octetsto1023octets); UPDATE_STAT64(tx_stat_gt1518, tx_stat_etherstatspkts1024octetsto1522octets); - UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); - UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); - UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); - UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gt2047, tx_stat_mac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_mac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_mac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_mac_16383); UPDATE_STAT64(tx_stat_gterr, tx_stat_dot3statsinternalmactransmiterrors); - UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl); } estats->pause_frames_received_hi = - pstats->mac_stx[1].rx_stat_bmac_xpf_hi; + pstats->mac_stx[1].rx_stat_mac_xpf_hi; + estats->pause_frames_received_lo = + pstats->mac_stx[1].rx_stat_mac_xpf_lo; + + estats->pause_frames_sent_hi = + pstats->mac_stx[1].tx_stat_outxoffsent_hi; + estats->pause_frames_sent_lo = + pstats->mac_stx[1].tx_stat_outxoffsent_lo; +} + +static void bnx2x_mstat_stats_update(struct bnx2x *bp) +{ + struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); + struct bnx2x_eth_stats *estats = &bp->eth_stats; + + struct mstat_stats *new = bnx2x_sp(bp, mac_stats.mstat_stats); + + ADD_STAT64(stats_rx.rx_grerb, rx_stat_ifhcinbadoctets); + ADD_STAT64(stats_rx.rx_grfcs, rx_stat_dot3statsfcserrors); + ADD_STAT64(stats_rx.rx_grund, rx_stat_etherstatsundersizepkts); + ADD_STAT64(stats_rx.rx_grovr, rx_stat_dot3statsframestoolong); + ADD_STAT64(stats_rx.rx_grfrg, rx_stat_etherstatsfragments); + ADD_STAT64(stats_rx.rx_grxcf, rx_stat_maccontrolframesreceived); + ADD_STAT64(stats_rx.rx_grxpf, rx_stat_xoffstateentered); + ADD_STAT64(stats_rx.rx_grxpf, rx_stat_mac_xpf); + ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_outxoffsent); + ADD_STAT64(stats_tx.tx_gtxpf, tx_stat_flowcontroldone); + + + ADD_STAT64(stats_tx.tx_gt64, tx_stat_etherstatspkts64octets); + ADD_STAT64(stats_tx.tx_gt127, + tx_stat_etherstatspkts65octetsto127octets); + ADD_STAT64(stats_tx.tx_gt255, + tx_stat_etherstatspkts128octetsto255octets); + ADD_STAT64(stats_tx.tx_gt511, + tx_stat_etherstatspkts256octetsto511octets); + ADD_STAT64(stats_tx.tx_gt1023, + tx_stat_etherstatspkts512octetsto1023octets); + ADD_STAT64(stats_tx.tx_gt1518, + tx_stat_etherstatspkts1024octetsto1522octets); + ADD_STAT64(stats_tx.tx_gt2047, tx_stat_mac_2047); + + ADD_STAT64(stats_tx.tx_gt4095, tx_stat_mac_4095); + ADD_STAT64(stats_tx.tx_gt9216, tx_stat_mac_9216); + ADD_STAT64(stats_tx.tx_gt16383, tx_stat_mac_16383); + + ADD_STAT64(stats_tx.tx_gterr, + tx_stat_dot3statsinternalmactransmiterrors); + ADD_STAT64(stats_tx.tx_gtufl, tx_stat_mac_ufl); + + ADD_64(estats->etherstatspkts1024octetsto1522octets_hi, + new->stats_tx.tx_gt1518_hi, + estats->etherstatspkts1024octetsto1522octets_lo, + new->stats_tx.tx_gt1518_lo); + + ADD_64(estats->etherstatspktsover1522octets_hi, + new->stats_tx.tx_gt2047_hi, + estats->etherstatspktsover1522octets_lo, + new->stats_tx.tx_gt2047_lo); + + ADD_64(estats->etherstatspktsover1522octets_hi, + new->stats_tx.tx_gt4095_hi, + estats->etherstatspktsover1522octets_lo, + new->stats_tx.tx_gt4095_lo); + + ADD_64(estats->etherstatspktsover1522octets_hi, + new->stats_tx.tx_gt9216_hi, + estats->etherstatspktsover1522octets_lo, + new->stats_tx.tx_gt9216_lo); + + + ADD_64(estats->etherstatspktsover1522octets_hi, + new->stats_tx.tx_gt16383_hi, + estats->etherstatspktsover1522octets_lo, + new->stats_tx.tx_gt16383_lo); + + estats->pause_frames_received_hi = + pstats->mac_stx[1].rx_stat_mac_xpf_hi; estats->pause_frames_received_lo = - pstats->mac_stx[1].rx_stat_bmac_xpf_lo; + pstats->mac_stx[1].rx_stat_mac_xpf_lo; estats->pause_frames_sent_hi = pstats->mac_stx[1].tx_stat_outxoffsent_hi; @@ -702,15 +695,26 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp) u32 hi; } diff; - if (bp->link_vars.mac_type == MAC_TYPE_BMAC) + switch (bp->link_vars.mac_type) { + case MAC_TYPE_BMAC: bnx2x_bmac_stats_update(bp); + break; - else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) + case MAC_TYPE_EMAC: bnx2x_emac_stats_update(bp); + break; + + case MAC_TYPE_UMAC: + case MAC_TYPE_XMAC: + bnx2x_mstat_stats_update(bp); + break; - else { /* unreached */ + case MAC_TYPE_NONE: /* unreached */ BNX2X_ERR("stats updated by DMAE but no MAC active\n"); return -1; + + default: /* unreached */ + BNX2X_ERR("Unknown MAC type\n"); } ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo, @@ -718,9 +722,12 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp) ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo, new->brb_truncate - old->brb_truncate); - UPDATE_STAT64_NIG(egress_mac_pkt0, + if (!CHIP_IS_E3(bp)) { + UPDATE_STAT64_NIG(egress_mac_pkt0, etherstatspkts1024octetsto1522octets); - UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets); + UPDATE_STAT64_NIG(egress_mac_pkt1, + etherstatspktsover1522octets); + } memcpy(old, new, sizeof(struct nig_stats)); @@ -746,11 +753,13 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp) static int bnx2x_storm_stats_update(struct bnx2x *bp) { - struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); struct tstorm_per_port_stats *tport = - &stats->tstorm_common.port_statistics; + &bp->fw_stats_data->port.tstorm_port_statistics; + struct tstorm_per_pf_stats *tfunc = + &bp->fw_stats_data->pf.tstorm_pf_statistics; struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); struct bnx2x_eth_stats *estats = &bp->eth_stats; + struct stats_counter *counters = &bp->fw_stats_data->storm_counters; int i; u16 cur_stats_counter; @@ -761,6 +770,35 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) cur_stats_counter = bp->stats_counter - 1; spin_unlock_bh(&bp->stats_lock); + /* are storm stats valid? */ + if (le16_to_cpu(counters->xstats_counter) != cur_stats_counter) { + DP(BNX2X_MSG_STATS, "stats not updated by xstorm" + " xstorm counter (0x%x) != stats_counter (0x%x)\n", + le16_to_cpu(counters->xstats_counter), bp->stats_counter); + return -EAGAIN; + } + + if (le16_to_cpu(counters->ustats_counter) != cur_stats_counter) { + DP(BNX2X_MSG_STATS, "stats not updated by ustorm" + " ustorm counter (0x%x) != stats_counter (0x%x)\n", + le16_to_cpu(counters->ustats_counter), bp->stats_counter); + return -EAGAIN; + } + + if (le16_to_cpu(counters->cstats_counter) != cur_stats_counter) { + DP(BNX2X_MSG_STATS, "stats not updated by cstorm" + " cstorm counter (0x%x) != stats_counter (0x%x)\n", + le16_to_cpu(counters->cstats_counter), bp->stats_counter); + return -EAGAIN; + } + + if (le16_to_cpu(counters->tstats_counter) != cur_stats_counter) { + DP(BNX2X_MSG_STATS, "stats not updated by tstorm" + " tstorm counter (0x%x) != stats_counter (0x%x)\n", + le16_to_cpu(counters->tstats_counter), bp->stats_counter); + return -EAGAIN; + } + memcpy(&(fstats->total_bytes_received_hi), &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), sizeof(struct host_func_stats) - 2*sizeof(u32)); @@ -770,94 +808,84 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) estats->etherstatsoverrsizepkts_lo = 0; estats->no_buff_discard_hi = 0; estats->no_buff_discard_lo = 0; + estats->total_tpa_aggregations_hi = 0; + estats->total_tpa_aggregations_lo = 0; + estats->total_tpa_aggregated_frames_hi = 0; + estats->total_tpa_aggregated_frames_lo = 0; + estats->total_tpa_bytes_hi = 0; + estats->total_tpa_bytes_lo = 0; for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - int cl_id = fp->cl_id; - struct tstorm_per_client_stats *tclient = - &stats->tstorm_common.client_statistics[cl_id]; - struct tstorm_per_client_stats *old_tclient = &fp->old_tclient; - struct ustorm_per_client_stats *uclient = - &stats->ustorm_common.client_statistics[cl_id]; - struct ustorm_per_client_stats *old_uclient = &fp->old_uclient; - struct xstorm_per_client_stats *xclient = - &stats->xstorm_common.client_statistics[cl_id]; - struct xstorm_per_client_stats *old_xclient = &fp->old_xclient; + struct tstorm_per_queue_stats *tclient = + &bp->fw_stats_data->queue_stats[i]. + tstorm_queue_statistics; + struct tstorm_per_queue_stats *old_tclient = &fp->old_tclient; + struct ustorm_per_queue_stats *uclient = + &bp->fw_stats_data->queue_stats[i]. + ustorm_queue_statistics; + struct ustorm_per_queue_stats *old_uclient = &fp->old_uclient; + struct xstorm_per_queue_stats *xclient = + &bp->fw_stats_data->queue_stats[i]. + xstorm_queue_statistics; + struct xstorm_per_queue_stats *old_xclient = &fp->old_xclient; struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; u32 diff; - /* are storm stats valid? */ - if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) { - DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" - " xstorm counter (0x%x) != stats_counter (0x%x)\n", - i, xclient->stats_counter, cur_stats_counter + 1); - return -1; - } - if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) { - DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" - " tstorm counter (0x%x) != stats_counter (0x%x)\n", - i, tclient->stats_counter, cur_stats_counter + 1); - return -2; - } - if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) { - DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" - " ustorm counter (0x%x) != stats_counter (0x%x)\n", - i, uclient->stats_counter, cur_stats_counter + 1); - return -4; - } + DP(BNX2X_MSG_STATS, "queue[%d]: ucast_sent 0x%x, " + "bcast_sent 0x%x mcast_sent 0x%x\n", + i, xclient->ucast_pkts_sent, + xclient->bcast_pkts_sent, xclient->mcast_pkts_sent); + + DP(BNX2X_MSG_STATS, "---------------\n"); + qstats->total_broadcast_bytes_received_hi = + le32_to_cpu(tclient->rcv_bcast_bytes.hi); + qstats->total_broadcast_bytes_received_lo = + le32_to_cpu(tclient->rcv_bcast_bytes.lo); + + qstats->total_multicast_bytes_received_hi = + le32_to_cpu(tclient->rcv_mcast_bytes.hi); + qstats->total_multicast_bytes_received_lo = + le32_to_cpu(tclient->rcv_mcast_bytes.lo); + + qstats->total_unicast_bytes_received_hi = + le32_to_cpu(tclient->rcv_ucast_bytes.hi); + qstats->total_unicast_bytes_received_lo = + le32_to_cpu(tclient->rcv_ucast_bytes.lo); + + /* + * sum to total_bytes_received all + * unicast/multicast/broadcast + */ qstats->total_bytes_received_hi = - le32_to_cpu(tclient->rcv_broadcast_bytes.hi); + qstats->total_broadcast_bytes_received_hi; qstats->total_bytes_received_lo = - le32_to_cpu(tclient->rcv_broadcast_bytes.lo); + qstats->total_broadcast_bytes_received_lo; ADD_64(qstats->total_bytes_received_hi, - le32_to_cpu(tclient->rcv_multicast_bytes.hi), + qstats->total_multicast_bytes_received_hi, qstats->total_bytes_received_lo, - le32_to_cpu(tclient->rcv_multicast_bytes.lo)); + qstats->total_multicast_bytes_received_lo); ADD_64(qstats->total_bytes_received_hi, - le32_to_cpu(tclient->rcv_unicast_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(tclient->rcv_unicast_bytes.lo)); - - SUB_64(qstats->total_bytes_received_hi, - le32_to_cpu(uclient->bcast_no_buff_bytes.hi), + qstats->total_unicast_bytes_received_hi, qstats->total_bytes_received_lo, - le32_to_cpu(uclient->bcast_no_buff_bytes.lo)); - - SUB_64(qstats->total_bytes_received_hi, - le32_to_cpu(uclient->mcast_no_buff_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(uclient->mcast_no_buff_bytes.lo)); - - SUB_64(qstats->total_bytes_received_hi, - le32_to_cpu(uclient->ucast_no_buff_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(uclient->ucast_no_buff_bytes.lo)); + qstats->total_unicast_bytes_received_lo); qstats->valid_bytes_received_hi = qstats->total_bytes_received_hi; qstats->valid_bytes_received_lo = qstats->total_bytes_received_lo; - qstats->error_bytes_received_hi = - le32_to_cpu(tclient->rcv_error_bytes.hi); - qstats->error_bytes_received_lo = - le32_to_cpu(tclient->rcv_error_bytes.lo); - - ADD_64(qstats->total_bytes_received_hi, - qstats->error_bytes_received_hi, - qstats->total_bytes_received_lo, - qstats->error_bytes_received_lo); - UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, + UPDATE_EXTEND_TSTAT(rcv_ucast_pkts, total_unicast_packets_received); - UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, + UPDATE_EXTEND_TSTAT(rcv_mcast_pkts, total_multicast_packets_received); - UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, + UPDATE_EXTEND_TSTAT(rcv_bcast_pkts, total_broadcast_packets_received); - UPDATE_EXTEND_TSTAT(packets_too_big_discard, + UPDATE_EXTEND_TSTAT(pkts_too_big_discard, etherstatsoverrsizepkts); UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard); @@ -871,30 +899,78 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard); UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard); + qstats->total_broadcast_bytes_transmitted_hi = + le32_to_cpu(xclient->bcast_bytes_sent.hi); + qstats->total_broadcast_bytes_transmitted_lo = + le32_to_cpu(xclient->bcast_bytes_sent.lo); + + qstats->total_multicast_bytes_transmitted_hi = + le32_to_cpu(xclient->mcast_bytes_sent.hi); + qstats->total_multicast_bytes_transmitted_lo = + le32_to_cpu(xclient->mcast_bytes_sent.lo); + + qstats->total_unicast_bytes_transmitted_hi = + le32_to_cpu(xclient->ucast_bytes_sent.hi); + qstats->total_unicast_bytes_transmitted_lo = + le32_to_cpu(xclient->ucast_bytes_sent.lo); + /* + * sum to total_bytes_transmitted all + * unicast/multicast/broadcast + */ qstats->total_bytes_transmitted_hi = - le32_to_cpu(xclient->unicast_bytes_sent.hi); + qstats->total_unicast_bytes_transmitted_hi; qstats->total_bytes_transmitted_lo = - le32_to_cpu(xclient->unicast_bytes_sent.lo); + qstats->total_unicast_bytes_transmitted_lo; ADD_64(qstats->total_bytes_transmitted_hi, - le32_to_cpu(xclient->multicast_bytes_sent.hi), + qstats->total_broadcast_bytes_transmitted_hi, qstats->total_bytes_transmitted_lo, - le32_to_cpu(xclient->multicast_bytes_sent.lo)); + qstats->total_broadcast_bytes_transmitted_lo); ADD_64(qstats->total_bytes_transmitted_hi, - le32_to_cpu(xclient->broadcast_bytes_sent.hi), + qstats->total_multicast_bytes_transmitted_hi, qstats->total_bytes_transmitted_lo, - le32_to_cpu(xclient->broadcast_bytes_sent.lo)); + qstats->total_multicast_bytes_transmitted_lo); - UPDATE_EXTEND_XSTAT(unicast_pkts_sent, + UPDATE_EXTEND_XSTAT(ucast_pkts_sent, total_unicast_packets_transmitted); - UPDATE_EXTEND_XSTAT(multicast_pkts_sent, + UPDATE_EXTEND_XSTAT(mcast_pkts_sent, total_multicast_packets_transmitted); - UPDATE_EXTEND_XSTAT(broadcast_pkts_sent, + UPDATE_EXTEND_XSTAT(bcast_pkts_sent, total_broadcast_packets_transmitted); - old_tclient->checksum_discard = tclient->checksum_discard; - old_tclient->ttl0_discard = tclient->ttl0_discard; + UPDATE_EXTEND_TSTAT(checksum_discard, + total_packets_received_checksum_discarded); + UPDATE_EXTEND_TSTAT(ttl0_discard, + total_packets_received_ttl0_discarded); + + UPDATE_EXTEND_XSTAT(error_drop_pkts, + total_transmitted_dropped_packets_error); + + /* TPA aggregations completed */ + UPDATE_EXTEND_USTAT(coalesced_events, total_tpa_aggregations); + /* Number of network frames aggregated by TPA */ + UPDATE_EXTEND_USTAT(coalesced_pkts, + total_tpa_aggregated_frames); + /* Total number of bytes in completed TPA aggregations */ + qstats->total_tpa_bytes_lo = + le32_to_cpu(uclient->coalesced_bytes.lo); + qstats->total_tpa_bytes_hi = + le32_to_cpu(uclient->coalesced_bytes.hi); + + /* TPA stats per-function */ + ADD_64(estats->total_tpa_aggregations_hi, + qstats->total_tpa_aggregations_hi, + estats->total_tpa_aggregations_lo, + qstats->total_tpa_aggregations_lo); + ADD_64(estats->total_tpa_aggregated_frames_hi, + qstats->total_tpa_aggregated_frames_hi, + estats->total_tpa_aggregated_frames_lo, + qstats->total_tpa_aggregated_frames_lo); + ADD_64(estats->total_tpa_bytes_hi, + qstats->total_tpa_bytes_hi, + estats->total_tpa_bytes_lo, + qstats->total_tpa_bytes_lo); ADD_64(fstats->total_bytes_received_hi, qstats->total_bytes_received_hi, @@ -933,10 +1009,6 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) fstats->valid_bytes_received_lo, qstats->valid_bytes_received_lo); - ADD_64(estats->error_bytes_received_hi, - qstats->error_bytes_received_hi, - estats->error_bytes_received_lo, - qstats->error_bytes_received_lo); ADD_64(estats->etherstatsoverrsizepkts_hi, qstats->etherstatsoverrsizepkts_hi, estats->etherstatsoverrsizepkts_lo, @@ -950,9 +1022,19 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) fstats->total_bytes_received_lo, estats->rx_stat_ifhcinbadoctets_lo); + ADD_64(fstats->total_bytes_received_hi, + tfunc->rcv_error_bytes.hi, + fstats->total_bytes_received_lo, + tfunc->rcv_error_bytes.lo); + memcpy(estats, &(fstats->total_bytes_received_hi), sizeof(struct host_func_stats) - 2*sizeof(u32)); + ADD_64(estats->error_bytes_received_hi, + tfunc->rcv_error_bytes.hi, + estats->error_bytes_received_lo, + tfunc->rcv_error_bytes.lo); + ADD_64(estats->etherstatsoverrsizepkts_hi, estats->rx_stat_dot3statsframestoolong_hi, estats->etherstatsoverrsizepkts_lo, @@ -965,8 +1047,8 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) if (bp->port.pmf) { estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard); - estats->xxoverflow_discard = - le32_to_cpu(tport->xxoverflow_discard); + estats->mf_tag_discard = + le32_to_cpu(tport->mf_tag_discard); estats->brb_truncate_discard = le32_to_cpu(tport->brb_truncate_discard); estats->mac_discard = le32_to_cpu(tport->mac_discard); @@ -1023,7 +1105,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) nstats->rx_frame_errors = bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi); nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi); - nstats->rx_missed_errors = estats->xxoverflow_discard; + nstats->rx_missed_errors = 0; nstats->rx_errors = nstats->rx_length_errors + nstats->rx_over_errors + @@ -1065,10 +1147,27 @@ static void bnx2x_drv_stats_update(struct bnx2x *bp) } } +static bool bnx2x_edebug_stats_stopped(struct bnx2x *bp) +{ + u32 val; + + if (SHMEM2_HAS(bp, edebug_driver_if[1])) { + val = SHMEM2_RD(bp, edebug_driver_if[1]); + + if (val == EDEBUG_DRIVER_IF_OP_CODE_DISABLE_STAT) + return true; + } + + return false; +} + static void bnx2x_stats_update(struct bnx2x *bp) { u32 *stats_comp = bnx2x_sp(bp, stats_comp); + if (bnx2x_edebug_stats_stopped(bp)) + return; + if (*stats_comp != DMAE_COMP_VAL) return; @@ -1088,8 +1187,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) struct bnx2x_eth_stats *estats = &bp->eth_stats; int i; - printk(KERN_DEBUG "%s: brb drops %u brb truncate %u\n", - bp->dev->name, + netdev_dbg(bp->dev, "brb drops %u brb truncate %u\n", estats->brb_drop_lo, estats->brb_truncate_lo); for_each_eth_queue(bp, i) { @@ -1149,6 +1247,7 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) else dmae->opcode = bnx2x_dmae_opcode_add_comp( opcode, DMAE_COMP_PCI); + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); dmae->dst_addr_lo = bp->port.port_stx >> 2; @@ -1235,13 +1334,9 @@ static const struct { void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) { enum bnx2x_stats_state state; - if (unlikely(bp->panic)) return; - bnx2x_stats_stm[bp->stats_state][event].action(bp); - - /* Protect a state change flow */ spin_lock_bh(&bp->stats_lock); state = bp->stats_state; bp->stats_state = bnx2x_stats_stm[state][event].next_state; @@ -1297,7 +1392,7 @@ static void bnx2x_func_stats_base_init(struct bnx2x *bp) func_stx = bp->func_stx; for (vn = VN_0; vn < vn_max; vn++) { - int mb_idx = !CHIP_IS_E2(bp) ? 2*vn + BP_PORT(bp) : vn; + int mb_idx = CHIP_IS_E1x(bp) ? 2*vn + BP_PORT(bp) : vn; bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param); bnx2x_func_stats_init(bp); @@ -1339,12 +1434,97 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp) bnx2x_stats_comp(bp); } +/** + * This function will prepare the statistics ramrod data the way + * we will only have to increment the statistics counter and + * send the ramrod each time we have to. + * + * @param bp + */ +static inline void bnx2x_prep_fw_stats_req(struct bnx2x *bp) +{ + int i; + struct stats_query_header *stats_hdr = &bp->fw_stats_req->hdr; + + dma_addr_t cur_data_offset; + struct stats_query_entry *cur_query_entry; + + stats_hdr->cmd_num = bp->fw_stats_num; + stats_hdr->drv_stats_counter = 0; + + /* storm_counters struct contains the counters of completed + * statistics requests per storm which are incremented by FW + * each time it completes hadning a statistics ramrod. We will + * check these counters in the timer handler and discard a + * (statistics) ramrod completion. + */ + cur_data_offset = bp->fw_stats_data_mapping + + offsetof(struct bnx2x_fw_stats_data, storm_counters); + + stats_hdr->stats_counters_addrs.hi = + cpu_to_le32(U64_HI(cur_data_offset)); + stats_hdr->stats_counters_addrs.lo = + cpu_to_le32(U64_LO(cur_data_offset)); + + /* prepare to the first stats ramrod (will be completed with + * the counters equal to zero) - init counters to somethig different. + */ + memset(&bp->fw_stats_data->storm_counters, 0xff, + sizeof(struct stats_counter)); + + /**** Port FW statistics data ****/ + cur_data_offset = bp->fw_stats_data_mapping + + offsetof(struct bnx2x_fw_stats_data, port); + + cur_query_entry = &bp->fw_stats_req->query[BNX2X_PORT_QUERY_IDX]; + + cur_query_entry->kind = STATS_TYPE_PORT; + /* For port query index is a DONT CARE */ + cur_query_entry->index = BP_PORT(bp); + /* For port query funcID is a DONT CARE */ + cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp)); + cur_query_entry->address.hi = cpu_to_le32(U64_HI(cur_data_offset)); + cur_query_entry->address.lo = cpu_to_le32(U64_LO(cur_data_offset)); + + /**** PF FW statistics data ****/ + cur_data_offset = bp->fw_stats_data_mapping + + offsetof(struct bnx2x_fw_stats_data, pf); + + cur_query_entry = &bp->fw_stats_req->query[BNX2X_PF_QUERY_IDX]; + + cur_query_entry->kind = STATS_TYPE_PF; + /* For PF query index is a DONT CARE */ + cur_query_entry->index = BP_PORT(bp); + cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp)); + cur_query_entry->address.hi = cpu_to_le32(U64_HI(cur_data_offset)); + cur_query_entry->address.lo = cpu_to_le32(U64_LO(cur_data_offset)); + + /**** Clients' queries ****/ + cur_data_offset = bp->fw_stats_data_mapping + + offsetof(struct bnx2x_fw_stats_data, queue_stats); + + for_each_eth_queue(bp, i) { + cur_query_entry = + &bp->fw_stats_req-> + query[BNX2X_FIRST_QUEUE_QUERY_IDX + i]; + + cur_query_entry->kind = STATS_TYPE_QUEUE; + cur_query_entry->index = bnx2x_stats_id(&bp->fp[i]); + cur_query_entry->funcID = cpu_to_le16(BP_FUNC(bp)); + cur_query_entry->address.hi = + cpu_to_le32(U64_HI(cur_data_offset)); + cur_query_entry->address.lo = + cpu_to_le32(U64_LO(cur_data_offset)); + + cur_data_offset += sizeof(struct per_queue_stats); + } +} + void bnx2x_stats_init(struct bnx2x *bp) { - int port = BP_PORT(bp); + int /*abs*/port = BP_PORT(bp); int mb_idx = BP_FW_MB_IDX(bp); int i; - struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); bp->stats_pending = 0; bp->executer_idx = 0; @@ -1362,45 +1542,35 @@ void bnx2x_stats_init(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "port_stx 0x%x func_stx 0x%x\n", bp->port.port_stx, bp->func_stx); + port = BP_PORT(bp); /* port stats */ memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); bp->port.old_nig_stats.brb_discard = REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); bp->port.old_nig_stats.brb_truncate = REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38); - REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, - &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); - REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, - &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); + if (!CHIP_IS_E3(bp)) { + REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, + &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); + REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, + &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); + } /* function stats */ for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - memset(&fp->old_tclient, 0, - sizeof(struct tstorm_per_client_stats)); - memset(&fp->old_uclient, 0, - sizeof(struct ustorm_per_client_stats)); - memset(&fp->old_xclient, 0, - sizeof(struct xstorm_per_client_stats)); - memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); + memset(&fp->old_tclient, 0, sizeof(fp->old_tclient)); + memset(&fp->old_uclient, 0, sizeof(fp->old_uclient)); + memset(&fp->old_xclient, 0, sizeof(fp->old_xclient)); + memset(&fp->eth_q_stats, 0, sizeof(fp->eth_q_stats)); } - /* FW stats are currently collected for ETH clients only */ - for_each_eth_queue(bp, i) { - /* Set initial stats counter in the stats ramrod data to -1 */ - int cl_id = bp->fp[i].cl_id; - - stats->xstorm_common.client_statistics[cl_id]. - stats_counter = 0xffff; - stats->ustorm_common.client_statistics[cl_id]. - stats_counter = 0xffff; - stats->tstorm_common.client_statistics[cl_id]. - stats_counter = 0xffff; - } + /* Prepare statistics ramrod data */ + bnx2x_prep_fw_stats_req(bp); - memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); - memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); + memset(&bp->dev->stats, 0, sizeof(bp->dev->stats)); + memset(&bp->eth_stats, 0, sizeof(bp->eth_stats)); bp->stats_state = STATS_STATE_DISABLED; diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h index 45d14d8bc1a..5d8ce2f6afe 100644 --- a/drivers/net/bnx2x/bnx2x_stats.h +++ b/drivers/net/bnx2x/bnx2x_stats.h @@ -14,48 +14,11 @@ * Statistics and Link management by Yitchak Gertner * */ - #ifndef BNX2X_STATS_H #define BNX2X_STATS_H #include -struct bnx2x_eth_q_stats { - u32 total_bytes_received_hi; - u32 total_bytes_received_lo; - u32 total_bytes_transmitted_hi; - u32 total_bytes_transmitted_lo; - u32 total_unicast_packets_received_hi; - u32 total_unicast_packets_received_lo; - u32 total_multicast_packets_received_hi; - u32 total_multicast_packets_received_lo; - u32 total_broadcast_packets_received_hi; - u32 total_broadcast_packets_received_lo; - u32 total_unicast_packets_transmitted_hi; - u32 total_unicast_packets_transmitted_lo; - u32 total_multicast_packets_transmitted_hi; - u32 total_multicast_packets_transmitted_lo; - u32 total_broadcast_packets_transmitted_hi; - u32 total_broadcast_packets_transmitted_lo; - u32 valid_bytes_received_hi; - u32 valid_bytes_received_lo; - - u32 error_bytes_received_hi; - u32 error_bytes_received_lo; - u32 etherstatsoverrsizepkts_hi; - u32 etherstatsoverrsizepkts_lo; - u32 no_buff_discard_hi; - u32 no_buff_discard_lo; - - u32 driver_xoff; - u32 rx_err_discard_pkt; - u32 rx_skb_alloc_failed; - u32 hw_csum_err; -}; - -#define Q_STATS_OFFSET32(stat_name) \ - (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) - struct nig_stats { u32 brb_discard; u32 brb_packet; @@ -212,7 +175,7 @@ struct bnx2x_eth_stats { u32 brb_truncate_lo; u32 mac_filter_discard; - u32 xxoverflow_discard; + u32 mf_tag_discard; u32 brb_truncate_discard; u32 mac_discard; @@ -222,16 +185,197 @@ struct bnx2x_eth_stats { u32 hw_csum_err; u32 nig_timer_max; + + /* TPA */ + u32 total_tpa_aggregations_hi; + u32 total_tpa_aggregations_lo; + u32 total_tpa_aggregated_frames_hi; + u32 total_tpa_aggregated_frames_lo; + u32 total_tpa_bytes_hi; + u32 total_tpa_bytes_lo; +}; + + +struct bnx2x_eth_q_stats { + u32 total_unicast_bytes_received_hi; + u32 total_unicast_bytes_received_lo; + u32 total_broadcast_bytes_received_hi; + u32 total_broadcast_bytes_received_lo; + u32 total_multicast_bytes_received_hi; + u32 total_multicast_bytes_received_lo; + u32 total_bytes_received_hi; + u32 total_bytes_received_lo; + u32 total_unicast_bytes_transmitted_hi; + u32 total_unicast_bytes_transmitted_lo; + u32 total_broadcast_bytes_transmitted_hi; + u32 total_broadcast_bytes_transmitted_lo; + u32 total_multicast_bytes_transmitted_hi; + u32 total_multicast_bytes_transmitted_lo; + u32 total_bytes_transmitted_hi; + u32 total_bytes_transmitted_lo; + u32 total_unicast_packets_received_hi; + u32 total_unicast_packets_received_lo; + u32 total_multicast_packets_received_hi; + u32 total_multicast_packets_received_lo; + u32 total_broadcast_packets_received_hi; + u32 total_broadcast_packets_received_lo; + u32 total_unicast_packets_transmitted_hi; + u32 total_unicast_packets_transmitted_lo; + u32 total_multicast_packets_transmitted_hi; + u32 total_multicast_packets_transmitted_lo; + u32 total_broadcast_packets_transmitted_hi; + u32 total_broadcast_packets_transmitted_lo; + u32 valid_bytes_received_hi; + u32 valid_bytes_received_lo; + + u32 etherstatsoverrsizepkts_hi; + u32 etherstatsoverrsizepkts_lo; + u32 no_buff_discard_hi; + u32 no_buff_discard_lo; + + u32 driver_xoff; + u32 rx_err_discard_pkt; + u32 rx_skb_alloc_failed; + u32 hw_csum_err; + + u32 total_packets_received_checksum_discarded_hi; + u32 total_packets_received_checksum_discarded_lo; + u32 total_packets_received_ttl0_discarded_hi; + u32 total_packets_received_ttl0_discarded_lo; + u32 total_transmitted_dropped_packets_error_hi; + u32 total_transmitted_dropped_packets_error_lo; + + /* TPA */ + u32 total_tpa_aggregations_hi; + u32 total_tpa_aggregations_lo; + u32 total_tpa_aggregated_frames_hi; + u32 total_tpa_aggregated_frames_lo; + u32 total_tpa_bytes_hi; + u32 total_tpa_bytes_lo; }; -#define STATS_OFFSET32(stat_name) \ - (offsetof(struct bnx2x_eth_stats, stat_name) / 4) +/**************************************************************************** +* Macros +****************************************************************************/ + +/* sum[hi:lo] += add[hi:lo] */ +#define ADD_64(s_hi, a_hi, s_lo, a_lo) \ + do { \ + s_lo += a_lo; \ + s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ + } while (0) + +/* difference = minuend - subtrahend */ +#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ + do { \ + if (m_lo < s_lo) { \ + /* underflow */ \ + d_hi = m_hi - s_hi; \ + if (d_hi > 0) { \ + /* we can 'loan' 1 */ \ + d_hi--; \ + d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ + } else { \ + /* m_hi <= s_hi */ \ + d_hi = 0; \ + d_lo = 0; \ + } \ + } else { \ + /* m_lo >= s_lo */ \ + if (m_hi < s_hi) { \ + d_hi = 0; \ + d_lo = 0; \ + } else { \ + /* m_hi >= s_hi */ \ + d_hi = m_hi - s_hi; \ + d_lo = m_lo - s_lo; \ + } \ + } \ + } while (0) + +#define UPDATE_STAT64(s, t) \ + do { \ + DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \ + diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \ + pstats->mac_stx[0].t##_hi = new->s##_hi; \ + pstats->mac_stx[0].t##_lo = new->s##_lo; \ + ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \ + pstats->mac_stx[1].t##_lo, diff.lo); \ + } while (0) + +#define UPDATE_STAT64_NIG(s, t) \ + do { \ + DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \ + diff.lo, new->s##_lo, old->s##_lo); \ + ADD_64(estats->t##_hi, diff.hi, \ + estats->t##_lo, diff.lo); \ + } while (0) + +/* sum[hi:lo] += add */ +#define ADD_EXTEND_64(s_hi, s_lo, a) \ + do { \ + s_lo += a; \ + s_hi += (s_lo < a) ? 1 : 0; \ + } while (0) + +#define ADD_STAT64(diff, t) \ + do { \ + ADD_64(pstats->mac_stx[1].t##_hi, new->diff##_hi, \ + pstats->mac_stx[1].t##_lo, new->diff##_lo); \ + } while (0) + +#define UPDATE_EXTEND_STAT(s) \ + do { \ + ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \ + pstats->mac_stx[1].s##_lo, \ + new->s); \ + } while (0) + +#define UPDATE_EXTEND_TSTAT(s, t) \ + do { \ + diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \ + old_tclient->s = tclient->s; \ + ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + +#define UPDATE_EXTEND_USTAT(s, t) \ + do { \ + diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ + old_uclient->s = uclient->s; \ + ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + +#define UPDATE_EXTEND_XSTAT(s, t) \ + do { \ + diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \ + old_xclient->s = xclient->s; \ + ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + +/* minuend -= subtrahend */ +#define SUB_64(m_hi, s_hi, m_lo, s_lo) \ + do { \ + DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ + } while (0) + +/* minuend[hi:lo] -= subtrahend */ +#define SUB_EXTEND_64(m_hi, m_lo, s) \ + do { \ + SUB_64(m_hi, 0, m_lo, s); \ + } while (0) + +#define SUB_EXTEND_USTAT(s, t) \ + do { \ + diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ + SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + -/* Forward declaration */ +/* forward */ struct bnx2x; void bnx2x_stats_init(struct bnx2x *bp); -extern const u32 dmae_reg_go_c[]; +void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); #endif /* BNX2X_STATS_H */ diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 07f1b13c8dc..e66c3d9ab2c 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1,6 +1,6 @@ /* cnic.c: Broadcom CNIC core network driver. * - * Copyright (c) 2006-2010 Broadcom Corporation + * Copyright (c) 2006-2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -836,7 +836,6 @@ static void cnic_free_resc(struct cnic_dev *dev) cp->ctx_blks = 0; cnic_free_dma(dev, &cp->gbl_buf_info); - cnic_free_dma(dev, &cp->conn_buf_info); cnic_free_dma(dev, &cp->kwq_info); cnic_free_dma(dev, &cp->kwq_16_data_info); cnic_free_dma(dev, &cp->kcq2.dma); @@ -1176,7 +1175,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->iscsi_start_cid = start_cid; cp->fcoe_start_cid = start_cid + MAX_ISCSI_TBL_SZ; - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { cp->max_cid_space += BNX2X_FCOE_NUM_CONNECTIONS; cp->fcoe_init_cid = ethdev->fcoe_init_cid; if (!cp->fcoe_init_cid) @@ -1232,18 +1231,12 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) if (ret) goto error; - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { - ret = cnic_alloc_kcq(dev, &cp->kcq2, false); + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { + ret = cnic_alloc_kcq(dev, &cp->kcq2, true); if (ret) goto error; } - pages = PAGE_ALIGN(BNX2X_ISCSI_NUM_CONNECTIONS * - BNX2X_ISCSI_CONN_BUF_SIZE) / PAGE_SIZE; - ret = cnic_alloc_dma(dev, &cp->conn_buf_info, pages, 1); - if (ret) - goto error; - pages = PAGE_ALIGN(BNX2X_ISCSI_GLB_BUF_SIZE) / PAGE_SIZE; ret = cnic_alloc_dma(dev, &cp->gbl_buf_info, pages, 0); if (ret) @@ -1610,6 +1603,7 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], struct iscsi_context *ictx; struct regpair context_addr; int i, j, n = 2, n_max; + u8 port = CNIC_PORT(cp); ctx->ctx_flags = 0; if (!req2->num_additional_wqes) @@ -1661,6 +1655,17 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA; ictx->xstorm_st_context.iscsi.flags.flags |= XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T; + ictx->xstorm_st_context.common.ethernet.reserved_vlan_type = + ETH_P_8021Q; + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id) && + cp->port_mode == CHIP_2_PORT_MODE) { + + port = 0; + } + ictx->xstorm_st_context.common.flags = + 1 << XSTORM_COMMON_CONTEXT_SECTION_PHYSQ_INITIALIZED_SHIFT; + ictx->xstorm_st_context.common.flags = + port << XSTORM_COMMON_CONTEXT_SECTION_PBF_PORT_SHIFT; ictx->tstorm_st_context.iscsi.hdr_bytes_2_fetch = ISCSI_HEADER_SIZE; /* TSTORM requires the base address of RQ DB & not PTE */ @@ -1876,8 +1881,11 @@ static int cnic_bnx2x_destroy_ramrod(struct cnic_dev *dev, u32 l5_cid) ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, hw_cid, NONE_CONNECTION_TYPE, &l5_data); - if (ret == 0) + if (ret == 0) { wait_event(ctx->waitq, ctx->wait_cond); + if (unlikely(test_bit(CTX_FL_CID_ERROR, &ctx->ctx_flags))) + return -EBUSY; + } return ret; } @@ -1912,8 +1920,10 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) skip_cfc_delete: cnic_free_bnx2x_conn_resc(dev, l5_cid); - atomic_dec(&cp->iscsi_conn); - clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); + if (!ret) { + atomic_dec(&cp->iscsi_conn); + clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); + } destroy_reply: memset(&kcqe, 0, sizeof(kcqe)); @@ -1972,8 +1982,6 @@ static void cnic_init_storm_conn_bufs(struct cnic_dev *dev, tstorm_buf->ka_interval = kwqe3->ka_interval; tstorm_buf->ka_max_probe_count = kwqe3->ka_max_probe_count; } - tstorm_buf->rcv_buf = kwqe3->rcv_buf; - tstorm_buf->snd_buf = kwqe3->snd_buf; tstorm_buf->max_rt_time = 0xffffffff; } @@ -2002,15 +2010,14 @@ static void cnic_init_bnx2x_mac(struct cnic_dev *dev) TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, mac[4]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[3]); + TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfid), mac[3]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, + TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, mac[2]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 2, - mac[1]); + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[1]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 3, + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, mac[0]); } @@ -2189,7 +2196,7 @@ static int cnic_bnx2x_fcoe_stat(struct cnic_dev *dev, struct kwqe *kwqe) memset(fcoe_stat, 0, sizeof(*fcoe_stat)); memcpy(&fcoe_stat->stat_kwqe, req, sizeof(*req)); - ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_STAT, cid, + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_STAT_FUNC, cid, FCOE_CONNECTION_TYPE, &l5_data); return ret; } @@ -2234,12 +2241,9 @@ static int cnic_bnx2x_fcoe_init1(struct cnic_dev *dev, struct kwqe *wqes[], memcpy(&fcoe_init->init_kwqe1, req1, sizeof(*req1)); memcpy(&fcoe_init->init_kwqe2, req2, sizeof(*req2)); memcpy(&fcoe_init->init_kwqe3, req3, sizeof(*req3)); - fcoe_init->eq_addr.lo = cp->kcq2.dma.pg_map_arr[0] & 0xffffffff; - fcoe_init->eq_addr.hi = (u64) cp->kcq2.dma.pg_map_arr[0] >> 32; - fcoe_init->eq_next_page_addr.lo = - cp->kcq2.dma.pg_map_arr[1] & 0xffffffff; - fcoe_init->eq_next_page_addr.hi = - (u64) cp->kcq2.dma.pg_map_arr[1] >> 32; + fcoe_init->eq_pbl_base.lo = cp->kcq2.dma.pgtbl_map & 0xffffffff; + fcoe_init->eq_pbl_base.hi = (u64) cp->kcq2.dma.pgtbl_map >> 32; + fcoe_init->eq_pbl_size = cp->kcq2.dma.num_pages; fcoe_init->sb_num = cp->status_blk_num; fcoe_init->eq_prod = MAX_KCQ_IDX; @@ -2247,7 +2251,7 @@ static int cnic_bnx2x_fcoe_init1(struct cnic_dev *dev, struct kwqe *wqes[], cp->kcq2.sw_prod_idx = 0; cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); - ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_INIT, cid, + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_INIT_FUNC, cid, FCOE_CONNECTION_TYPE, &l5_data); *work = 3; return ret; @@ -2463,7 +2467,7 @@ static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); memset(&l5_data, 0, sizeof(l5_data)); - ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_DESTROY, cid, + ret = cnic_submit_kwqe_16(dev, FCOE_RAMROD_CMD_ID_DESTROY_FUNC, cid, FCOE_CONNECTION_TYPE, &l5_data); return ret; } @@ -2544,7 +2548,7 @@ static int cnic_submit_bnx2x_fcoe_kwqes(struct cnic_dev *dev, if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) return -EAGAIN; /* bnx2 is down */ - if (BNX2X_CHIP_NUM(cp->chip_id) == BNX2X_CHIP_NUM_57710) + if (!BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) return -EINVAL; for (i = 0; i < num_wqes; ) { @@ -2935,7 +2939,7 @@ static void cnic_service_bnx2x_bh(unsigned long data) CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - if (!BNX2X_CHIP_IS_E2(cp->chip_id)) { + if (!BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, status_idx, IGU_INT_ENABLE, 1); break; @@ -3054,13 +3058,21 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info) break; } case CNIC_CTL_COMPLETION_CMD: { - u32 cid = BNX2X_SW_CID(info->data.comp.cid); + struct cnic_ctl_completion *comp = &info->data.comp; + u32 cid = BNX2X_SW_CID(comp->cid); u32 l5_cid; struct cnic_local *cp = dev->cnic_priv; if (cnic_get_l5_cid(cp, cid, &l5_cid) == 0) { struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; + if (unlikely(comp->error)) { + set_bit(CTX_FL_CID_ERROR, &ctx->ctx_flags); + netdev_err(dev->netdev, + "CID %x CFC delete comp error %x\n", + cid, comp->error); + } + ctx->wait_cond = 1; wake_up(&ctx->waitq); } @@ -3935,10 +3947,17 @@ static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) for (i = 0; i < cp->max_cid_space; i++) { struct cnic_context *ctx = &cp->ctx_tbl[i]; + int j; while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) msleep(10); + for (j = 0; j < 5; j++) { + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + break; + msleep(20); + } + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) netdev_warn(dev->netdev, "CID %x not deleted\n", ctx->cid); @@ -4005,6 +4024,7 @@ static void cnic_delete_task(struct work_struct *work) for (i = 0; i < cp->max_cid_space; i++) { struct cnic_context *ctx = &cp->ctx_tbl[i]; + int err; if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags) || !test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) @@ -4018,13 +4038,15 @@ static void cnic_delete_task(struct work_struct *work) if (!test_and_clear_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) continue; - cnic_bnx2x_destroy_ramrod(dev, i); + err = cnic_bnx2x_destroy_ramrod(dev, i); cnic_free_bnx2x_conn_resc(dev, i); - if (ctx->ulp_proto_id == CNIC_ULP_ISCSI) - atomic_dec(&cp->iscsi_conn); + if (!err) { + if (ctx->ulp_proto_id == CNIC_ULP_ISCSI) + atomic_dec(&cp->iscsi_conn); - clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); + clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); + } } if (need_resched) @@ -4620,7 +4642,7 @@ static void cnic_enable_bnx2x_int(struct cnic_dev *dev) CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) + offsetof(struct hc_status_block_data_e1x, index_data) + sizeof(struct hc_index_data)*HC_INDEX_ISCSI_EQ_CONS + - offsetof(struct hc_index_data, timeout), 64 / 12); + offsetof(struct hc_index_data, timeout), 64 / 4); cnic_storm_memset_hc_disable(dev, sb_id, HC_INDEX_ISCSI_EQ_CONS, 0); } @@ -4636,7 +4658,6 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) udev->l2_ring; dma_addr_t buf_map, ring_map = udev->l2_ring_map; struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; - int port = CNIC_PORT(cp); int i; u32 cli = cp->ethdev->iscsi_l2_client_id; u32 val; @@ -4677,10 +4698,9 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, /* reset xstorm per client statistics */ if (cli < MAX_STAT_COUNTER_ID) { - val = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); - for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) - CNIC_WR(dev, val + i * 4, 0); + data->general.statistics_zero_flg = 1; + data->general.statistics_en_flg = 1; + data->general.statistics_counter_id = cli; } cp->tx_cons_ptr = @@ -4698,7 +4718,6 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, (udev->l2_ring + (2 * BCM_PAGE_SIZE)); struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int i; - int port = CNIC_PORT(cp); u32 cli = cp->ethdev->iscsi_l2_client_id; int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); u32 val; @@ -4706,10 +4725,10 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, /* General data */ data->general.client_id = cli; - data->general.statistics_en_flg = 1; - data->general.statistics_counter_id = cli; data->general.activate_flg = 1; data->general.sp_client_id = cli; + data->general.mtu = cpu_to_le16(cp->l2_single_buf_size - 14); + data->general.func_id = cp->pfid; for (i = 0; i < BNX2X_MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; @@ -4743,23 +4762,12 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, data->rx.status_block_id = BNX2X_DEF_SB_ID; data->rx.cache_line_alignment_log_size = L1_CACHE_SHIFT; - data->rx.bd_buff_size = cpu_to_le16(cp->l2_single_buf_size); - data->rx.mtu = cpu_to_le16(cp->l2_single_buf_size - 14); + data->rx.max_bytes_on_bd = cpu_to_le16(cp->l2_single_buf_size); data->rx.outer_vlan_removal_enable_flg = 1; - - /* reset tstorm and ustorm per client statistics */ - if (cli < MAX_STAT_COUNTER_ID) { - val = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); - for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) - CNIC_WR(dev, val + i * 4, 0); - - val = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); - for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) - CNIC_WR(dev, val + i * 4, 0); - } + data->rx.silent_vlan_removal_flg = 1; + data->rx.silent_vlan_value = 0; + data->rx.silent_vlan_mask = 0xffff; cp->rx_cons_ptr = &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS]; @@ -4775,7 +4783,7 @@ static void cnic_init_bnx2x_kcq(struct cnic_dev *dev) CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); cp->kcq1.sw_prod_idx = 0; - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { struct host_hc_status_block_e2 *sb = cp->status_blk.gen; cp->kcq1.hw_prod_idx_ptr = @@ -4791,7 +4799,7 @@ static void cnic_init_bnx2x_kcq(struct cnic_dev *dev) &sb->sb.running_index[SM_RX_ID]; } - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { struct host_hc_status_block_e2 *sb = cp->status_blk.gen; cp->kcq2.io_addr = BAR_USTRORM_INTMEM + @@ -4808,10 +4816,12 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; - int func = CNIC_FUNC(cp), ret, i; + int func = CNIC_FUNC(cp), ret; u32 pfid; - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + cp->port_mode = CHIP_PORT_MODE_NONE; + + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { u32 val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR); if (!(val & 1)) @@ -4819,10 +4829,13 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) else val = (val >> 1) & 1; - if (val) + if (val) { + cp->port_mode = CHIP_4_PORT_MODE; cp->pfid = func >> 1; - else + } else { + cp->port_mode = CHIP_4_PORT_MODE; cp->pfid = func & 0x6; + } } else { cp->pfid = func; } @@ -4834,7 +4847,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (ret) return -ENOMEM; - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { ret = cnic_init_id_tbl(&cp->fcoe_cid_tbl, BNX2X_FCOE_NUM_CONNECTIONS, cp->fcoe_start_cid, 0); @@ -4871,15 +4884,6 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfid, 0), HC_INDEX_ISCSI_EQ_CONS); - for (i = 0; i < cp->conn_buf_info.num_pages; i++) { - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i), - cp->conn_buf_info.pgtbl[2 * i]); - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i) + 4, - cp->conn_buf_info.pgtbl[(2 * i) + 1]); - } - CNIC_WR(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid), cp->gbl_buf_info.pg_map_arr[0] & 0xffffffff); @@ -4927,7 +4931,7 @@ static void cnic_init_rings(struct cnic_dev *dev) cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); off = BAR_USTRORM_INTMEM + - (BNX2X_CHIP_IS_E2(cp->chip_id) ? + (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id) ? USTORM_RX_PRODS_E2_OFFSET(cl_qzone_id) : USTORM_RX_PRODS_E1X_OFFSET(CNIC_PORT(cp), cli)); @@ -5277,7 +5281,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) if (!(ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)) cdev->max_iscsi_conn = ethdev->max_iscsi_conn; - if (BNX2X_CHIP_IS_E2(cp->chip_id) && + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id) && !(ethdev->drv_state & CNIC_DRV_STATE_NO_FCOE)) cdev->max_fcoe_conn = ethdev->max_fcoe_conn; @@ -5293,7 +5297,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) cp->stop_cm = cnic_cm_stop_bnx2x_hw; cp->enable_int = cnic_enable_bnx2x_int; cp->disable_int_sync = cnic_disable_bnx2x_int_sync; - if (BNX2X_CHIP_IS_E2(cp->chip_id)) + if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) cp->ack_int = cnic_ack_bnx2x_e2_msix; else cp->ack_int = cnic_ack_bnx2x_msix; diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index eb11821108a..330ef935041 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -1,6 +1,6 @@ /* cnic.h: Broadcom CNIC core network driver. * - * Copyright (c) 2006-2010 Broadcom Corporation + * Copyright (c) 2006-2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -68,11 +68,6 @@ #define BNX2_PG_CTX_MAP 0x1a0034 #define BNX2_ISCSI_CTX_MAP 0x1a0074 -struct cnic_redirect_entry { - struct dst_entry *old_dst; - struct dst_entry *new_dst; -}; - #define MAX_COMPLETED_KCQE 64 #define MAX_CNIC_L5_CONTEXT 256 @@ -171,6 +166,7 @@ struct cnic_context { unsigned long ctx_flags; #define CTX_FL_OFFLD_START 0 #define CTX_FL_DELETE_WAIT 1 +#define CTX_FL_CID_ERROR 2 u8 ulp_proto_id; union { struct cnic_iscsi *iscsi; @@ -245,7 +241,7 @@ struct cnic_local { u16 rx_cons; u16 tx_cons; - struct iro *iro_arr; + const struct iro *iro_arr; #define IRO (((struct cnic_local *) dev->cnic_priv)->iro_arr) struct cnic_dma kwq_info; @@ -286,7 +282,6 @@ struct cnic_local { struct cnic_sock *csk_tbl; struct cnic_id_tbl csk_port_tbl; - struct cnic_dma conn_buf_info; struct cnic_dma gbl_buf_info; struct cnic_iscsi *iscsi_tbl; @@ -320,6 +315,11 @@ struct cnic_local { u32 chip_id; int func; u32 pfid; + u8 port_mode; +#define CHIP_4_PORT_MODE 0 +#define CHIP_2_PORT_MODE 1 +#define CHIP_PORT_MODE_NONE 2 + u32 shmem_base; struct cnic_ops *cnic_ops; @@ -369,7 +369,6 @@ struct bnx2x_bd_chain_next { #define BNX2X_ISCSI_MAX_PENDING_R2TS 4 #define BNX2X_ISCSI_R2TQE_SIZE 8 #define BNX2X_ISCSI_HQ_BD_SIZE 64 -#define BNX2X_ISCSI_CONN_BUF_SIZE 64 #define BNX2X_ISCSI_GLB_BUF_SIZE 64 #define BNX2X_ISCSI_PBL_NOT_CACHED 0xff #define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED 0xff @@ -406,6 +405,7 @@ struct bnx2x_bd_chain_next { #define BNX2X_CHIP_IS_E2(x) \ (BNX2X_CHIP_IS_57712(x) || BNX2X_CHIP_IS_57712E(x) || \ BNX2X_CHIP_IS_57713(x) || BNX2X_CHIP_IS_57713E(x)) +#define BNX2X_CHIP_IS_E2_PLUS(x) BNX2X_CHIP_IS_E2(x) #define IS_E1H_OFFSET BNX2X_CHIP_IS_E1H(cp->chip_id) @@ -442,8 +442,8 @@ struct bnx2x_bd_chain_next { #define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_FUNC(cp) ((cp)->func) -#define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\ - (CNIC_FUNC(cp) & 1)) +#define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2_PLUS(cp->chip_id) ? \ + 0 : (CNIC_FUNC(cp) & 1)) #define CNIC_E1HVN(cp) ((cp)->pfid >> 1) #define BNX2X_HW_CID(cp, x) ((CNIC_PORT(cp) << 23) | \ @@ -452,10 +452,15 @@ struct bnx2x_bd_chain_next { #define BNX2X_SW_CID(x) (x & 0x1ffff) #define BNX2X_CL_QZONE_ID(cp, cli) \ - (cli + (CNIC_PORT(cp) * (BNX2X_CHIP_IS_E2(cp->chip_id) ?\ - ETH_MAX_RX_CLIENTS_E2 : \ - ETH_MAX_RX_CLIENTS_E1H))) + (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id) ? cli : \ + cli + (CNIC_PORT(cp) * ETH_MAX_RX_CLIENTS_E1H)) + +#ifndef MAX_STAT_COUNTER_ID +#define MAX_STAT_COUNTER_ID \ + (BNX2X_CHIP_IS_E1H((cp)->chip_id) ? MAX_STAT_COUNTER_ID_E1H : \ + ((BNX2X_CHIP_IS_E2_PLUS((cp)->chip_id)) ? MAX_STAT_COUNTER_ID_E2 :\ + MAX_STAT_COUNTER_ID_E1)) +#endif -#define TCP_TSTORM_OOO_DROP_AND_PROC_ACK (0<<4) #endif diff --git a/drivers/net/cnic_defs.h b/drivers/net/cnic_defs.h index fdbc0041560..e47d2107676 100644 --- a/drivers/net/cnic_defs.h +++ b/drivers/net/cnic_defs.h @@ -1,7 +1,7 @@ /* cnic.c: Broadcom CNIC core network driver. * - * Copyright (c) 2006-2010 Broadcom Corporation + * Copyright (c) 2006-2009 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,13 +45,13 @@ #define FCOE_KCQE_OPCODE_CQ_EVENT_NOTIFICATION (0x20) #define FCOE_KCQE_OPCODE_FCOE_ERROR (0x21) -#define FCOE_RAMROD_CMD_ID_INIT (FCOE_KCQE_OPCODE_INIT_FUNC) -#define FCOE_RAMROD_CMD_ID_DESTROY (FCOE_KCQE_OPCODE_DESTROY_FUNC) +#define FCOE_RAMROD_CMD_ID_INIT_FUNC (FCOE_KCQE_OPCODE_INIT_FUNC) +#define FCOE_RAMROD_CMD_ID_DESTROY_FUNC (FCOE_KCQE_OPCODE_DESTROY_FUNC) +#define FCOE_RAMROD_CMD_ID_STAT_FUNC (FCOE_KCQE_OPCODE_STAT_FUNC) #define FCOE_RAMROD_CMD_ID_OFFLOAD_CONN (FCOE_KCQE_OPCODE_OFFLOAD_CONN) #define FCOE_RAMROD_CMD_ID_ENABLE_CONN (FCOE_KCQE_OPCODE_ENABLE_CONN) #define FCOE_RAMROD_CMD_ID_DISABLE_CONN (FCOE_KCQE_OPCODE_DISABLE_CONN) #define FCOE_RAMROD_CMD_ID_DESTROY_CONN (FCOE_KCQE_OPCODE_DESTROY_CONN) -#define FCOE_RAMROD_CMD_ID_STAT (FCOE_KCQE_OPCODE_STAT_FUNC) #define FCOE_RAMROD_CMD_ID_TERMINATE_CONN (0x81) #define FCOE_KWQE_OPCODE_INIT1 (0) @@ -641,20 +641,20 @@ struct cstorm_iscsi_ag_context { #define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12 #define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13) #define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14 +#define __CSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<14) +#define __CSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 14 #define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16) #define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16 #define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18) #define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22 +#define __CSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN (0x1<<19) +#define __CSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN_SHIFT 19 +#define __CSTORM_ISCSI_AG_CONTEXT_AUX2_CF_EN (0x1<<20) +#define __CSTORM_ISCSI_AG_CONTEXT_AUX2_CF_EN_SHIFT 20 +#define __CSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<21) +#define __CSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 21 +#define __CSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<22) +#define __CSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 22 #define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23) #define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23 #define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26) @@ -694,573 +694,667 @@ struct cstorm_iscsi_ag_context { #endif #if defined(__BIG_ENDIAN) u16 __reserved64; - u16 __cq_u_prod0; + u16 cq_u_prod; #elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod0; + u16 cq_u_prod; u16 __reserved64; #endif u32 __cq_u_prod1; #if defined(__BIG_ENDIAN) u16 __agg_vars3; - u16 __cq_u_prod2; + u16 cq_u_pend; #elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod2; + u16 cq_u_pend; u16 __agg_vars3; #endif #if defined(__BIG_ENDIAN) u16 __aux2_th; - u16 __cq_u_prod3; + u16 aux2_val; #elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod3; + u16 aux2_val; u16 __aux2_th; #endif }; /* - * Parameters initialized during offloaded according to FLOGI/PLOGI/PRLI and used in FCoE context section + * The fcoe extra aggregative context section of Tstorm */ -struct ustorm_fcoe_params { +struct tstorm_fcoe_extra_ag_context_section { + u32 __agg_val1; #if defined(__BIG_ENDIAN) - u16 fcoe_conn_id; - u16 flags; -#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0) -#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0 -#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1) -#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1 -#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2) -#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2 -#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3) -#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3 -#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4) -#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4 -#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5) -#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5 -#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6) -#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6 -#define USTORM_FCOE_PARAMS_B_C2_VALID (0x1<<7) -#define USTORM_FCOE_PARAMS_B_C2_VALID_SHIFT 7 -#define USTORM_FCOE_PARAMS_B_ACK_0 (0x1<<8) -#define USTORM_FCOE_PARAMS_B_ACK_0_SHIFT 8 -#define USTORM_FCOE_PARAMS_RSRV0 (0x7F<<9) -#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 9 + u8 __tcp_agg_vars2; + u8 __agg_val3; + u16 __agg_val2; #elif defined(__LITTLE_ENDIAN) - u16 flags; -#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0) -#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0 -#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1) -#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1 -#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2) -#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2 -#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3) -#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3 -#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4) -#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4 -#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5) -#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5 -#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6) -#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6 -#define USTORM_FCOE_PARAMS_B_C2_VALID (0x1<<7) -#define USTORM_FCOE_PARAMS_B_C2_VALID_SHIFT 7 -#define USTORM_FCOE_PARAMS_B_ACK_0 (0x1<<8) -#define USTORM_FCOE_PARAMS_B_ACK_0_SHIFT 8 -#define USTORM_FCOE_PARAMS_RSRV0 (0x7F<<9) -#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 9 - u16 fcoe_conn_id; + u16 __agg_val2; + u8 __agg_val3; + u8 __tcp_agg_vars2; #endif #if defined(__BIG_ENDIAN) - u8 hc_csdm_byte_en; - u8 func_id; - u8 port_id; - u8 vnic_id; + u16 __agg_val5; + u8 __agg_val6; + u8 __tcp_agg_vars3; #elif defined(__LITTLE_ENDIAN) - u8 vnic_id; - u8 port_id; - u8 func_id; - u8 hc_csdm_byte_en; + u8 __tcp_agg_vars3; + u8 __agg_val6; + u16 __agg_val5; #endif + u32 __lcq_prod; + u32 rtt_seq; + u32 rtt_time; + u32 __reserved66; + u32 wnd_right_edge; + u32 tcp_agg_vars1; +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 0 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG (0x1<<1) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG_SHIFT 1 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF (0x3<<2) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_SHIFT 2 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF (0x3<<4) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_SHIFT 4 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN (0x1<<6) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN_SHIFT 6 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN (0x1<<7) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN_SHIFT 7 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN (0x1<<8) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN_SHIFT 8 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN (0x1<<9) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN_SHIFT 9 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<10) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 10 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG (0x1<<11) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG_SHIFT 11 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN (0x1<<12) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN_SHIFT 12 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN (0x1<<13) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN_SHIFT 13 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF (0x3<<14) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_SHIFT 14 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF (0x3<<16) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_SHIFT 16 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED (0x1<<18) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED_SHIFT 18 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<19) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 19 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN (0x1<<20) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN_SHIFT 20 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN (0x1<<21) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN_SHIFT 21 +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1 (0x3<<22) +#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1_SHIFT 22 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ (0xF<<24) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ_SHIFT 24 +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ (0xF<<28) +#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ_SHIFT 28 + u32 snd_max; + u32 __lcq_cons; + u32 __reserved2; +}; + +/* + * The fcoe aggregative context of Tstorm + */ +struct tstorm_fcoe_ag_context { #if defined(__BIG_ENDIAN) - u16 rx_total_conc_seqs; - u16 rx_max_fc_pay_len; + u16 ulp_credit; + u8 agg_vars1; +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7 + u8 state; #elif defined(__LITTLE_ENDIAN) - u16 rx_max_fc_pay_len; - u16 rx_total_conc_seqs; + u8 state; + u8 agg_vars1; +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7 + u16 ulp_credit; #endif #if defined(__BIG_ENDIAN) - u16 ox_id; - u16 rx_max_conc_seqs; + u16 __agg_val4; + u16 agg_vars2; +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2 +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11 +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12) +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13) +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14) +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15) +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 #elif defined(__LITTLE_ENDIAN) - u16 rx_max_conc_seqs; - u16 ox_id; + u16 agg_vars2; +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1 +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2) +#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2 +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4) +#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6) +#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8 +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10) +#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10 +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11) +#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11 +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12) +#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13) +#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14) +#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15) +#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 + u16 __agg_val4; #endif + struct tstorm_fcoe_extra_ag_context_section __extra_section; }; -/* - * FCoE 16-bits index structure - */ -struct fcoe_idx16_fields { - u16 fields; -#define FCOE_IDX16_FIELDS_IDX (0x7FFF<<0) -#define FCOE_IDX16_FIELDS_IDX_SHIFT 0 -#define FCOE_IDX16_FIELDS_MSB (0x1<<15) -#define FCOE_IDX16_FIELDS_MSB_SHIFT 15 -}; -/* - * FCoE 16-bits index union - */ -union fcoe_idx16_field_union { - struct fcoe_idx16_fields fields; - u16 val; -}; /* - * 4 regs size + * The tcp aggregative context section of Tstorm */ -struct fcoe_bd_ctx { - u32 buf_addr_hi; - u32 buf_addr_lo; +struct tstorm_tcp_tcp_ag_context_section { + u32 __agg_val1; #if defined(__BIG_ENDIAN) - u16 rsrv0; - u16 buf_len; + u8 __tcp_agg_vars2; + u8 __agg_val3; + u16 __agg_val2; #elif defined(__LITTLE_ENDIAN) - u16 buf_len; - u16 rsrv0; + u16 __agg_val2; + u8 __agg_val3; + u8 __tcp_agg_vars2; #endif #if defined(__BIG_ENDIAN) - u16 rsrv1; - u16 flags; + u16 __agg_val5; + u8 __agg_val6; + u8 __tcp_agg_vars3; #elif defined(__LITTLE_ENDIAN) - u16 flags; - u16 rsrv1; + u8 __tcp_agg_vars3; + u8 __agg_val6; + u16 __agg_val5; #endif + u32 snd_nxt; + u32 rtt_seq; + u32 rtt_time; + u32 __reserved66; + u32 wnd_right_edge; + u32 tcp_agg_vars1; +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 0 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG (0x1<<1) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG_SHIFT 1 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF (0x3<<2) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_SHIFT 2 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF (0x3<<4) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_SHIFT 4 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_EN (0x1<<6) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_EN_SHIFT 6 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_EN (0x1<<7) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_EN_SHIFT 7 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN (0x1<<8) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN_SHIFT 8 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_SND_NXT_EN (0x1<<9) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_SND_NXT_EN_SHIFT 9 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<10) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 10 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_FLAG (0x1<<11) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_FLAG_SHIFT 11 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_EN (0x1<<12) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_EN_SHIFT 12 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_EN (0x1<<13) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_EN_SHIFT 13 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF (0x3<<14) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_SHIFT 14 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF (0x3<<16) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_SHIFT 16 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_BLOCKED (0x1<<18) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_BLOCKED_SHIFT 18 +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<19) +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 19 +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_EN (0x1<<20) +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_EN_SHIFT 20 +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_EN (0x1<<21) +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_EN_SHIFT 21 +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED1 (0x3<<22) +#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED1_SHIFT 22 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ (0xF<<24) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ_SHIFT 24 +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ (0xF<<28) +#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ_SHIFT 28 + u32 snd_max; + u32 snd_una; + u32 __reserved2; }; -/* - * Parameters required for placement according to SGL - */ -struct ustorm_fcoe_data_place { -#if defined(__BIG_ENDIAN) - u16 cached_sge_off; - u8 cached_num_sges; - u8 cached_sge_idx; -#elif defined(__LITTLE_ENDIAN) - u8 cached_sge_idx; - u8 cached_num_sges; - u16 cached_sge_off; -#endif - struct fcoe_bd_ctx cached_sge[3]; -}; - -struct fcoe_task_ctx_entry_txwr_rxrd { +/* + * The iscsi aggregative context of Tstorm + */ +struct tstorm_iscsi_ag_context { #if defined(__BIG_ENDIAN) - u16 verify_tx_seq; - u8 init_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6 - u8 tx_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4 + u16 ulp_credit; + u8 agg_vars1; +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 + u8 state; #elif defined(__LITTLE_ENDIAN) - u8 tx_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4 - u8 init_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6 - u16 verify_tx_seq; + u8 state; + u8 agg_vars1; +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 + u16 ulp_credit; +#endif +#if defined(__BIG_ENDIAN) + u16 __agg_val4; + u16 agg_vars2; +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 +#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) +#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 +#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) +#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 +#elif defined(__LITTLE_ENDIAN) + u16 agg_vars2; +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) +#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 +#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) +#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 +#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) +#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 + u16 __agg_val4; #endif + struct tstorm_tcp_tcp_ag_context_section tcp; }; -struct fcoe_fcp_cmd_payload { - u32 opaque[8]; -}; -struct fcoe_fc_hdr { + +/* + * The fcoe aggregative context of Ustorm + */ +struct ustorm_fcoe_ag_context { #if defined(__BIG_ENDIAN) - u8 cs_ctl; - u8 s_id[3]; + u8 __aux_counter_flags; + u8 agg_vars2; +#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 + u8 agg_vars1; +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4) +#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6 + u8 state; #elif defined(__LITTLE_ENDIAN) - u8 s_id[3]; - u8 cs_ctl; + u8 state; + u8 agg_vars1; +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4) +#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6 + u8 agg_vars2; +#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2 +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) +#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 + u8 __aux_counter_flags; #endif #if defined(__BIG_ENDIAN) - u8 r_ctl; - u8 d_id[3]; + u8 cdu_usage; + u8 agg_misc2; + u16 pbf_tx_seq_ack; #elif defined(__LITTLE_ENDIAN) - u8 d_id[3]; - u8 r_ctl; + u16 pbf_tx_seq_ack; + u8 agg_misc2; + u8 cdu_usage; #endif + u32 agg_misc4; #if defined(__BIG_ENDIAN) - u8 seq_id; - u8 df_ctl; - u16 seq_cnt; + u8 agg_val3_th; + u8 agg_val3; + u16 agg_misc3; #elif defined(__LITTLE_ENDIAN) - u16 seq_cnt; - u8 df_ctl; - u8 seq_id; + u16 agg_misc3; + u8 agg_val3; + u8 agg_val3_th; #endif + u32 expired_task_id; + u32 agg_misc4_th; #if defined(__BIG_ENDIAN) - u8 type; - u8 f_ctl[3]; + u16 cq_prod; + u16 cq_cons; #elif defined(__LITTLE_ENDIAN) - u8 f_ctl[3]; - u8 type; + u16 cq_cons; + u16 cq_prod; #endif - u32 parameters; #if defined(__BIG_ENDIAN) - u16 ox_id; - u16 rx_id; -#elif defined(__LITTLE_ENDIAN) - u16 rx_id; - u16 ox_id; -#endif -}; - -struct fcoe_fc_frame { - struct fcoe_fc_hdr fc_hdr; - u32 reserved0[2]; -}; - -union fcoe_cmd_flow_info { - struct fcoe_fcp_cmd_payload fcp_cmd_payload; - struct fcoe_fc_frame mp_fc_frame; -}; - -struct fcoe_read_flow_info { - struct fcoe_fc_hdr fc_data_in_hdr; - u32 reserved[2]; -}; - -struct fcoe_fcp_xfr_rdy_payload { - u32 burst_len; - u32 data_ro; -}; - -struct fcoe_write_flow_info { - struct fcoe_fc_hdr fc_data_out_hdr; - struct fcoe_fcp_xfr_rdy_payload fcp_xfr_payload; -}; - -struct fcoe_fcp_rsp_flags { - u8 flags; -#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID (0x1<<0) -#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID_SHIFT 0 -#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID (0x1<<1) -#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID_SHIFT 1 -#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER (0x1<<2) -#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER_SHIFT 2 -#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER (0x1<<3) -#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER_SHIFT 3 -#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ (0x1<<4) -#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ_SHIFT 4 -#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS (0x7<<5) -#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS_SHIFT 5 -}; - -struct fcoe_fcp_rsp_payload { - struct regpair reserved0; - u32 fcp_resid; -#if defined(__BIG_ENDIAN) - u16 retry_delay_timer; - struct fcoe_fcp_rsp_flags fcp_flags; - u8 scsi_status_code; + u16 __reserved2; + u8 decision_rules; +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0) +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6) +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7 + u8 decision_rule_enable_bits; +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4) +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5) +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5 +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6) +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 #elif defined(__LITTLE_ENDIAN) - u8 scsi_status_code; - struct fcoe_fcp_rsp_flags fcp_flags; - u16 retry_delay_timer; + u8 decision_rule_enable_bits; +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0 +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) +#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2) +#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2 +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3) +#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4) +#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4 +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5) +#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5 +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6) +#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 + u8 decision_rules; +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0) +#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0 +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) +#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6) +#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6 +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7) +#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7 + u16 __reserved2; #endif - u32 fcp_rsp_len; - u32 fcp_sns_len; -}; - -/* - * Fixed size structure in order to plant it in Union structure - */ -struct fcoe_fcp_rsp_union { - struct fcoe_fcp_rsp_payload payload; - struct regpair reserved0; -}; - -/* - * Fixed size structure in order to plant it in Union structure - */ -struct fcoe_abts_rsp_union { - u32 r_ctl; - u32 abts_rsp_payload[7]; -}; - -union fcoe_rsp_flow_info { - struct fcoe_fcp_rsp_union fcp_rsp; - struct fcoe_abts_rsp_union abts_rsp; }; -struct fcoe_cleanup_flow_info { -#if defined(__BIG_ENDIAN) - u16 reserved1; - u16 task_id; -#elif defined(__LITTLE_ENDIAN) - u16 task_id; - u16 reserved1; -#endif - u32 reserved2[7]; -}; /* - * 32 bytes used for general purposes + * The iscsi aggregative context of Ustorm */ -union fcoe_general_task_ctx { - union fcoe_cmd_flow_info cmd_info; - struct fcoe_read_flow_info read_info; - struct fcoe_write_flow_info write_info; - union fcoe_rsp_flow_info rsp_info; - struct fcoe_cleanup_flow_info cleanup_info; - u32 comp_info[8]; -}; - -struct fcoe_s_stat_ctx { - u8 flags; -#define FCOE_S_STAT_CTX_ACTIVE (0x1<<0) -#define FCOE_S_STAT_CTX_ACTIVE_SHIFT 0 -#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND (0x1<<1) -#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND_SHIFT 1 -#define FCOE_S_STAT_CTX_ABTS_PERFORMED (0x1<<2) -#define FCOE_S_STAT_CTX_ABTS_PERFORMED_SHIFT 2 -#define FCOE_S_STAT_CTX_SEQ_TIMEOUT (0x1<<3) -#define FCOE_S_STAT_CTX_SEQ_TIMEOUT_SHIFT 3 -#define FCOE_S_STAT_CTX_P_RJT (0x1<<4) -#define FCOE_S_STAT_CTX_P_RJT_SHIFT 4 -#define FCOE_S_STAT_CTX_ACK_EOFT (0x1<<5) -#define FCOE_S_STAT_CTX_ACK_EOFT_SHIFT 5 -#define FCOE_S_STAT_CTX_RSRV1 (0x3<<6) -#define FCOE_S_STAT_CTX_RSRV1_SHIFT 6 -}; - -/* - * Common section. Both TX and RX processing might write and read from it in different flows - */ -struct fcoe_task_ctx_entry_tx_rx_cmn { - u32 data_2_trns; - union fcoe_general_task_ctx general; -#if defined(__BIG_ENDIAN) - u16 tx_low_seq_cnt; - struct fcoe_s_stat_ctx tx_s_stat; - u8 tx_seq_id; -#elif defined(__LITTLE_ENDIAN) - u8 tx_seq_id; - struct fcoe_s_stat_ctx tx_s_stat; - u16 tx_low_seq_cnt; -#endif - u32 common_flags; -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID (0xFFFFFF<<0) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID (0x1<<24) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID_SHIFT 24 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT (0x1<<25) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT_SHIFT 25 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER (0x1<<26) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER_SHIFT 26 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF (0x1<<27) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF_SHIFT 27 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME (0x1<<28) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME_SHIFT 28 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV (0x7<<29) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV_SHIFT 29 -}; - -struct fcoe_task_ctx_entry_rxwr_txrd { -#if defined(__BIG_ENDIAN) - u16 rx_id; - u16 rx_flags; -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9 -#elif defined(__LITTLE_ENDIAN) - u16 rx_flags; -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9 - u16 rx_id; -#endif -}; - -struct fcoe_seq_ctx { -#if defined(__BIG_ENDIAN) - u16 low_seq_cnt; - struct fcoe_s_stat_ctx s_stat; - u8 seq_id; -#elif defined(__LITTLE_ENDIAN) - u8 seq_id; - struct fcoe_s_stat_ctx s_stat; - u16 low_seq_cnt; -#endif -#if defined(__BIG_ENDIAN) - u16 err_seq_cnt; - u16 high_seq_cnt; -#elif defined(__LITTLE_ENDIAN) - u16 high_seq_cnt; - u16 err_seq_cnt; -#endif - u32 low_exp_ro; - u32 high_exp_ro; -}; - -struct fcoe_single_sge_ctx { - struct regpair cur_buf_addr; +struct ustorm_iscsi_ag_context { #if defined(__BIG_ENDIAN) - u16 reserved0; - u16 cur_buf_rem; + u8 __aux_counter_flags; + u8 agg_vars2; +#define USTORM_ISCSI_AG_CONTEXT_TX_CF (0x3<<0) +#define USTORM_ISCSI_AG_CONTEXT_TX_CF_SHIFT 0 +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF (0x3<<2) +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_SHIFT 2 +#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) +#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 + u8 agg_vars1; +#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define USTORM_ISCSI_AG_CONTEXT_INV_CF (0x3<<4) +#define USTORM_ISCSI_AG_CONTEXT_INV_CF_SHIFT 4 +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF (0x3<<6) +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_SHIFT 6 + u8 state; #elif defined(__LITTLE_ENDIAN) - u16 cur_buf_rem; - u16 reserved0; + u8 state; + u8 agg_vars1; +#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define USTORM_ISCSI_AG_CONTEXT_INV_CF (0x3<<4) +#define USTORM_ISCSI_AG_CONTEXT_INV_CF_SHIFT 4 +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF (0x3<<6) +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_SHIFT 6 + u8 agg_vars2; +#define USTORM_ISCSI_AG_CONTEXT_TX_CF (0x3<<0) +#define USTORM_ISCSI_AG_CONTEXT_TX_CF_SHIFT 0 +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF (0x3<<2) +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_SHIFT 2 +#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) +#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 + u8 __aux_counter_flags; #endif -}; - -struct fcoe_mul_sges_ctx { - struct regpair cur_sge_addr; #if defined(__BIG_ENDIAN) - u8 sgl_size; - u8 cur_sge_idx; - u16 cur_sge_off; + u8 cdu_usage; + u8 agg_misc2; + u16 __cq_local_comp_itt_val; #elif defined(__LITTLE_ENDIAN) - u16 cur_sge_off; - u8 cur_sge_idx; - u8 sgl_size; + u16 __cq_local_comp_itt_val; + u8 agg_misc2; + u8 cdu_usage; #endif -}; - -union fcoe_sgl_ctx { - struct fcoe_single_sge_ctx single_sge; - struct fcoe_mul_sges_ctx mul_sges; -}; - -struct fcoe_task_ctx_entry_rx_only { - struct fcoe_seq_ctx seq_ctx; - struct fcoe_seq_ctx ooo_seq_ctx; - u32 rsrv3; - union fcoe_sgl_ctx sgl_ctx; -}; - -struct ustorm_fcoe_task_ctx_entry_rd { - struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd; - struct fcoe_task_ctx_entry_tx_rx_cmn cmn; - struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd; - struct fcoe_task_ctx_entry_rx_only rx_wr; - u32 reserved; -}; - -/* - * Ustorm FCoE Storm Context - */ -struct ustorm_fcoe_st_context { - struct ustorm_fcoe_params fcoe_params; - struct regpair task_addr; - struct regpair cq_base_addr; - struct regpair rq_pbl_base; - struct regpair rq_cur_page_addr; - struct regpair confq_pbl_base_addr; - struct regpair conn_db_base; - struct regpair xfrq_base_addr; - struct regpair lcq_base_addr; + u32 agg_misc4; #if defined(__BIG_ENDIAN) - union fcoe_idx16_field_union rq_cons; - union fcoe_idx16_field_union rq_prod; + u8 agg_val3_th; + u8 agg_val3; + u16 agg_misc3; #elif defined(__LITTLE_ENDIAN) - union fcoe_idx16_field_union rq_prod; - union fcoe_idx16_field_union rq_cons; + u16 agg_misc3; + u8 agg_val3; + u8 agg_val3_th; #endif + u32 agg_val1; + u32 agg_misc4_th; #if defined(__BIG_ENDIAN) - u16 xfrq_prod; - u16 cq_cons; + u16 agg_val2_th; + u16 agg_val2; #elif defined(__LITTLE_ENDIAN) - u16 cq_cons; - u16 xfrq_prod; + u16 agg_val2; + u16 agg_val2_th; #endif #if defined(__BIG_ENDIAN) - u16 lcq_cons; - u16 hc_cram_address; -#elif defined(__LITTLE_ENDIAN) - u16 hc_cram_address; - u16 lcq_cons; -#endif -#if defined(__BIG_ENDIAN) - u16 sq_xfrq_lcq_confq_size; - u16 confq_prod; -#elif defined(__LITTLE_ENDIAN) - u16 confq_prod; - u16 sq_xfrq_lcq_confq_size; -#endif -#if defined(__BIG_ENDIAN) - u8 hc_csdm_agg_int; - u8 flags; -#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG (0x1<<0) -#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG_SHIFT 0 -#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG (0x1<<1) -#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG_SHIFT 1 -#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG (0x1<<2) -#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG_SHIFT 2 -#define USTORM_FCOE_ST_CONTEXT_RSRV1 (0x1F<<3) -#define USTORM_FCOE_ST_CONTEXT_RSRV1_SHIFT 3 - u8 available_rqes; - u8 sp_q_flush_cnt; + u16 __reserved2; + u8 decision_rules; +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE (0x7<<0) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) +#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 + u8 decision_rule_enable_bits; +#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN (0x1<<0) +#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN_SHIFT 0 +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 +#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN (0x1<<2) +#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN_SHIFT 2 +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN (0x1<<3) +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 +#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN (0x1<<4) +#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN_SHIFT 4 +#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<5) +#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 5 +#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<6) +#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 +#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 #elif defined(__LITTLE_ENDIAN) - u8 sp_q_flush_cnt; - u8 available_rqes; - u8 flags; -#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG (0x1<<0) -#define USTORM_FCOE_ST_CONTEXT_MID_SEQ_PROC_FLAG_SHIFT 0 -#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG (0x1<<1) -#define USTORM_FCOE_ST_CONTEXT_CACHED_CONN_FLAG_SHIFT 1 -#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG (0x1<<2) -#define USTORM_FCOE_ST_CONTEXT_CACHED_TCE_FLAG_SHIFT 2 -#define USTORM_FCOE_ST_CONTEXT_RSRV1 (0x1F<<3) -#define USTORM_FCOE_ST_CONTEXT_RSRV1_SHIFT 3 - u8 hc_csdm_agg_int; + u8 decision_rule_enable_bits; +#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN (0x1<<0) +#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN_SHIFT 0 +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) +#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 +#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN (0x1<<2) +#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN_SHIFT 2 +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN (0x1<<3) +#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 +#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN (0x1<<4) +#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN_SHIFT 4 +#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<5) +#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 5 +#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<6) +#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 +#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 + u8 decision_rules; +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE (0x7<<0) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) +#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) +#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 + u16 __reserved2; #endif - struct ustorm_fcoe_data_place data_place; - struct ustorm_fcoe_task_ctx_entry_rd tce; }; -/* - * The FCoE non-aggregative context of Tstorm - */ -struct tstorm_fcoe_st_context { - struct regpair reserved0; - struct regpair reserved1; -}; /* * The fcoe aggregative context section of Xstorm @@ -1272,8 +1366,8 @@ struct xstorm_fcoe_extra_ag_context_section { #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51_SHIFT 0 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2 -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF (0x3<<4) -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_SHIFT 4 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF (0x3<<4) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_SHIFT 4 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN (0x1<<6) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN_SHIFT 6 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG (0x1<<7) @@ -1288,20 +1382,20 @@ struct xstorm_fcoe_extra_ag_context_section { #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED51_SHIFT 0 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2 -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF (0x3<<4) -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_SHIFT 4 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF (0x3<<4) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_SHIFT 4 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN (0x1<<6) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_CLEAR_DA_TIMER_EN_SHIFT 6 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG (0x1<<7) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG_SHIFT 7 #endif - u32 __task_addr_lo; - u32 __task_addr_hi; + u32 snd_nxt; + u32 tx_wnd; u32 __reserved55; - u32 __tx_prods; + u32 local_adv_wnd; #if defined(__BIG_ENDIAN) u8 __agg_val8_th; - u8 __agg_val8; + u8 __tx_dest; u16 tcp_agg_vars2; #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57 (0x1<<0) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57_SHIFT 0 @@ -1317,8 +1411,8 @@ struct xstorm_fcoe_extra_ag_context_section { #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60_SHIFT 5 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN (0x1<<6) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN_SHIFT 6 -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN (0x1<<7) -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN_SHIFT 7 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN (0x1<<7) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN_SHIFT 7 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN (0x1<<8) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN_SHIFT 8 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) @@ -1327,8 +1421,8 @@ struct xstorm_fcoe_extra_ag_context_section { #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 -#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14) -#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14 +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF (0x3<<14) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF_SHIFT 14 #elif defined(__LITTLE_ENDIAN) u16 tcp_agg_vars2; #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED57 (0x1<<0) @@ -1345,8 +1439,8 @@ struct xstorm_fcoe_extra_ag_context_section { #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED60_SHIFT 5 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN (0x1<<6) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_ACK_TO_FE_UPDATED_EN_SHIFT 6 -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN (0x1<<7) -#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_PBF_TX_SEQ_ACK_CF_EN_SHIFT 7 +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN (0x1<<7) +#define XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN_SHIFT 7 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN (0x1<<8) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_TX_FIN_FLAG_EN_SHIFT 8 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) @@ -1355,9 +1449,9 @@ struct xstorm_fcoe_extra_ag_context_section { #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 -#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14) -#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14 - u8 __agg_val8; +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF (0x3<<14) +#define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF_SHIFT 14 + u8 __tx_dest; u8 __agg_val8_th; #endif u32 __sq_base_addr_lo; @@ -1591,9 +1685,9 @@ struct xstorm_fcoe_ag_context { #if defined(__BIG_ENDIAN) u8 __reserved1; u8 __agg_val6_th; - u16 __confq_tx_prod; + u16 __agg_val9; #elif defined(__LITTLE_ENDIAN) - u16 __confq_tx_prod; + u16 __agg_val9; u8 __agg_val6_th; u8 __reserved1; #endif @@ -1605,16 +1699,16 @@ struct xstorm_fcoe_ag_context { u16 confq_cons; #endif u32 agg_vars8; -#define __XSTORM_FCOE_AG_CONTEXT_CACHE_WQE_IDX (0xFFFFFF<<0) -#define __XSTORM_FCOE_AG_CONTEXT_CACHE_WQE_IDX_SHIFT 0 +#define XSTORM_FCOE_AG_CONTEXT_AGG_MISC2 (0xFFFFFF<<0) +#define XSTORM_FCOE_AG_CONTEXT_AGG_MISC2_SHIFT 0 #define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3 (0xFF<<24) #define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3_SHIFT 24 #if defined(__BIG_ENDIAN) - u16 ox_id; + u16 agg_misc0; u16 sq_prod; #elif defined(__LITTLE_ENDIAN) u16 sq_prod; - u16 ox_id; + u16 agg_misc0; #endif #if defined(__BIG_ENDIAN) u8 agg_val3; @@ -1628,1696 +1722,1691 @@ struct xstorm_fcoe_ag_context { u8 agg_val3; #endif #if defined(__BIG_ENDIAN) - u16 __pbf_tx_seq_ack; + u16 __agg_misc1; u16 agg_limit1; #elif defined(__LITTLE_ENDIAN) u16 agg_limit1; - u16 __pbf_tx_seq_ack; + u16 __agg_misc1; #endif u32 completion_seq; u32 confq_pbl_base_lo; u32 confq_pbl_base_hi; }; + + /* - * The fcoe extra aggregative context section of Tstorm + * The tcp aggregative context section of Xstorm */ -struct tstorm_fcoe_extra_ag_context_section { - u32 __agg_val1; +struct xstorm_tcp_tcp_ag_context_section { #if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars2; - u8 __agg_val3; - u16 __agg_val2; + u8 tcp_agg_vars1; +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_DA_TIMER_CF (0x3<<0) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_DA_TIMER_CF_SHIFT 0 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2 +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF (0x3<<4) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_SHIFT 4 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CLEAR_DA_TIMER_EN (0x1<<6) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CLEAR_DA_TIMER_EN_SHIFT 6 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_EXPIRATION_FLAG (0x1<<7) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_EXPIRATION_FLAG_SHIFT 7 + u8 __da_cnt; + u16 mss; #elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u8 __agg_val3; - u8 __tcp_agg_vars2; + u16 mss; + u8 __da_cnt; + u8 tcp_agg_vars1; +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_DA_TIMER_CF (0x3<<0) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_DA_TIMER_CF_SHIFT 0 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED (0x3<<2) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_SHIFT 2 +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF (0x3<<4) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_SHIFT 4 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CLEAR_DA_TIMER_EN (0x1<<6) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CLEAR_DA_TIMER_EN_SHIFT 6 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_EXPIRATION_FLAG (0x1<<7) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_EXPIRATION_FLAG_SHIFT 7 #endif + u32 snd_nxt; + u32 tx_wnd; + u32 snd_una; + u32 local_adv_wnd; #if defined(__BIG_ENDIAN) - u16 __agg_val5; - u8 __agg_val6; - u8 __tcp_agg_vars3; + u8 __agg_val8_th; + u8 __tx_dest; + u16 tcp_agg_vars2; +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG (0x1<<0) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_SHIFT 0 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED (0x1<<1) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED_SHIFT 1 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE (0x1<<2) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE_SHIFT 2 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4 +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE (0x1<<5) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE_SHIFT 5 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN (0x1<<6) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN_SHIFT 6 +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN (0x1<<7) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN_SHIFT 7 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN (0x1<<8) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN_SHIFT 8 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF (0x3<<14) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF_SHIFT 14 #elif defined(__LITTLE_ENDIAN) - u8 __tcp_agg_vars3; - u8 __agg_val6; - u16 __agg_val5; + u16 tcp_agg_vars2; +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG (0x1<<0) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_SHIFT 0 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED (0x1<<1) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED_SHIFT 1 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE (0x1<<2) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE_SHIFT 2 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4 +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE (0x1<<5) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE_SHIFT 5 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN (0x1<<6) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN_SHIFT 6 +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN (0x1<<7) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SIDEBAND_SENT_CF_EN_SHIFT 7 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN (0x1<<8) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN_SHIFT 8 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF (0x3<<14) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF_SHIFT 14 + u8 __tx_dest; + u8 __agg_val8_th; #endif - u32 __lcq_prod; - u32 rtt_seq; - u32 rtt_time; - u32 __reserved66; - u32 wnd_right_edge; - u32 tcp_agg_vars1; -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 0 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG (0x1<<1) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG_SHIFT 1 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF (0x3<<2) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_SHIFT 2 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF (0x3<<4) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_SHIFT 4 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN (0x1<<6) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_WND_UPD_CF_EN_SHIFT 6 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN (0x1<<7) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TIMEOUT_CF_EN_SHIFT 7 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN (0x1<<8) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN_SHIFT 8 -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN (0x1<<9) -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_LCQ_SND_EN_SHIFT 9 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<10) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 10 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG (0x1<<11) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_FLAG_SHIFT 11 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN (0x1<<12) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_EN_SHIFT 12 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN (0x1<<13) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_EN_SHIFT 13 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF (0x3<<14) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX1_CF_SHIFT 14 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF (0x3<<16) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX2_CF_SHIFT 16 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED (0x1<<18) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_TX_BLOCKED_SHIFT 18 -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<19) -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 19 -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN (0x1<<20) -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX11_CF_EN_SHIFT 20 -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN (0x1<<21) -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_AUX12_CF_EN_SHIFT 21 -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1 (0x3<<22) -#define __TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED1_SHIFT 22 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ (0xF<<24) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ_SHIFT 24 -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ (0xF<<28) -#define TSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ_SHIFT 28 - u32 snd_max; - u32 __lcq_cons; - u32 __reserved2; -}; - -/* - * The fcoe aggregative context of Tstorm - */ -struct tstorm_fcoe_ag_context { + u32 ack_to_far_end; + u32 rto_timer; + u32 ka_timer; + u32 ts_to_echo; #if defined(__BIG_ENDIAN) - u16 ulp_credit; - u8 agg_vars1; -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4) -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4 -#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6) -#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7 - u8 state; + u16 __agg_val7_th; + u16 __agg_val7; #elif defined(__LITTLE_ENDIAN) - u8 state; - u8 agg_vars1; -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define TSTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF (0x3<<4) -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_SHIFT 4 -#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG (0x1<<6) -#define __TSTORM_FCOE_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_FLAG_SHIFT 7 - u16 ulp_credit; + u16 __agg_val7; + u16 __agg_val7_th; #endif #if defined(__BIG_ENDIAN) - u16 __agg_val4; - u16 agg_vars2; -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4 -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6) -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6 -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8) -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8 -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10) -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11) -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11 -#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 -#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14) -#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 -#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15) -#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 + u8 __tcp_agg_vars5; + u8 __tcp_agg_vars4; + u8 __tcp_agg_vars3; + u8 __force_pure_ack_cnt; #elif defined(__LITTLE_ENDIAN) - u16 agg_vars2; -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_FCOE_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_FCOE_AG_CONTEXT_AUX5_CF_SHIFT 4 -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF (0x3<<6) -#define __TSTORM_FCOE_AG_CONTEXT_AUX6_CF_SHIFT 6 -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF (0x3<<8) -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_CF_SHIFT 8 -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG (0x1<<10) -#define __TSTORM_FCOE_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN (0x1<<11) -#define __TSTORM_FCOE_AG_CONTEXT_QUEUE0_FLUSH_CF_EN_SHIFT 11 -#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_FCOE_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_FCOE_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 -#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN (0x1<<14) -#define TSTORM_FCOE_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 -#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN (0x1<<15) -#define TSTORM_FCOE_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 - u16 __agg_val4; + u8 __force_pure_ack_cnt; + u8 __tcp_agg_vars3; + u8 __tcp_agg_vars4; + u8 __tcp_agg_vars5; +#endif + u32 tcp_agg_vars6; +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_CF_EN (0x1<<0) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_CF_EN_SHIFT 0 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF_EN (0x1<<1) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_DEST_UPDATED_CF_EN_SHIFT 1 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_EN (0x1<<2) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_EN_SHIFT 2 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<3) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 3 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX6_FLAG (0x1<<4) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX6_FLAG_SHIFT 4 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX7_FLAG (0x1<<5) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX7_FLAG_SHIFT 5 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX5_CF (0x3<<6) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX5_CF_SHIFT 6 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF (0x3<<8) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_SHIFT 8 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF (0x3<<10) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_SHIFT 10 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF (0x3<<12) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_SHIFT 12 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF (0x3<<14) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_SHIFT 14 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX13_CF (0x3<<16) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX13_CF_SHIFT 16 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX14_CF (0x3<<18) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX14_CF_SHIFT 18 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX15_CF (0x3<<20) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX15_CF_SHIFT 20 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX16_CF (0x3<<22) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX16_CF_SHIFT 22 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX17_CF (0x3<<24) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX17_CF_SHIFT 24 +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ECE_FLAG (0x1<<26) +#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ECE_FLAG_SHIFT 26 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED71 (0x1<<27) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED71_SHIFT 27 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_FORCE_PURE_ACK_CNT_DIRTY (0x1<<28) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_FORCE_PURE_ACK_CNT_DIRTY_SHIFT 28 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TCP_AUTO_STOP_FLAG (0x1<<29) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TCP_AUTO_STOP_FLAG_SHIFT 29 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DO_TS_UPDATE_FLAG (0x1<<30) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DO_TS_UPDATE_FLAG_SHIFT 30 +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CANCEL_RETRANSMIT_FLAG (0x1<<31) +#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CANCEL_RETRANSMIT_FLAG_SHIFT 31 +#if defined(__BIG_ENDIAN) + u16 __agg_misc6; + u16 __tcp_agg_vars7; +#elif defined(__LITTLE_ENDIAN) + u16 __tcp_agg_vars7; + u16 __agg_misc6; +#endif + u32 __agg_val10; + u32 __agg_val10_th; +#if defined(__BIG_ENDIAN) + u16 __reserved3; + u8 __reserved2; + u8 __da_only_cnt; +#elif defined(__LITTLE_ENDIAN) + u8 __da_only_cnt; + u8 __reserved2; + u16 __reserved3; #endif - struct tstorm_fcoe_extra_ag_context_section __extra_section; }; /* - * The fcoe aggregative context of Ustorm + * The iscsi aggregative context of Xstorm */ -struct ustorm_fcoe_ag_context { +struct xstorm_iscsi_ag_context { #if defined(__BIG_ENDIAN) - u8 __aux_counter_flags; - u8 agg_vars2; -#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0) -#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0 -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2) -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2 -#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) -#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 + u16 agg_val1; u8 agg_vars1; -#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4) -#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4 -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6) -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6 +#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 +#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN (0x1<<5) +#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN_SHIFT 5 +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 +#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7) +#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7 u8 state; #elif defined(__LITTLE_ENDIAN) u8 state; u8 agg_vars1; -#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define __USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define USTORM_FCOE_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define USTORM_FCOE_AG_CONTEXT_INV_CF (0x3<<4) -#define USTORM_FCOE_AG_CONTEXT_INV_CF_SHIFT 4 -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF (0x3<<6) -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_SHIFT 6 - u8 agg_vars2; -#define USTORM_FCOE_AG_CONTEXT_TX_CF (0x3<<0) -#define USTORM_FCOE_AG_CONTEXT_TX_CF_SHIFT 0 -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF (0x3<<2) -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_SHIFT 2 -#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) -#define USTORM_FCOE_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 - u8 __aux_counter_flags; -#endif -#if defined(__BIG_ENDIAN) - u8 cdu_usage; - u8 agg_misc2; - u16 pbf_tx_seq_ack; -#elif defined(__LITTLE_ENDIAN) - u16 pbf_tx_seq_ack; - u8 agg_misc2; - u8 cdu_usage; +#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 +#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN (0x1<<5) +#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN_SHIFT 5 +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 +#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7) +#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7 + u16 agg_val1; #endif - u32 agg_misc4; #if defined(__BIG_ENDIAN) - u8 agg_val3_th; - u8 agg_val3; - u16 agg_misc3; + u8 cdu_reserved; + u8 __agg_vars4; + u8 agg_vars3; +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 + u8 agg_vars2; +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0 +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG (0x1<<3) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG_SHIFT 3 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG (0x1<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG_SHIFT 4 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1 (0x3<<5) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1_SHIFT 5 +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 #elif defined(__LITTLE_ENDIAN) - u16 agg_misc3; - u8 agg_val3; - u8 agg_val3_th; -#endif - u32 expired_task_id; - u32 agg_misc4_th; -#if defined(__BIG_ENDIAN) - u16 cq_prod; - u16 cq_cons; + u8 agg_vars2; +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0 +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG (0x1<<3) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG_SHIFT 3 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG (0x1<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG_SHIFT 4 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1 (0x3<<5) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1_SHIFT 5 +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) +#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 + u8 agg_vars3; +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 + u8 __agg_vars4; + u8 cdu_reserved; +#endif + u32 more_to_send; +#if defined(__BIG_ENDIAN) + u16 agg_vars5; +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5 (0x3<<0) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5_SHIFT 0 +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2 (0x3<<14) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2_SHIFT 14 + u16 sq_cons; #elif defined(__LITTLE_ENDIAN) - u16 cq_cons; - u16 cq_prod; + u16 sq_cons; + u16 agg_vars5; +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5 (0x3<<0) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5_SHIFT 0 +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) +#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2 (0x3<<14) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2_SHIFT 14 #endif + struct xstorm_tcp_tcp_ag_context_section tcp; #if defined(__BIG_ENDIAN) - u16 __reserved2; - u8 decision_rules; -#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0) -#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0 -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6) -#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6 -#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7) -#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7 - u8 decision_rule_enable_bits; -#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0) -#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0 -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 -#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2) -#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2 -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3) -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 -#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4) -#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4 -#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5) -#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5 -#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6) -#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 -#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) -#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 + u16 agg_vars7; +#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) +#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 +#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) +#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_SHIFT 8 +#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10) +#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN (0x1<<11) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG (0x1<<12) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG_SHIFT 12 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG (0x1<<13) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 + u8 agg_val3_th; + u8 agg_vars6; +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6_SHIFT 0 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7 (0x7<<3) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7_SHIFT 3 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4 (0x3<<6) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4_SHIFT 6 #elif defined(__LITTLE_ENDIAN) - u8 decision_rule_enable_bits; -#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN (0x1<<0) -#define __USTORM_FCOE_AG_CONTEXT_RESERVED_INV_CF_EN_SHIFT 0 -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) -#define USTORM_FCOE_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 -#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN (0x1<<2) -#define USTORM_FCOE_AG_CONTEXT_TX_CF_EN_SHIFT 2 -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN (0x1<<3) -#define __USTORM_FCOE_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 -#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN (0x1<<4) -#define __USTORM_FCOE_AG_CONTEXT_AUX1_CF_EN_SHIFT 4 -#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN (0x1<<5) -#define __USTORM_FCOE_AG_CONTEXT_QUEUE0_CF_EN_SHIFT 5 -#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN (0x1<<6) -#define __USTORM_FCOE_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 -#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN (0x1<<7) -#define __USTORM_FCOE_AG_CONTEXT_DQ_CF_EN_SHIFT 7 - u8 decision_rules; -#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE (0x7<<0) -#define USTORM_FCOE_AG_CONTEXT_CQ_DEC_RULE_SHIFT 0 -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) -#define __USTORM_FCOE_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG (0x1<<6) -#define USTORM_FCOE_AG_CONTEXT_CQ_ARM_N_FLAG_SHIFT 6 -#define __USTORM_FCOE_AG_CONTEXT_RESERVED1 (0x1<<7) -#define __USTORM_FCOE_AG_CONTEXT_RESERVED1_SHIFT 7 - u16 __reserved2; + u8 agg_vars6; +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6_SHIFT 0 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7 (0x7<<3) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7_SHIFT 3 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4 (0x3<<6) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4_SHIFT 6 + u8 agg_val3_th; + u16 agg_vars7; +#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) +#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) +#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 +#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) +#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_SHIFT 8 +#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10) +#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN (0x1<<11) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG (0x1<<12) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG_SHIFT 12 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG (0x1<<13) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 +#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) +#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 #endif -}; - -/* - * Ethernet context section - */ -struct xstorm_fcoe_eth_context_section { #if defined(__BIG_ENDIAN) - u8 remote_addr_4; - u8 remote_addr_5; - u8 local_addr_0; - u8 local_addr_1; + u16 __agg_val11_th; + u16 __gen_data; #elif defined(__LITTLE_ENDIAN) - u8 local_addr_1; - u8 local_addr_0; - u8 remote_addr_5; - u8 remote_addr_4; + u16 __gen_data; + u16 __agg_val11_th; #endif #if defined(__BIG_ENDIAN) - u8 remote_addr_0; - u8 remote_addr_1; - u8 remote_addr_2; - u8 remote_addr_3; + u8 __reserved1; + u8 __agg_val6_th; + u16 __agg_val9; #elif defined(__LITTLE_ENDIAN) - u8 remote_addr_3; - u8 remote_addr_2; - u8 remote_addr_1; - u8 remote_addr_0; + u16 __agg_val9; + u8 __agg_val6_th; + u8 __reserved1; #endif #if defined(__BIG_ENDIAN) - u16 reserved_vlan_type; - u16 params; -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12) -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12 -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 + u16 hq_prod; + u16 hq_cons; #elif defined(__LITTLE_ENDIAN) - u16 params; -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12) -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12 -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) -#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 - u16 reserved_vlan_type; + u16 hq_cons; + u16 hq_prod; #endif + u32 agg_vars8; +#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC2 (0xFFFFFF<<0) +#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC2_SHIFT 0 +#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC3 (0xFF<<24) +#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC3_SHIFT 24 #if defined(__BIG_ENDIAN) - u8 local_addr_2; - u8 local_addr_3; - u8 local_addr_4; - u8 local_addr_5; + u16 r2tq_prod; + u16 sq_prod; #elif defined(__LITTLE_ENDIAN) - u8 local_addr_5; - u8 local_addr_4; - u8 local_addr_3; - u8 local_addr_2; + u16 sq_prod; + u16 r2tq_prod; +#endif +#if defined(__BIG_ENDIAN) + u8 agg_val3; + u8 agg_val6; + u8 agg_val5_th; + u8 agg_val5; +#elif defined(__LITTLE_ENDIAN) + u8 agg_val5; + u8 agg_val5_th; + u8 agg_val6; + u8 agg_val3; +#endif +#if defined(__BIG_ENDIAN) + u16 __agg_misc1; + u16 agg_limit1; +#elif defined(__LITTLE_ENDIAN) + u16 agg_limit1; + u16 __agg_misc1; #endif + u32 hq_cons_tcp_seq; + u32 exp_stat_sn; + u32 rst_seq_num; }; + /* - * Flags used in FCoE context section - 1 byte + * The L5cm aggregative context of XStorm */ -struct xstorm_fcoe_context_flags { - u8 flags; -#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q (0x3<<0) -#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q_SHIFT 0 -#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ (0x1<<2) -#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ_SHIFT 2 -#define XSTORM_FCOE_CONTEXT_FLAGS_B_EXCHANGE_CLEANUP_DEFFERED (0x1<<3) -#define XSTORM_FCOE_CONTEXT_FLAGS_B_EXCHANGE_CLEANUP_DEFFERED_SHIFT 3 -#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT (0x1<<4) -#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT_SHIFT 4 -#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE (0x1<<5) -#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE_SHIFT 5 -#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE (0x1<<6) -#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE_SHIFT 6 -#define XSTORM_FCOE_CONTEXT_FLAGS_B_ABTS_DEFFERED (0x1<<7) -#define XSTORM_FCOE_CONTEXT_FLAGS_B_ABTS_DEFFERED_SHIFT 7 -}; - -/* - * FCoE SQ element - */ -struct fcoe_sqe { - u16 wqe; -#define FCOE_SQE_TASK_ID (0x7FFF<<0) -#define FCOE_SQE_TASK_ID_SHIFT 0 -#define FCOE_SQE_TOGGLE_BIT (0x1<<15) -#define FCOE_SQE_TOGGLE_BIT_SHIFT 15 -}; - -/* - * FCoE XFRQ element - */ -struct fcoe_xfrqe { - u16 wqe; -#define FCOE_XFRQE_TASK_ID (0x7FFF<<0) -#define FCOE_XFRQE_TASK_ID_SHIFT 0 -#define FCOE_XFRQE_TOGGLE_BIT (0x1<<15) -#define FCOE_XFRQE_TOGGLE_BIT_SHIFT 15 -}; - -/* - * FCoE SQ\XFRQ element - */ -struct fcoe_cached_wqe { +struct xstorm_l5cm_ag_context { #if defined(__BIG_ENDIAN) - struct fcoe_xfrqe xfrqe; - struct fcoe_sqe sqe; + u16 agg_val1; + u8 agg_vars1; +#define __XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __XSTORM_L5CM_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) +#define __XSTORM_L5CM_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 +#define XSTORM_L5CM_AG_CONTEXT_NAGLE_EN (0x1<<5) +#define XSTORM_L5CM_AG_CONTEXT_NAGLE_EN_SHIFT 5 +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 +#define __XSTORM_L5CM_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7) +#define __XSTORM_L5CM_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7 + u8 state; #elif defined(__LITTLE_ENDIAN) - struct fcoe_sqe sqe; - struct fcoe_xfrqe xfrqe; + u8 state; + u8 agg_vars1; +#define __XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) +#define __XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) +#define XSTORM_L5CM_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 +#define __XSTORM_L5CM_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) +#define __XSTORM_L5CM_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 +#define XSTORM_L5CM_AG_CONTEXT_NAGLE_EN (0x1<<5) +#define XSTORM_L5CM_AG_CONTEXT_NAGLE_EN_SHIFT 5 +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 +#define __XSTORM_L5CM_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7) +#define __XSTORM_L5CM_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7 + u16 agg_val1; #endif -}; - -struct fcoe_task_ctx_entry_tx_only { - union fcoe_sgl_ctx sgl_ctx; -}; - -struct xstorm_fcoe_task_ctx_entry_rd { - struct fcoe_task_ctx_entry_tx_only tx_wr; - struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd; - struct fcoe_task_ctx_entry_tx_rx_cmn cmn; - struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd; -}; - -/* - * Cached SGEs - */ -struct common_fcoe_sgl { - struct fcoe_bd_ctx sge[2]; -}; - -/* - * FCP_DATA parameters required for transmission - */ -struct xstorm_fcoe_fcp_data { - u32 io_rem; #if defined(__BIG_ENDIAN) - u16 cached_sge_off; - u8 cached_num_sges; - u8 cached_sge_idx; + u8 cdu_reserved; + u8 __agg_vars4; + u8 agg_vars3; +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 +#define __XSTORM_L5CM_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_L5CM_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 + u8 agg_vars2; +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF (0x3<<0) +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF_SHIFT 0 +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 +#define __XSTORM_L5CM_AG_CONTEXT_AUX8_FLAG (0x1<<3) +#define __XSTORM_L5CM_AG_CONTEXT_AUX8_FLAG_SHIFT 3 +#define __XSTORM_L5CM_AG_CONTEXT_AUX9_FLAG (0x1<<4) +#define __XSTORM_L5CM_AG_CONTEXT_AUX9_FLAG_SHIFT 4 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE1 (0x3<<5) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE1_SHIFT 5 +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF_EN (0x1<<7) +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF_EN_SHIFT 7 #elif defined(__LITTLE_ENDIAN) - u8 cached_sge_idx; - u8 cached_num_sges; - u16 cached_sge_off; + u8 agg_vars2; +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF (0x3<<0) +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF_SHIFT 0 +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) +#define __XSTORM_L5CM_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 +#define __XSTORM_L5CM_AG_CONTEXT_AUX8_FLAG (0x1<<3) +#define __XSTORM_L5CM_AG_CONTEXT_AUX8_FLAG_SHIFT 3 +#define __XSTORM_L5CM_AG_CONTEXT_AUX9_FLAG (0x1<<4) +#define __XSTORM_L5CM_AG_CONTEXT_AUX9_FLAG_SHIFT 4 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE1 (0x3<<5) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE1_SHIFT 5 +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF_EN (0x1<<7) +#define XSTORM_L5CM_AG_CONTEXT_AUX4_CF_EN_SHIFT 7 + u8 agg_vars3; +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 +#define __XSTORM_L5CM_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_L5CM_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 + u8 __agg_vars4; + u8 cdu_reserved; #endif - struct common_fcoe_sgl cached_sgl; -}; - -/* - * FCoE context section - */ -struct xstorm_fcoe_context_section { + u32 more_to_send; #if defined(__BIG_ENDIAN) - u8 vlan_flag; - u8 s_id[3]; -#elif defined(__LITTLE_ENDIAN) - u8 s_id[3]; - u8 vlan_flag; + u16 agg_vars5; +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE5 (0x3<<0) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE5_SHIFT 0 +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE2 (0x3<<14) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE2_SHIFT 14 + u16 agg_val4_th; +#elif defined(__LITTLE_ENDIAN) + u16 agg_val4_th; + u16 agg_vars5; +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE5 (0x3<<0) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE5_SHIFT 0 +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) +#define XSTORM_L5CM_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE2 (0x3<<14) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE2_SHIFT 14 #endif + struct xstorm_tcp_tcp_ag_context_section tcp; #if defined(__BIG_ENDIAN) - u8 func_id; - u8 d_id[3]; + u16 agg_vars7; +#define __XSTORM_L5CM_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) +#define __XSTORM_L5CM_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 +#define __XSTORM_L5CM_AG_CONTEXT_AUX13_FLAG (0x1<<3) +#define __XSTORM_L5CM_AG_CONTEXT_AUX13_FLAG_SHIFT 3 +#define __XSTORM_L5CM_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_L5CM_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE3 (0x3<<6) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE3_SHIFT 6 +#define XSTORM_L5CM_AG_CONTEXT_AUX1_CF (0x3<<8) +#define XSTORM_L5CM_AG_CONTEXT_AUX1_CF_SHIFT 8 +#define __XSTORM_L5CM_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10) +#define __XSTORM_L5CM_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10 +#define __XSTORM_L5CM_AG_CONTEXT_AUX1_CF_EN (0x1<<11) +#define __XSTORM_L5CM_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 +#define __XSTORM_L5CM_AG_CONTEXT_AUX10_FLAG (0x1<<12) +#define __XSTORM_L5CM_AG_CONTEXT_AUX10_FLAG_SHIFT 12 +#define __XSTORM_L5CM_AG_CONTEXT_AUX11_FLAG (0x1<<13) +#define __XSTORM_L5CM_AG_CONTEXT_AUX11_FLAG_SHIFT 13 +#define __XSTORM_L5CM_AG_CONTEXT_AUX12_FLAG (0x1<<14) +#define __XSTORM_L5CM_AG_CONTEXT_AUX12_FLAG_SHIFT 14 +#define __XSTORM_L5CM_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_L5CM_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 + u8 agg_val3_th; + u8 agg_vars6; +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE6 (0x7<<0) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE6_SHIFT 0 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE7 (0x7<<3) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE7_SHIFT 3 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE4 (0x3<<6) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE4_SHIFT 6 #elif defined(__LITTLE_ENDIAN) - u8 d_id[3]; - u8 func_id; + u8 agg_vars6; +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE6 (0x7<<0) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE6_SHIFT 0 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE7 (0x7<<3) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE7_SHIFT 3 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE4 (0x3<<6) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE4_SHIFT 6 + u8 agg_val3_th; + u16 agg_vars7; +#define __XSTORM_L5CM_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) +#define __XSTORM_L5CM_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 +#define __XSTORM_L5CM_AG_CONTEXT_AUX13_FLAG (0x1<<3) +#define __XSTORM_L5CM_AG_CONTEXT_AUX13_FLAG_SHIFT 3 +#define __XSTORM_L5CM_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_L5CM_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE3 (0x3<<6) +#define XSTORM_L5CM_AG_CONTEXT_DECISION_RULE3_SHIFT 6 +#define XSTORM_L5CM_AG_CONTEXT_AUX1_CF (0x3<<8) +#define XSTORM_L5CM_AG_CONTEXT_AUX1_CF_SHIFT 8 +#define __XSTORM_L5CM_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10) +#define __XSTORM_L5CM_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10 +#define __XSTORM_L5CM_AG_CONTEXT_AUX1_CF_EN (0x1<<11) +#define __XSTORM_L5CM_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 +#define __XSTORM_L5CM_AG_CONTEXT_AUX10_FLAG (0x1<<12) +#define __XSTORM_L5CM_AG_CONTEXT_AUX10_FLAG_SHIFT 12 +#define __XSTORM_L5CM_AG_CONTEXT_AUX11_FLAG (0x1<<13) +#define __XSTORM_L5CM_AG_CONTEXT_AUX11_FLAG_SHIFT 13 +#define __XSTORM_L5CM_AG_CONTEXT_AUX12_FLAG (0x1<<14) +#define __XSTORM_L5CM_AG_CONTEXT_AUX12_FLAG_SHIFT 14 +#define __XSTORM_L5CM_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_L5CM_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 #endif #if defined(__BIG_ENDIAN) - u16 sq_xfrq_lcq_confq_size; - u16 tx_max_fc_pay_len; + u16 __agg_val11_th; + u16 __gen_data; #elif defined(__LITTLE_ENDIAN) - u16 tx_max_fc_pay_len; - u16 sq_xfrq_lcq_confq_size; + u16 __gen_data; + u16 __agg_val11_th; #endif - u32 lcq_prod; #if defined(__BIG_ENDIAN) - u8 port_id; - u8 tx_max_conc_seqs_c3; - u8 seq_id; - struct xstorm_fcoe_context_flags tx_flags; + u8 __reserved1; + u8 __agg_val6_th; + u16 __agg_val9; #elif defined(__LITTLE_ENDIAN) - struct xstorm_fcoe_context_flags tx_flags; - u8 seq_id; - u8 tx_max_conc_seqs_c3; - u8 port_id; + u16 __agg_val9; + u8 __agg_val6_th; + u8 __reserved1; #endif #if defined(__BIG_ENDIAN) - u16 verify_tx_seq; - u8 func_mode; - u8 vnic_id; + u16 agg_val2_th; + u16 agg_val2; #elif defined(__LITTLE_ENDIAN) - u8 vnic_id; - u8 func_mode; - u16 verify_tx_seq; + u16 agg_val2; + u16 agg_val2_th; #endif - struct regpair confq_curr_page_addr; - struct fcoe_cached_wqe cached_wqe[8]; - struct regpair lcq_base_addr; - struct xstorm_fcoe_task_ctx_entry_rd tce; - struct xstorm_fcoe_fcp_data fcp_data; + u32 agg_vars8; +#define XSTORM_L5CM_AG_CONTEXT_AGG_MISC2 (0xFFFFFF<<0) +#define XSTORM_L5CM_AG_CONTEXT_AGG_MISC2_SHIFT 0 +#define XSTORM_L5CM_AG_CONTEXT_AGG_MISC3 (0xFF<<24) +#define XSTORM_L5CM_AG_CONTEXT_AGG_MISC3_SHIFT 24 #if defined(__BIG_ENDIAN) - u16 fcoe_tx_stat_params_ram_addr; - u16 cmng_port_ram_addr; + u16 agg_misc0; + u16 agg_val4; #elif defined(__LITTLE_ENDIAN) - u16 cmng_port_ram_addr; - u16 fcoe_tx_stat_params_ram_addr; + u16 agg_val4; + u16 agg_misc0; #endif #if defined(__BIG_ENDIAN) - u8 fcp_cmd_pb_cmd_size; - u8 eth_hdr_size; - u16 pbf_addr; + u8 agg_val3; + u8 agg_val6; + u8 agg_val5_th; + u8 agg_val5; #elif defined(__LITTLE_ENDIAN) - u16 pbf_addr; - u8 eth_hdr_size; - u8 fcp_cmd_pb_cmd_size; + u8 agg_val5; + u8 agg_val5_th; + u8 agg_val6; + u8 agg_val3; #endif #if defined(__BIG_ENDIAN) - u8 reserved2[2]; - u8 cos; - u8 dcb_version; + u16 __agg_misc1; + u16 agg_limit1; #elif defined(__LITTLE_ENDIAN) - u8 dcb_version; - u8 cos; - u8 reserved2[2]; + u16 agg_limit1; + u16 __agg_misc1; #endif - u32 reserved3; - struct regpair reserved4[2]; + u32 completion_seq; + u32 agg_misc4; + u32 rst_seq_num; }; /* - * Xstorm FCoE Storm Context + * ABTS info $$KEEP_ENDIANNESS$$ */ -struct xstorm_fcoe_st_context { - struct xstorm_fcoe_eth_context_section eth; - struct xstorm_fcoe_context_section fcoe; +struct fcoe_abts_info { + __le16 aborted_task_id; + __le16 reserved0; + __le32 reserved1; }; + /* - * Fcoe connection context + * Fixed size structure in order to plant it in Union structure + * $$KEEP_ENDIANNESS$$ */ -struct fcoe_context { - struct ustorm_fcoe_st_context ustorm_st_context; - struct tstorm_fcoe_st_context tstorm_st_context; - struct xstorm_fcoe_ag_context xstorm_ag_context; - struct tstorm_fcoe_ag_context tstorm_ag_context; - struct ustorm_fcoe_ag_context ustorm_ag_context; - struct timers_block_context timers_context; - struct xstorm_fcoe_st_context xstorm_st_context; +struct fcoe_abts_rsp_union { + u8 r_ctl; + u8 rsrv[3]; + __le32 abts_rsp_payload[7]; }; + /* - * iSCSI context region, used only in iSCSI + * 4 regs size $$KEEP_ENDIANNESS$$ */ -struct ustorm_iscsi_rq_db { - struct regpair pbl_base; - struct regpair curr_pbe; +struct fcoe_bd_ctx { + __le32 buf_addr_hi; + __le32 buf_addr_lo; + __le16 buf_len; + __le16 rsrv0; + __le16 flags; + __le16 rsrv1; }; + /* - * iSCSI context region, used only in iSCSI + * FCoE cached sges context $$KEEP_ENDIANNESS$$ */ -struct ustorm_iscsi_r2tq_db { - struct regpair pbl_base; - struct regpair curr_pbe; +struct fcoe_cached_sge_ctx { + struct regpair cur_buf_addr; + __le16 cur_buf_rem; + __le16 second_buf_rem; + struct regpair second_buf_addr; }; + /* - * iSCSI context region, used only in iSCSI + * Cleanup info $$KEEP_ENDIANNESS$$ */ -struct ustorm_iscsi_cq_db { -#if defined(__BIG_ENDIAN) - u16 cq_sn; - u16 prod; -#elif defined(__LITTLE_ENDIAN) - u16 prod; - u16 cq_sn; -#endif - struct regpair curr_pbe; +struct fcoe_cleanup_info { + __le16 cleaned_task_id; + __le16 rolled_tx_seq_cnt; + __le32 rolled_tx_data_offset; }; + /* - * iSCSI context region, used only in iSCSI + * Fcp RSP flags $$KEEP_ENDIANNESS$$ */ -struct rings_db { - struct ustorm_iscsi_rq_db rq; - struct ustorm_iscsi_r2tq_db r2tq; - struct ustorm_iscsi_cq_db cq[8]; -#if defined(__BIG_ENDIAN) - u16 rq_prod; - u16 r2tq_prod; -#elif defined(__LITTLE_ENDIAN) - u16 r2tq_prod; - u16 rq_prod; -#endif - struct regpair cq_pbl_base; +struct fcoe_fcp_rsp_flags { + u8 flags; +#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID (0x1<<0) +#define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID_SHIFT 0 +#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID (0x1<<1) +#define FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID_SHIFT 1 +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER (0x1<<2) +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER_SHIFT 2 +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER (0x1<<3) +#define FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER_SHIFT 3 +#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ (0x1<<4) +#define FCOE_FCP_RSP_FLAGS_FCP_CONF_REQ_SHIFT 4 +#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS (0x7<<5) +#define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS_SHIFT 5 }; /* - * iSCSI context region, used only in iSCSI + * Fcp RSP payload $$KEEP_ENDIANNESS$$ */ -struct ustorm_iscsi_placement_db { - u32 sgl_base_lo; - u32 sgl_base_hi; - u32 local_sge_0_address_hi; - u32 local_sge_0_address_lo; -#if defined(__BIG_ENDIAN) - u16 curr_sge_offset; - u16 local_sge_0_size; -#elif defined(__LITTLE_ENDIAN) - u16 local_sge_0_size; - u16 curr_sge_offset; -#endif - u32 local_sge_1_address_hi; - u32 local_sge_1_address_lo; -#if defined(__BIG_ENDIAN) - u16 reserved6; - u16 local_sge_1_size; -#elif defined(__LITTLE_ENDIAN) - u16 local_sge_1_size; - u16 reserved6; -#endif -#if defined(__BIG_ENDIAN) - u8 sgl_size; - u8 local_sge_index_2b; - u16 reserved7; -#elif defined(__LITTLE_ENDIAN) - u16 reserved7; - u8 local_sge_index_2b; - u8 sgl_size; -#endif - u32 rem_pdu; - u32 place_db_bitfield_1; -#define USTORM_ISCSI_PLACEMENT_DB_REM_PDU_PAYLOAD (0xFFFFFF<<0) -#define USTORM_ISCSI_PLACEMENT_DB_REM_PDU_PAYLOAD_SHIFT 0 -#define USTORM_ISCSI_PLACEMENT_DB_CQ_ID (0xFF<<24) -#define USTORM_ISCSI_PLACEMENT_DB_CQ_ID_SHIFT 24 - u32 place_db_bitfield_2; -#define USTORM_ISCSI_PLACEMENT_DB_BYTES_2_TRUNCATE (0xFFFFFF<<0) -#define USTORM_ISCSI_PLACEMENT_DB_BYTES_2_TRUNCATE_SHIFT 0 -#define USTORM_ISCSI_PLACEMENT_DB_HOST_SGE_INDEX (0xFF<<24) -#define USTORM_ISCSI_PLACEMENT_DB_HOST_SGE_INDEX_SHIFT 24 - u32 nal; -#define USTORM_ISCSI_PLACEMENT_DB_REM_SGE_SIZE (0xFFFFFF<<0) -#define USTORM_ISCSI_PLACEMENT_DB_REM_SGE_SIZE_SHIFT 0 -#define USTORM_ISCSI_PLACEMENT_DB_EXP_PADDING_2B (0x3<<24) -#define USTORM_ISCSI_PLACEMENT_DB_EXP_PADDING_2B_SHIFT 24 -#define USTORM_ISCSI_PLACEMENT_DB_EXP_DIGEST_3B (0x7<<26) -#define USTORM_ISCSI_PLACEMENT_DB_EXP_DIGEST_3B_SHIFT 26 -#define USTORM_ISCSI_PLACEMENT_DB_NAL_LEN_3B (0x7<<29) -#define USTORM_ISCSI_PLACEMENT_DB_NAL_LEN_3B_SHIFT 29 +struct fcoe_fcp_rsp_payload { + struct regpair reserved0; + __le32 fcp_resid; + u8 scsi_status_code; + struct fcoe_fcp_rsp_flags fcp_flags; + __le16 retry_delay_timer; + __le32 fcp_rsp_len; + __le32 fcp_sns_len; }; /* - * Ustorm iSCSI Storm Context + * Fixed size structure in order to plant it in Union structure + * $$KEEP_ENDIANNESS$$ */ -struct ustorm_iscsi_st_context { - u32 exp_stat_sn; - u32 exp_data_sn; - struct rings_db ring; - struct regpair task_pbl_base; - struct regpair tce_phy_addr; - struct ustorm_iscsi_placement_db place_db; - u32 reserved8; - u32 rem_rcv_len; -#if defined(__BIG_ENDIAN) - u16 hdr_itt; - u16 iscsi_conn_id; -#elif defined(__LITTLE_ENDIAN) - u16 iscsi_conn_id; - u16 hdr_itt; -#endif - u32 nal_bytes; -#if defined(__BIG_ENDIAN) - u8 hdr_second_byte_union; - u8 bitfield_0; -#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU (0x1<<0) -#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 -#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) -#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) -#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 - u8 task_pdu_cache_index; - u8 task_pbe_cache_index; -#elif defined(__LITTLE_ENDIAN) - u8 task_pbe_cache_index; - u8 task_pdu_cache_index; - u8 bitfield_0; -#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU (0x1<<0) -#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 -#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) -#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) -#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 - u8 hdr_second_byte_union; -#endif -#if defined(__BIG_ENDIAN) - u16 reserved3; - u8 reserved2; - u8 acDecrement; -#elif defined(__LITTLE_ENDIAN) - u8 acDecrement; - u8 reserved2; - u16 reserved3; -#endif - u32 task_stat; -#if defined(__BIG_ENDIAN) - u8 hdr_opcode; - u8 num_cqs; - u16 reserved5; -#elif defined(__LITTLE_ENDIAN) - u16 reserved5; - u8 num_cqs; - u8 hdr_opcode; -#endif - u32 negotiated_rx; -#define USTORM_ISCSI_ST_CONTEXT_MAX_RECV_PDU_LENGTH (0xFFFFFF<<0) -#define USTORM_ISCSI_ST_CONTEXT_MAX_RECV_PDU_LENGTH_SHIFT 0 -#define USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS (0xFF<<24) -#define USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS_SHIFT 24 - u32 negotiated_rx_and_flags; -#define USTORM_ISCSI_ST_CONTEXT_MAX_BURST_LENGTH (0xFFFFFF<<0) -#define USTORM_ISCSI_ST_CONTEXT_MAX_BURST_LENGTH_SHIFT 0 -#define USTORM_ISCSI_ST_CONTEXT_B_CQE_POSTED_OR_HEADER_CACHED (0x1<<24) -#define USTORM_ISCSI_ST_CONTEXT_B_CQE_POSTED_OR_HEADER_CACHED_SHIFT 24 -#define USTORM_ISCSI_ST_CONTEXT_B_HDR_DIGEST_EN (0x1<<25) -#define USTORM_ISCSI_ST_CONTEXT_B_HDR_DIGEST_EN_SHIFT 25 -#define USTORM_ISCSI_ST_CONTEXT_B_DATA_DIGEST_EN (0x1<<26) -#define USTORM_ISCSI_ST_CONTEXT_B_DATA_DIGEST_EN_SHIFT 26 -#define USTORM_ISCSI_ST_CONTEXT_B_PROTOCOL_ERROR (0x1<<27) -#define USTORM_ISCSI_ST_CONTEXT_B_PROTOCOL_ERROR_SHIFT 27 -#define USTORM_ISCSI_ST_CONTEXT_B_TASK_VALID (0x1<<28) -#define USTORM_ISCSI_ST_CONTEXT_B_TASK_VALID_SHIFT 28 -#define USTORM_ISCSI_ST_CONTEXT_TASK_TYPE (0x3<<29) -#define USTORM_ISCSI_ST_CONTEXT_TASK_TYPE_SHIFT 29 -#define USTORM_ISCSI_ST_CONTEXT_B_ALL_DATA_ACKED (0x1<<31) -#define USTORM_ISCSI_ST_CONTEXT_B_ALL_DATA_ACKED_SHIFT 31 +struct fcoe_fcp_rsp_union { + struct fcoe_fcp_rsp_payload payload; + struct regpair reserved0; }; /* - * TCP context region, shared in TOE, RDMA and ISCSI + * FC header $$KEEP_ENDIANNESS$$ */ -struct tstorm_tcp_st_context_section { - u32 flags1; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_SHIFT 0 -#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID (0x1<<24) -#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID_SHIFT 24 -#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS (0x1<<25) -#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS_SHIFT 25 -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0 (0x1<<26) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0_SHIFT 26 -#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD (0x1<<27) -#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD_SHIFT 27 -#define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED (0x1<<28) -#define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED_SHIFT 28 -#define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE (0x1<<29) -#define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE_SHIFT 29 -#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN (0x1<<30) -#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN_SHIFT 30 -#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN (0x1<<31) -#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN_SHIFT 31 - u32 flags2; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_SHIFT 0 -#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN (0x1<<24) -#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN_SHIFT 24 -#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN (0x1<<25) -#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN_SHIFT 25 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_KA_PROBE_SENT (0x1<<26) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_KA_PROBE_SENT_SHIFT 26 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_PERSIST_PROBE_SENT (0x1<<27) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_PERSIST_PROBE_SENT_SHIFT 27 -#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<28) -#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 28 -#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<29) -#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 29 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK (0x1<<30) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK_SHIFT 30 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK (0x1<<31) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK_SHIFT 31 -#if defined(__BIG_ENDIAN) - u16 mss; - u8 tcp_sm_state; - u8 rto_exp; -#elif defined(__LITTLE_ENDIAN) - u8 rto_exp; - u8 tcp_sm_state; - u16 mss; -#endif - u32 rcv_nxt; - u32 timestamp_recent; - u32 timestamp_recent_time; - u32 cwnd; - u32 ss_thresh; - u32 cwnd_accum; - u32 prev_seg_seq; - u32 expected_rel_seq; - u32 recover; -#if defined(__BIG_ENDIAN) - u8 retransmit_count; - u8 ka_max_probe_count; - u8 persist_probe_count; - u8 ka_probe_count; -#elif defined(__LITTLE_ENDIAN) - u8 ka_probe_count; - u8 persist_probe_count; - u8 ka_max_probe_count; - u8 retransmit_count; -#endif -#if defined(__BIG_ENDIAN) - u8 statistics_counter_id; - u8 ooo_support_mode; - u8 snd_wnd_scale; - u8 dup_ack_count; -#elif defined(__LITTLE_ENDIAN) - u8 dup_ack_count; - u8 snd_wnd_scale; - u8 ooo_support_mode; - u8 statistics_counter_id; -#endif - u32 retransmit_start_time; - u32 ka_timeout; - u32 ka_interval; - u32 isle_start_seq; - u32 isle_end_seq; -#if defined(__BIG_ENDIAN) - u16 second_isle_address; - u16 recent_seg_wnd; -#elif defined(__LITTLE_ENDIAN) - u16 recent_seg_wnd; - u16 second_isle_address; -#endif -#if defined(__BIG_ENDIAN) - u8 max_isles_ever_happened; - u8 isles_number; - u16 last_isle_address; -#elif defined(__LITTLE_ENDIAN) - u16 last_isle_address; - u8 isles_number; - u8 max_isles_ever_happened; -#endif - u32 max_rt_time; -#if defined(__BIG_ENDIAN) - u16 lsb_mac_address; - u16 vlan_id; -#elif defined(__LITTLE_ENDIAN) - u16 vlan_id; - u16 lsb_mac_address; -#endif - u32 msb_mac_address; - u32 rightmost_received_seq; +struct fcoe_fc_hdr { + u8 s_id[3]; + u8 cs_ctl; + u8 d_id[3]; + u8 r_ctl; + __le16 seq_cnt; + u8 df_ctl; + u8 seq_id; + u8 f_ctl[3]; + u8 type; + __le32 parameters; + __le16 rx_id; + __le16 ox_id; }; /* - * Termination variables + * FC header union $$KEEP_ENDIANNESS$$ */ -struct iscsi_term_vars { - u8 BitMap; -#define ISCSI_TERM_VARS_TCP_STATE (0xF<<0) -#define ISCSI_TERM_VARS_TCP_STATE_SHIFT 0 -#define ISCSI_TERM_VARS_FIN_RECEIVED_SBIT (0x1<<4) -#define ISCSI_TERM_VARS_FIN_RECEIVED_SBIT_SHIFT 4 -#define ISCSI_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT (0x1<<5) -#define ISCSI_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT_SHIFT 5 -#define ISCSI_TERM_VARS_TERM_ON_CHIP (0x1<<6) -#define ISCSI_TERM_VARS_TERM_ON_CHIP_SHIFT 6 -#define ISCSI_TERM_VARS_RSRV (0x1<<7) -#define ISCSI_TERM_VARS_RSRV_SHIFT 7 +struct fcoe_mp_rsp_union { + struct fcoe_fc_hdr fc_hdr; + __le32 mp_payload_len; + __le32 rsrv; }; /* - * iSCSI context region, used only in iSCSI + * Completion information $$KEEP_ENDIANNESS$$ */ -struct tstorm_iscsi_st_context_section { -#if defined(__BIG_ENDIAN) - u16 rem_tcp_data_len; - u16 brb_offset; -#elif defined(__LITTLE_ENDIAN) - u16 brb_offset; - u16 rem_tcp_data_len; -#endif - u32 b2nh; -#if defined(__BIG_ENDIAN) - u16 rq_cons; - u8 flags; -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN (0x1<<0) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN_SHIFT 0 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN (0x1<<1) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN_SHIFT 1 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER (0x1<<2) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER_SHIFT 2 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE (0x1<<3) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE_SHIFT 3 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS (0x1<<4) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS_SHIFT 4 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV (0x7<<5) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV_SHIFT 5 - u8 hdr_bytes_2_fetch; -#elif defined(__LITTLE_ENDIAN) - u8 hdr_bytes_2_fetch; - u8 flags; -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN (0x1<<0) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN_SHIFT 0 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN (0x1<<1) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN_SHIFT 1 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER (0x1<<2) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER_SHIFT 2 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE (0x1<<3) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE_SHIFT 3 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS (0x1<<4) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS_SHIFT 4 -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV (0x7<<5) -#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV_SHIFT 5 - u16 rq_cons; -#endif - struct regpair rq_db_phy_addr; -#if defined(__BIG_ENDIAN) - struct iscsi_term_vars term_vars; - u8 scratchpad_idx; - u16 iscsi_conn_id; -#elif defined(__LITTLE_ENDIAN) - u16 iscsi_conn_id; - u8 scratchpad_idx; - struct iscsi_term_vars term_vars; -#endif - u32 process_nxt; +union fcoe_comp_flow_info { + struct fcoe_fcp_rsp_union fcp_rsp; + struct fcoe_abts_rsp_union abts_rsp; + struct fcoe_mp_rsp_union mp_rsp; + __le32 opaque[8]; }; + /* - * The iSCSI non-aggregative context of Tstorm + * External ABTS info $$KEEP_ENDIANNESS$$ */ -struct tstorm_iscsi_st_context { - struct tstorm_tcp_st_context_section tcp; - struct tstorm_iscsi_st_context_section iscsi; +struct fcoe_ext_abts_info { + __le32 rsrv0[6]; + struct fcoe_abts_info ctx; }; + /* - * The tcp aggregative context section of Xstorm + * External cleanup info $$KEEP_ENDIANNESS$$ */ -struct xstorm_tcp_tcp_ag_context_section { -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars1; - u8 __da_cnt; - u16 mss; -#elif defined(__LITTLE_ENDIAN) - u16 mss; - u8 __da_cnt; - u8 __tcp_agg_vars1; -#endif - u32 snd_nxt; - u32 tx_wnd; - u32 snd_una; - u32 local_adv_wnd; -#if defined(__BIG_ENDIAN) - u8 __agg_val8_th; - u8 __agg_val8; - u16 tcp_agg_vars2; -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG (0x1<<0) -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_SHIFT 0 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED (0x1<<1) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED_SHIFT 1 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE (0x1<<2) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE_SHIFT 2 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4 -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE (0x1<<5) -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE_SHIFT 5 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN (0x1<<6) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN_SHIFT 6 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN (0x1<<7) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN_SHIFT 7 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN (0x1<<8) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN_SHIFT 8 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14 -#elif defined(__LITTLE_ENDIAN) - u16 tcp_agg_vars2; -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG (0x1<<0) -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_SHIFT 0 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED (0x1<<1) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED_SHIFT 1 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE (0x1<<2) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE_SHIFT 2 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4 -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE (0x1<<5) -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE_SHIFT 5 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN (0x1<<6) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN_SHIFT 6 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN (0x1<<7) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN_SHIFT 7 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN (0x1<<8) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN_SHIFT 8 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14 - u8 __agg_val8; - u8 __agg_val8_th; -#endif - u32 ack_to_far_end; - u32 rto_timer; - u32 ka_timer; - u32 ts_to_echo; -#if defined(__BIG_ENDIAN) - u16 __agg_val7_th; - u16 __agg_val7; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val7; - u16 __agg_val7_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars5; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars3; - u8 __force_pure_ack_cnt; -#elif defined(__LITTLE_ENDIAN) - u8 __force_pure_ack_cnt; - u8 __tcp_agg_vars3; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars5; -#endif - u32 tcp_agg_vars6; -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_CF_EN (0x1<<0) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_CF_EN_SHIFT 0 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_EN (0x1<<1) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_EN_SHIFT 1 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_EN (0x1<<2) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_EN_SHIFT 2 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<3) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 3 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX6_FLAG (0x1<<4) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX6_FLAG_SHIFT 4 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX7_FLAG (0x1<<5) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX7_FLAG_SHIFT 5 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX5_CF (0x3<<6) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX5_CF_SHIFT 6 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF (0x3<<8) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_SHIFT 8 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF (0x3<<10) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_SHIFT 10 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF (0x3<<12) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_SHIFT 12 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF (0x3<<14) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_SHIFT 14 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX13_CF (0x3<<16) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX13_CF_SHIFT 16 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX14_CF (0x3<<18) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX14_CF_SHIFT 18 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX15_CF (0x3<<20) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX15_CF_SHIFT 20 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX16_CF (0x3<<22) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX16_CF_SHIFT 22 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX17_CF (0x3<<24) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX17_CF_SHIFT 24 -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ECE_FLAG (0x1<<26) -#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ECE_FLAG_SHIFT 26 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED71 (0x1<<27) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED71_SHIFT 27 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_FORCE_PURE_ACK_CNT_DIRTY (0x1<<28) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_FORCE_PURE_ACK_CNT_DIRTY_SHIFT 28 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TCP_AUTO_STOP_FLAG (0x1<<29) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TCP_AUTO_STOP_FLAG_SHIFT 29 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DO_TS_UPDATE_FLAG (0x1<<30) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DO_TS_UPDATE_FLAG_SHIFT 30 -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CANCEL_RETRANSMIT_FLAG (0x1<<31) -#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CANCEL_RETRANSMIT_FLAG_SHIFT 31 -#if defined(__BIG_ENDIAN) - u16 __agg_misc6; - u16 __tcp_agg_vars7; -#elif defined(__LITTLE_ENDIAN) - u16 __tcp_agg_vars7; - u16 __agg_misc6; -#endif - u32 __agg_val10; - u32 __agg_val10_th; -#if defined(__BIG_ENDIAN) - u16 __reserved3; - u8 __reserved2; - u8 __da_only_cnt; -#elif defined(__LITTLE_ENDIAN) - u8 __da_only_cnt; - u8 __reserved2; - u16 __reserved3; -#endif +struct fcoe_ext_cleanup_info { + __le32 rsrv0[6]; + struct fcoe_cleanup_info ctx; }; + /* - * The iscsi aggregative context of Xstorm + * Fcoe FW Tx sequence context $$KEEP_ENDIANNESS$$ */ -struct xstorm_iscsi_ag_context { -#if defined(__BIG_ENDIAN) - u16 agg_val1; - u8 agg_vars1; -#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 -#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN (0x1<<5) -#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7 - u8 state; -#elif defined(__LITTLE_ENDIAN) - u8 state; - u8 agg_vars1; -#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4 -#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN (0x1<<5) -#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7 - u16 agg_val1; -#endif -#if defined(__BIG_ENDIAN) - u8 cdu_reserved; - u8 __agg_vars4; - u8 agg_vars3; -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 - u8 agg_vars2; -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG (0x1<<3) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG_SHIFT 3 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG_SHIFT 4 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1 (0x3<<5) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 -#elif defined(__LITTLE_ENDIAN) - u8 agg_vars2; -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG (0x1<<3) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG_SHIFT 3 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG_SHIFT 4 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1 (0x3<<5) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 - u8 agg_vars3; -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 - u8 __agg_vars4; - u8 cdu_reserved; -#endif - u32 more_to_send; -#if defined(__BIG_ENDIAN) - u16 agg_vars5; -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5 (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5_SHIFT 0 -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2 (0x3<<14) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2_SHIFT 14 - u16 sq_cons; -#elif defined(__LITTLE_ENDIAN) - u16 sq_cons; - u16 agg_vars5; -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5 (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5_SHIFT 0 -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2) -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2 -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8) -#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2 (0x3<<14) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2_SHIFT 14 -#endif - struct xstorm_tcp_tcp_ag_context_section tcp; -#if defined(__BIG_ENDIAN) - u16 agg_vars7; -#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) -#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 -#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) -#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_SHIFT 8 -#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10) -#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN (0x1<<11) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG (0x1<<12) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG_SHIFT 12 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG (0x1<<13) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 - u8 agg_val3_th; - u8 agg_vars6; -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6_SHIFT 0 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7 (0x7<<3) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4 (0x3<<6) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4_SHIFT 6 -#elif defined(__LITTLE_ENDIAN) - u8 agg_vars6; -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6_SHIFT 0 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7 (0x7<<3) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4 (0x3<<6) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4_SHIFT 6 - u8 agg_val3_th; - u16 agg_vars7; -#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0) -#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) -#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 -#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) -#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_SHIFT 8 -#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10) -#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN (0x1<<11) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN_SHIFT 11 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG (0x1<<12) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG_SHIFT 12 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG (0x1<<13) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val11_th; - u16 __gen_data; -#elif defined(__LITTLE_ENDIAN) - u16 __gen_data; - u16 __agg_val11_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved1; - u8 __agg_val6_th; - u16 __agg_val9; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val9; - u8 __agg_val6_th; - u8 __reserved1; -#endif +struct fcoe_fw_tx_seq_ctx { + __le32 data_offset; + __le16 seq_cnt; + __le16 rsrv0; +}; + +/* + * Fcoe external FW Tx sequence context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_ext_fw_tx_seq_ctx { + __le32 rsrv0[6]; + struct fcoe_fw_tx_seq_ctx ctx; +}; + + +/* + * FCoE multiple sges context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_mul_sges_ctx { + struct regpair cur_sge_addr; + __le16 cur_sge_off; + u8 cur_sge_idx; + u8 sgl_size; +}; + +/* + * FCoE external multiple sges context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_ext_mul_sges_ctx { + struct fcoe_mul_sges_ctx mul_sgl; + struct regpair rsrv0; +}; + + +/* + * FCP CMD payload $$KEEP_ENDIANNESS$$ + */ +struct fcoe_fcp_cmd_payload { + __le32 opaque[8]; +}; + + + + + +/* + * Fcp xfr rdy payload $$KEEP_ENDIANNESS$$ + */ +struct fcoe_fcp_xfr_rdy_payload { + __le32 burst_len; + __le32 data_ro; +}; + + +/* + * FC frame $$KEEP_ENDIANNESS$$ + */ +struct fcoe_fc_frame { + struct fcoe_fc_hdr fc_hdr; + __le32 reserved0[2]; +}; + + + + +/* + * FCoE KCQ CQE parameters $$KEEP_ENDIANNESS$$ + */ +union fcoe_kcqe_params { + __le32 reserved0[4]; +}; + +/* + * FCoE KCQ CQE $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kcqe { + __le32 fcoe_conn_id; + __le32 completion_status; + __le32 fcoe_conn_context_id; + union fcoe_kcqe_params params; + __le16 qe_self_seq; + u8 op_code; + u8 flags; +#define FCOE_KCQE_RESERVED0 (0x7<<0) +#define FCOE_KCQE_RESERVED0_SHIFT 0 +#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3) +#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3 +#define FCOE_KCQE_LAYER_CODE (0x7<<4) +#define FCOE_KCQE_LAYER_CODE_SHIFT 4 +#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7) +#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7 +}; + + + +/* + * FCoE KWQE header $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_header { + u8 op_code; + u8 flags; +#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0) +#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0 +#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4) +#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4 +#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7) +#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7 +}; + +/* + * FCoE firmware init request 1 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_init1 { + __le16 num_tasks; + struct fcoe_kwqe_header hdr; + __le32 task_list_pbl_addr_lo; + __le32 task_list_pbl_addr_hi; + __le32 dummy_buffer_addr_lo; + __le32 dummy_buffer_addr_hi; + __le16 sq_num_wqes; + __le16 rq_num_wqes; + __le16 rq_buffer_log_size; + __le16 cq_num_wqes; + __le16 mtu; + u8 num_sessions_log; + u8 flags; +#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0) +#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0 +#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4) +#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4 +#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7) +#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7 +}; + +/* + * FCoE firmware init request 2 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_init2 { + u8 hsi_major_version; + u8 hsi_minor_version; + struct fcoe_kwqe_header hdr; + __le32 hash_tbl_pbl_addr_lo; + __le32 hash_tbl_pbl_addr_hi; + __le32 t2_hash_tbl_addr_lo; + __le32 t2_hash_tbl_addr_hi; + __le32 t2_ptr_hash_tbl_addr_lo; + __le32 t2_ptr_hash_tbl_addr_hi; + __le32 free_list_count; +}; + +/* + * FCoE firmware init request 3 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_init3 { + __le16 reserved0; + struct fcoe_kwqe_header hdr; + __le32 error_bit_map_lo; + __le32 error_bit_map_hi; + u8 perf_config; + u8 reserved21[3]; + __le32 reserved2[4]; +}; + +/* + * FCoE connection offload request 1 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_conn_offload1 { + __le16 fcoe_conn_id; + struct fcoe_kwqe_header hdr; + __le32 sq_addr_lo; + __le32 sq_addr_hi; + __le32 rq_pbl_addr_lo; + __le32 rq_pbl_addr_hi; + __le32 rq_first_pbe_addr_lo; + __le32 rq_first_pbe_addr_hi; + __le16 rq_prod; + __le16 reserved0; +}; + +/* + * FCoE connection offload request 2 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_conn_offload2 { + __le16 tx_max_fc_pay_len; + struct fcoe_kwqe_header hdr; + __le32 cq_addr_lo; + __le32 cq_addr_hi; + __le32 xferq_addr_lo; + __le32 xferq_addr_hi; + __le32 conn_db_addr_lo; + __le32 conn_db_addr_hi; + __le32 reserved1; +}; + +/* + * FCoE connection offload request 3 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_conn_offload3 { + __le16 vlan_tag; +#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0) +#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0 +#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12) +#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12 +#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13) +#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13 + struct fcoe_kwqe_header hdr; + u8 s_id[3]; + u8 tx_max_conc_seqs_c3; + u8 d_id[3]; + u8 flags; +#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0) +#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0 +#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1) +#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1 +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2) +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2 +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3) +#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3 +#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4) +#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4 +#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5) +#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5 +#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6) +#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6 +#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7) +#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7 + __le32 reserved; + __le32 confq_first_pbe_addr_lo; + __le32 confq_first_pbe_addr_hi; + __le16 tx_total_conc_seqs; + __le16 rx_max_fc_pay_len; + __le16 rx_total_conc_seqs; + u8 rx_max_conc_seqs_c3; + u8 rx_open_seqs_exch_c3; +}; + +/* + * FCoE connection offload request 4 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_conn_offload4 { + u8 e_d_tov_timer_val; + u8 reserved2; + struct fcoe_kwqe_header hdr; + u8 src_mac_addr_lo[2]; + u8 src_mac_addr_mid[2]; + u8 src_mac_addr_hi[2]; + u8 dst_mac_addr_hi[2]; + u8 dst_mac_addr_lo[2]; + u8 dst_mac_addr_mid[2]; + __le32 lcq_addr_lo; + __le32 lcq_addr_hi; + __le32 confq_pbl_base_addr_lo; + __le32 confq_pbl_base_addr_hi; +}; + +/* + * FCoE connection enable request $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_conn_enable_disable { + __le16 reserved0; + struct fcoe_kwqe_header hdr; + u8 src_mac_addr_lo[2]; + u8 src_mac_addr_mid[2]; + u8 src_mac_addr_hi[2]; + u16 vlan_tag; +#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0 +#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12 +#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13) +#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13 + u8 dst_mac_addr_lo[2]; + u8 dst_mac_addr_mid[2]; + u8 dst_mac_addr_hi[2]; + __le16 reserved1; + u8 s_id[3]; + u8 vlan_flag; + u8 d_id[3]; + u8 reserved3; + __le32 context_id; + __le32 conn_id; + __le32 reserved4; +}; + +/* + * FCoE connection destroy request $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_conn_destroy { + __le16 reserved0; + struct fcoe_kwqe_header hdr; + __le32 context_id; + __le32 conn_id; + __le32 reserved1[5]; +}; + +/* + * FCoe destroy request $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_destroy { + __le16 reserved0; + struct fcoe_kwqe_header hdr; + __le32 reserved1[7]; +}; + +/* + * FCoe statistics request $$KEEP_ENDIANNESS$$ + */ +struct fcoe_kwqe_stat { + __le16 reserved0; + struct fcoe_kwqe_header hdr; + __le32 stat_params_addr_lo; + __le32 stat_params_addr_hi; + __le32 reserved1[5]; +}; + +/* + * FCoE KWQ WQE $$KEEP_ENDIANNESS$$ + */ +union fcoe_kwqe { + struct fcoe_kwqe_init1 init1; + struct fcoe_kwqe_init2 init2; + struct fcoe_kwqe_init3 init3; + struct fcoe_kwqe_conn_offload1 conn_offload1; + struct fcoe_kwqe_conn_offload2 conn_offload2; + struct fcoe_kwqe_conn_offload3 conn_offload3; + struct fcoe_kwqe_conn_offload4 conn_offload4; + struct fcoe_kwqe_conn_enable_disable conn_enable_disable; + struct fcoe_kwqe_conn_destroy conn_destroy; + struct fcoe_kwqe_destroy destroy; + struct fcoe_kwqe_stat statistics; +}; + + + + + + + + + + + + + + + + +/* + * TX SGL context $$KEEP_ENDIANNESS$$ + */ +union fcoe_sgl_union_ctx { + struct fcoe_cached_sge_ctx cached_sge; + struct fcoe_ext_mul_sges_ctx sgl; + __le32 opaque[5]; +}; + +/* + * Data-In/ELS/BLS information $$KEEP_ENDIANNESS$$ + */ +struct fcoe_read_flow_info { + union fcoe_sgl_union_ctx sgl_ctx; + __le32 rsrv0[3]; +}; + + +/* + * Fcoe stat context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_s_stat_ctx { + u8 flags; +#define FCOE_S_STAT_CTX_ACTIVE (0x1<<0) +#define FCOE_S_STAT_CTX_ACTIVE_SHIFT 0 +#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND (0x1<<1) +#define FCOE_S_STAT_CTX_ACK_ABORT_SEQ_COND_SHIFT 1 +#define FCOE_S_STAT_CTX_ABTS_PERFORMED (0x1<<2) +#define FCOE_S_STAT_CTX_ABTS_PERFORMED_SHIFT 2 +#define FCOE_S_STAT_CTX_SEQ_TIMEOUT (0x1<<3) +#define FCOE_S_STAT_CTX_SEQ_TIMEOUT_SHIFT 3 +#define FCOE_S_STAT_CTX_P_RJT (0x1<<4) +#define FCOE_S_STAT_CTX_P_RJT_SHIFT 4 +#define FCOE_S_STAT_CTX_ACK_EOFT (0x1<<5) +#define FCOE_S_STAT_CTX_ACK_EOFT_SHIFT 5 +#define FCOE_S_STAT_CTX_RSRV1 (0x3<<6) +#define FCOE_S_STAT_CTX_RSRV1_SHIFT 6 +}; + +/* + * Fcoe rx seq context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_rx_seq_ctx { + u8 seq_id; + struct fcoe_s_stat_ctx s_stat; + __le16 seq_cnt; + __le32 low_exp_ro; + __le32 high_exp_ro; +}; + + +/* + * Fcoe rx_wr union context $$KEEP_ENDIANNESS$$ + */ +union fcoe_rx_wr_union_ctx { + struct fcoe_read_flow_info read_info; + union fcoe_comp_flow_info comp_info; + __le32 opaque[8]; +}; + + + +/* + * FCoE SQ element $$KEEP_ENDIANNESS$$ + */ +struct fcoe_sqe { + __le16 wqe; +#define FCOE_SQE_TASK_ID (0x7FFF<<0) +#define FCOE_SQE_TASK_ID_SHIFT 0 +#define FCOE_SQE_TOGGLE_BIT (0x1<<15) +#define FCOE_SQE_TOGGLE_BIT_SHIFT 15 +}; + + + +/* + * 14 regs $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_tx_only { + union fcoe_sgl_union_ctx sgl_ctx; + __le32 rsrv0; +}; + +/* + * 32 bytes (8 regs) used for TX only purposes $$KEEP_ENDIANNESS$$ + */ +union fcoe_tx_wr_rx_rd_union_ctx { + struct fcoe_fc_frame tx_frame; + struct fcoe_fcp_cmd_payload fcp_cmd; + struct fcoe_ext_cleanup_info cleanup; + struct fcoe_ext_abts_info abts; + struct fcoe_ext_fw_tx_seq_ctx tx_seq; + __le32 opaque[8]; +}; + +/* + * tce_tx_wr_rx_rd_const $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_tx_wr_rx_rd_const { + u8 init_flags; +#define FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE (0x7<<0) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT 0 +#define FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE (0x1<<3) +#define FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT 3 +#define FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE (0x1<<4) +#define FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT 4 +#define FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE (0x3<<5) +#define FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT 5 +#define FCOE_TCE_TX_WR_RX_RD_CONST_SUPPORT_REC_TOV (0x1<<7) +#define FCOE_TCE_TX_WR_RX_RD_CONST_SUPPORT_REC_TOV_SHIFT 7 + u8 tx_flags; +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_VALID (0x1<<0) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_VALID_SHIFT 0 +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE (0xF<<1) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT 1 +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV1 (0x1<<5) +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV1_SHIFT 5 +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_SEQ_INIT (0x1<<6) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_SEQ_INIT_SHIFT 6 +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV2 (0x1<<7) +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV2_SHIFT 7 + __le16 rsrv3; + __le32 verify_tx_seq; +}; + +/* + * tce_tx_wr_rx_rd $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_tx_wr_rx_rd { + union fcoe_tx_wr_rx_rd_union_ctx union_ctx; + struct fcoe_tce_tx_wr_rx_rd_const const_ctx; +}; + +/* + * tce_rx_wr_tx_rd_const $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_wr_tx_rd_const { + __le32 data_2_trns; + __le32 init_flags; +#define FCOE_TCE_RX_WR_TX_RD_CONST_CID (0xFFFFFF<<0) +#define FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT 0 +#define FCOE_TCE_RX_WR_TX_RD_CONST_RSRV0 (0xFF<<24) +#define FCOE_TCE_RX_WR_TX_RD_CONST_RSRV0_SHIFT 24 +}; + +/* + * tce_rx_wr_tx_rd_var $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_wr_tx_rd_var { + __le16 rx_flags; +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV1 (0xF<<0) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV1_SHIFT 0 +#define FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE (0x7<<4) +#define FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE_SHIFT 4 +#define FCOE_TCE_RX_WR_TX_RD_VAR_CONF_REQ (0x1<<7) +#define FCOE_TCE_RX_WR_TX_RD_VAR_CONF_REQ_SHIFT 7 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE (0xF<<8) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE_SHIFT 8 +#define FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME (0x1<<12) +#define FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT 12 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_SEQ_INIT (0x1<<13) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_SEQ_INIT_SHIFT 13 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV2 (0x1<<14) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV2_SHIFT 14 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_VALID (0x1<<15) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_VALID_SHIFT 15 + __le16 rx_id; + struct fcoe_fcp_xfr_rdy_payload fcp_xfr_rdy; +}; + +/* + * tce_rx_wr_tx_rd $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_wr_tx_rd { + struct fcoe_tce_rx_wr_tx_rd_const const_ctx; + struct fcoe_tce_rx_wr_tx_rd_var var_ctx; +}; + +/* + * tce_rx_only $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_only { + struct fcoe_rx_seq_ctx rx_seq_ctx; + union fcoe_rx_wr_union_ctx union_ctx; +}; + +/* + * task_ctx_entry $$KEEP_ENDIANNESS$$ + */ +struct fcoe_task_ctx_entry { + struct fcoe_tce_tx_only txwr_only; + struct fcoe_tce_tx_wr_rx_rd txwr_rxrd; + struct fcoe_tce_rx_wr_tx_rd rxwr_txrd; + struct fcoe_tce_rx_only rxwr_only; +}; + + + + + + + + + + +/* + * FCoE XFRQ element $$KEEP_ENDIANNESS$$ + */ +struct fcoe_xfrqe { + __le16 wqe; +#define FCOE_XFRQE_TASK_ID (0x7FFF<<0) +#define FCOE_XFRQE_TASK_ID_SHIFT 0 +#define FCOE_XFRQE_TOGGLE_BIT (0x1<<15) +#define FCOE_XFRQE_TOGGLE_BIT_SHIFT 15 +}; + + +/* + * Cached SGEs $$KEEP_ENDIANNESS$$ + */ +struct common_fcoe_sgl { + struct fcoe_bd_ctx sge[3]; +}; + + +/* + * FCoE SQ\XFRQ element + */ +struct fcoe_cached_wqe { + struct fcoe_sqe sqe; + struct fcoe_xfrqe xfrqe; +}; + + +/* + * FCoE connection enable\disable params passed by driver to FW in FCoE enable + * ramrod $$KEEP_ENDIANNESS$$ + */ +struct fcoe_conn_enable_disable_ramrod_params { + struct fcoe_kwqe_conn_enable_disable enable_disable_kwqe; +}; + + +/* + * FCoE connection offload params passed by driver to FW in FCoE offload ramrod + * $$KEEP_ENDIANNESS$$ + */ +struct fcoe_conn_offload_ramrod_params { + struct fcoe_kwqe_conn_offload1 offload_kwqe1; + struct fcoe_kwqe_conn_offload2 offload_kwqe2; + struct fcoe_kwqe_conn_offload3 offload_kwqe3; + struct fcoe_kwqe_conn_offload4 offload_kwqe4; +}; + + +struct ustorm_fcoe_mng_ctx { #if defined(__BIG_ENDIAN) - u16 hq_prod; - u16 hq_cons; + u8 mid_seq_proc_flag; + u8 tce_in_cam_flag; + u8 tce_on_ior_flag; + u8 en_cached_tce_flag; #elif defined(__LITTLE_ENDIAN) - u16 hq_cons; - u16 hq_prod; + u8 en_cached_tce_flag; + u8 tce_on_ior_flag; + u8 tce_in_cam_flag; + u8 mid_seq_proc_flag; #endif - u32 agg_vars8; -#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC2 (0xFFFFFF<<0) -#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC2_SHIFT 0 -#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC3 (0xFF<<24) -#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC3_SHIFT 24 #if defined(__BIG_ENDIAN) - u16 r2tq_prod; - u16 sq_prod; + u8 tce_cam_addr; + u8 cached_conn_flag; + u16 rsrv0; #elif defined(__LITTLE_ENDIAN) - u16 sq_prod; - u16 r2tq_prod; + u16 rsrv0; + u8 cached_conn_flag; + u8 tce_cam_addr; #endif #if defined(__BIG_ENDIAN) - u8 agg_val3; - u8 agg_val6; - u8 agg_val5_th; - u8 agg_val5; + u16 dma_tce_ram_addr; + u16 tce_ram_addr; #elif defined(__LITTLE_ENDIAN) - u8 agg_val5; - u8 agg_val5_th; - u8 agg_val6; - u8 agg_val3; + u16 tce_ram_addr; + u16 dma_tce_ram_addr; #endif #if defined(__BIG_ENDIAN) - u16 __agg_misc1; - u16 agg_limit1; + u16 ox_id; + u16 wr_done_seq; #elif defined(__LITTLE_ENDIAN) - u16 agg_limit1; - u16 __agg_misc1; + u16 wr_done_seq; + u16 ox_id; #endif - u32 hq_cons_tcp_seq; - u32 exp_stat_sn; - u32 rst_seq_num; + struct regpair task_addr; }; /* - * The tcp aggregative context section of Tstorm + * Parameters initialized during offloaded according to FLOGI/PLOGI/PRLI and + * used in FCoE context section */ -struct tstorm_tcp_tcp_ag_context_section { - u32 __agg_val1; +struct ustorm_fcoe_params { #if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars2; - u8 __agg_val3; - u16 __agg_val2; + u16 fcoe_conn_id; + u16 flags; +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0) +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0 +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1) +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1 +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2) +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2 +#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3) +#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3 +#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4) +#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4 +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5) +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5 +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6) +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6 +#define USTORM_FCOE_PARAMS_RSRV0 (0x1FF<<7) +#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 7 #elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u8 __agg_val3; - u8 __tcp_agg_vars2; + u16 flags; +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS (0x1<<0) +#define USTORM_FCOE_PARAMS_B_MUL_N_PORT_IDS_SHIFT 0 +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES (0x1<<1) +#define USTORM_FCOE_PARAMS_B_E_D_TOV_RES_SHIFT 1 +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT (0x1<<2) +#define USTORM_FCOE_PARAMS_B_CONT_INCR_SEQ_CNT_SHIFT 2 +#define USTORM_FCOE_PARAMS_B_CONF_REQ (0x1<<3) +#define USTORM_FCOE_PARAMS_B_CONF_REQ_SHIFT 3 +#define USTORM_FCOE_PARAMS_B_REC_VALID (0x1<<4) +#define USTORM_FCOE_PARAMS_B_REC_VALID_SHIFT 4 +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT (0x1<<5) +#define USTORM_FCOE_PARAMS_B_CQ_TOGGLE_BIT_SHIFT 5 +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT (0x1<<6) +#define USTORM_FCOE_PARAMS_B_XFRQ_TOGGLE_BIT_SHIFT 6 +#define USTORM_FCOE_PARAMS_RSRV0 (0x1FF<<7) +#define USTORM_FCOE_PARAMS_RSRV0_SHIFT 7 + u16 fcoe_conn_id; #endif #if defined(__BIG_ENDIAN) - u16 __agg_val5; - u8 __agg_val6; - u8 __tcp_agg_vars3; + u8 hc_csdm_byte_en; + u8 func_id; + u8 port_id; + u8 vnic_id; #elif defined(__LITTLE_ENDIAN) - u8 __tcp_agg_vars3; - u8 __agg_val6; - u16 __agg_val5; + u8 vnic_id; + u8 port_id; + u8 func_id; + u8 hc_csdm_byte_en; #endif - u32 snd_nxt; - u32 rtt_seq; - u32 rtt_time; - u32 __reserved66; - u32 wnd_right_edge; - u32 tcp_agg_vars1; -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 0 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG (0x1<<1) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG_SHIFT 1 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF (0x3<<2) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_SHIFT 2 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF (0x3<<4) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_SHIFT 4 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_EN (0x1<<6) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_EN_SHIFT 6 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_EN (0x1<<7) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_EN_SHIFT 7 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN (0x1<<8) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN_SHIFT 8 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_SND_NXT_EN (0x1<<9) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_SND_NXT_EN_SHIFT 9 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<10) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 10 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_FLAG (0x1<<11) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_FLAG_SHIFT 11 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_EN (0x1<<12) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_EN_SHIFT 12 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_EN (0x1<<13) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_EN_SHIFT 13 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF (0x3<<14) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_SHIFT 14 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF (0x3<<16) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_SHIFT 16 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_BLOCKED (0x1<<18) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_BLOCKED_SHIFT 18 -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<19) -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 19 -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_EN (0x1<<20) -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_EN_SHIFT 20 -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_EN (0x1<<21) -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_EN_SHIFT 21 -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED1 (0x3<<22) -#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED1_SHIFT 22 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ (0xF<<24) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ_SHIFT 24 -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ (0xF<<28) -#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ_SHIFT 28 - u32 snd_max; - u32 snd_una; - u32 __reserved2; -}; - -/* - * The iscsi aggregative context of Tstorm - */ -struct tstorm_iscsi_ag_context { #if defined(__BIG_ENDIAN) - u16 ulp_credit; - u8 agg_vars1; -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 - u8 state; + u16 rx_total_conc_seqs; + u16 rx_max_fc_pay_len; #elif defined(__LITTLE_ENDIAN) - u8 state; - u8 agg_vars1; -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 - u16 ulp_credit; + u16 rx_max_fc_pay_len; + u16 rx_total_conc_seqs; #endif #if defined(__BIG_ENDIAN) - u16 __agg_val4; - u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 -#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) -#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 -#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) -#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 + u8 task_pbe_idx_off; + u8 task_in_page_log_size; + u16 rx_max_conc_seqs; #elif defined(__LITTLE_ENDIAN) - u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) -#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) -#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) -#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 -#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) -#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 -#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) -#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 - u16 __agg_val4; + u16 rx_max_conc_seqs; + u8 task_in_page_log_size; + u8 task_pbe_idx_off; #endif - struct tstorm_tcp_tcp_ag_context_section tcp; }; /* - * The iscsi aggregative context of Ustorm + * FCoE 16-bits index structure */ -struct ustorm_iscsi_ag_context { +struct fcoe_idx16_fields { + u16 fields; +#define FCOE_IDX16_FIELDS_IDX (0x7FFF<<0) +#define FCOE_IDX16_FIELDS_IDX_SHIFT 0 +#define FCOE_IDX16_FIELDS_MSB (0x1<<15) +#define FCOE_IDX16_FIELDS_MSB_SHIFT 15 +}; + +/* + * FCoE 16-bits index union + */ +union fcoe_idx16_field_union { + struct fcoe_idx16_fields fields; + u16 val; +}; + +/* + * Parameters required for placement according to SGL + */ +struct ustorm_fcoe_data_place_mng { #if defined(__BIG_ENDIAN) - u8 __aux_counter_flags; - u8 agg_vars2; -#define USTORM_ISCSI_AG_CONTEXT_TX_CF (0x3<<0) -#define USTORM_ISCSI_AG_CONTEXT_TX_CF_SHIFT 0 -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF (0x3<<2) -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_SHIFT 2 -#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) -#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 - u8 agg_vars1; -#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define USTORM_ISCSI_AG_CONTEXT_INV_CF (0x3<<4) -#define USTORM_ISCSI_AG_CONTEXT_INV_CF_SHIFT 4 -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF (0x3<<6) -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_SHIFT 6 - u8 state; + u16 sge_off; + u8 num_sges; + u8 sge_idx; #elif defined(__LITTLE_ENDIAN) - u8 state; - u8 agg_vars1; -#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0) -#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0 -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1) -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1 -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2) -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) -#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define USTORM_ISCSI_AG_CONTEXT_INV_CF (0x3<<4) -#define USTORM_ISCSI_AG_CONTEXT_INV_CF_SHIFT 4 -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF (0x3<<6) -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_SHIFT 6 - u8 agg_vars2; -#define USTORM_ISCSI_AG_CONTEXT_TX_CF (0x3<<0) -#define USTORM_ISCSI_AG_CONTEXT_TX_CF_SHIFT 0 -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF (0x3<<2) -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_SHIFT 2 -#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4) -#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7 - u8 __aux_counter_flags; + u8 sge_idx; + u8 num_sges; + u16 sge_off; #endif +}; + +/* + * Parameters required for placement according to SGL + */ +struct ustorm_fcoe_data_place { + struct ustorm_fcoe_data_place_mng cached_mng; + struct fcoe_bd_ctx cached_sge[2]; +}; + +/* + * TX processing shall write and RX processing shall read from this section + */ +union fcoe_u_tce_tx_wr_rx_rd_union { + struct fcoe_abts_info abts; + struct fcoe_cleanup_info cleanup; + struct fcoe_fw_tx_seq_ctx tx_seq_ctx; + u32 opaque[2]; +}; + +/* + * TX processing shall write and RX processing shall read from this section + */ +struct fcoe_u_tce_tx_wr_rx_rd { + union fcoe_u_tce_tx_wr_rx_rd_union union_ctx; + struct fcoe_tce_tx_wr_rx_rd_const const_ctx; +}; + +struct ustorm_fcoe_tce { + struct fcoe_u_tce_tx_wr_rx_rd txwr_rxrd; + struct fcoe_tce_rx_wr_tx_rd rxwr_txrd; + struct fcoe_tce_rx_only rxwr; +}; + +struct ustorm_fcoe_cache_ctx { + u32 rsrv0; + struct ustorm_fcoe_data_place data_place; + struct ustorm_fcoe_tce tce; +}; + +/* + * Ustorm FCoE Storm Context + */ +struct ustorm_fcoe_st_context { + struct ustorm_fcoe_mng_ctx mng_ctx; + struct ustorm_fcoe_params fcoe_params; + struct regpair cq_base_addr; + struct regpair rq_pbl_base; + struct regpair rq_cur_page_addr; + struct regpair confq_pbl_base_addr; + struct regpair conn_db_base; + struct regpair xfrq_base_addr; + struct regpair lcq_base_addr; #if defined(__BIG_ENDIAN) - u8 cdu_usage; - u8 agg_misc2; - u16 __cq_local_comp_itt_val; + union fcoe_idx16_field_union rq_cons; + union fcoe_idx16_field_union rq_prod; #elif defined(__LITTLE_ENDIAN) - u16 __cq_local_comp_itt_val; - u8 agg_misc2; - u8 cdu_usage; + union fcoe_idx16_field_union rq_prod; + union fcoe_idx16_field_union rq_cons; #endif - u32 agg_misc4; #if defined(__BIG_ENDIAN) - u8 agg_val3_th; - u8 agg_val3; - u16 agg_misc3; + u16 xfrq_prod; + u16 cq_cons; #elif defined(__LITTLE_ENDIAN) - u16 agg_misc3; - u8 agg_val3; - u8 agg_val3_th; + u16 cq_cons; + u16 xfrq_prod; #endif - u32 agg_val1; - u32 agg_misc4_th; #if defined(__BIG_ENDIAN) - u16 agg_val2_th; - u16 agg_val2; + u16 lcq_cons; + u16 hc_cram_address; #elif defined(__LITTLE_ENDIAN) - u16 agg_val2; - u16 agg_val2_th; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved2; - u8 decision_rules; -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE (0x7<<0) -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 -#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) -#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 - u8 decision_rule_enable_bits; -#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN (0x1<<0) -#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN_SHIFT 0 -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 -#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN (0x1<<2) -#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN_SHIFT 2 -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN (0x1<<3) -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN (0x1<<4) -#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN_SHIFT 4 -#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<5) -#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 5 -#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 -#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) -#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 + u16 hc_cram_address; + u16 lcq_cons; +#endif +#if defined(__BIG_ENDIAN) + u16 sq_xfrq_lcq_confq_size; + u16 confq_prod; #elif defined(__LITTLE_ENDIAN) - u8 decision_rule_enable_bits; -#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN (0x1<<0) -#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN_SHIFT 0 -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1) -#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1 -#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN (0x1<<2) -#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN_SHIFT 2 -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN (0x1<<3) -#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN (0x1<<4) -#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN_SHIFT 4 -#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<5) -#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 5 -#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 6 -#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7) -#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7 - u8 decision_rules; -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE (0x7<<0) -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 -#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) -#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 - u16 __reserved2; + u16 confq_prod; + u16 sq_xfrq_lcq_confq_size; +#endif +#if defined(__BIG_ENDIAN) + u8 hc_csdm_agg_int; + u8 rsrv2; + u8 available_rqes; + u8 sp_q_flush_cnt; +#elif defined(__LITTLE_ENDIAN) + u8 sp_q_flush_cnt; + u8 available_rqes; + u8 rsrv2; + u8 hc_csdm_agg_int; +#endif +#if defined(__BIG_ENDIAN) + u16 num_pend_tasks; + u16 pbf_ack_ram_addr; +#elif defined(__LITTLE_ENDIAN) + u16 pbf_ack_ram_addr; + u16 num_pend_tasks; #endif + struct ustorm_fcoe_cache_ctx cache_ctx; }; /* - * Ethernet context section, shared in TOE, RDMA and ISCSI + * The FCoE non-aggregative context of Tstorm */ -struct xstorm_eth_context_section { +struct tstorm_fcoe_st_context { + struct regpair reserved0; + struct regpair reserved1; +}; + +/* + * Ethernet context section + */ +struct xstorm_fcoe_eth_context_section { #if defined(__BIG_ENDIAN) u8 remote_addr_4; u8 remote_addr_5; @@ -3343,20 +3432,20 @@ struct xstorm_eth_context_section { #if defined(__BIG_ENDIAN) u16 reserved_vlan_type; u16 params; -#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) -#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 -#define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12) -#define XSTORM_ETH_CONTEXT_SECTION_CFI_SHIFT 12 -#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) -#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 #elif defined(__LITTLE_ENDIAN) u16 params; -#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) -#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 -#define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12) -#define XSTORM_ETH_CONTEXT_SECTION_CFI_SHIFT 12 -#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) -#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI (0x1<<12) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_CFI_SHIFT 12 +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) +#define XSTORM_FCOE_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 u16 reserved_vlan_type; #endif #if defined(__BIG_ENDIAN) @@ -3373,1002 +3462,1601 @@ struct xstorm_eth_context_section { }; /* - * IpV4 context section, shared in TOE, RDMA and ISCSI + * Flags used in FCoE context section - 1 byte + */ +struct xstorm_fcoe_context_flags { + u8 flags; +#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q (0x3<<0) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_PROC_Q_SHIFT 0 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ (0x1<<2) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_MID_SEQ_SHIFT 2 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_BLOCK_SQ (0x1<<3) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_BLOCK_SQ_SHIFT 3 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT (0x1<<4) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_REC_SUPPORT_SHIFT 4 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE (0x1<<5) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_SQ_TOGGLE_SHIFT 5 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE (0x1<<6) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_XFRQ_TOGGLE_SHIFT 6 +#define XSTORM_FCOE_CONTEXT_FLAGS_B_VNTAG_VLAN (0x1<<7) +#define XSTORM_FCOE_CONTEXT_FLAGS_B_VNTAG_VLAN_SHIFT 7 +}; + +struct xstorm_fcoe_tce { + struct fcoe_tce_tx_only txwr; + struct fcoe_tce_tx_wr_rx_rd txwr_rxrd; +}; + +/* + * FCP_DATA parameters required for transmission + */ +struct xstorm_fcoe_fcp_data { + u32 io_rem; +#if defined(__BIG_ENDIAN) + u16 cached_sge_off; + u8 cached_num_sges; + u8 cached_sge_idx; +#elif defined(__LITTLE_ENDIAN) + u8 cached_sge_idx; + u8 cached_num_sges; + u16 cached_sge_off; +#endif + u32 buf_addr_hi_0; + u32 buf_addr_lo_0; +#if defined(__BIG_ENDIAN) + u16 num_of_pending_tasks; + u16 buf_len_0; +#elif defined(__LITTLE_ENDIAN) + u16 buf_len_0; + u16 num_of_pending_tasks; +#endif + u32 buf_addr_hi_1; + u32 buf_addr_lo_1; +#if defined(__BIG_ENDIAN) + u16 task_pbe_idx_off; + u16 buf_len_1; +#elif defined(__LITTLE_ENDIAN) + u16 buf_len_1; + u16 task_pbe_idx_off; +#endif + u32 buf_addr_hi_2; + u32 buf_addr_lo_2; +#if defined(__BIG_ENDIAN) + u16 ox_id; + u16 buf_len_2; +#elif defined(__LITTLE_ENDIAN) + u16 buf_len_2; + u16 ox_id; +#endif +}; + +/* + * vlan configuration + */ +struct xstorm_fcoe_vlan_conf { + u8 vlan_conf; +#define XSTORM_FCOE_VLAN_CONF_PRIORITY (0x7<<0) +#define XSTORM_FCOE_VLAN_CONF_PRIORITY_SHIFT 0 +#define XSTORM_FCOE_VLAN_CONF_INNER_VLAN_FLAG (0x1<<3) +#define XSTORM_FCOE_VLAN_CONF_INNER_VLAN_FLAG_SHIFT 3 +#define XSTORM_FCOE_VLAN_CONF_RESERVED (0xF<<4) +#define XSTORM_FCOE_VLAN_CONF_RESERVED_SHIFT 4 +}; + +/* + * FCoE 16-bits vlan structure + */ +struct fcoe_vlan_fields { + u16 fields; +#define FCOE_VLAN_FIELDS_VID (0xFFF<<0) +#define FCOE_VLAN_FIELDS_VID_SHIFT 0 +#define FCOE_VLAN_FIELDS_CLI (0x1<<12) +#define FCOE_VLAN_FIELDS_CLI_SHIFT 12 +#define FCOE_VLAN_FIELDS_PRI (0x7<<13) +#define FCOE_VLAN_FIELDS_PRI_SHIFT 13 +}; + +/* + * FCoE 16-bits vlan union + */ +union fcoe_vlan_field_union { + struct fcoe_vlan_fields fields; + u16 val; +}; + +/* + * FCoE 16-bits vlan, vif union + */ +union fcoe_vlan_vif_field_union { + union fcoe_vlan_field_union vlan; + u16 vif; +}; + +/* + * FCoE context section + */ +struct xstorm_fcoe_context_section { +#if defined(__BIG_ENDIAN) + u8 cs_ctl; + u8 s_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 s_id[3]; + u8 cs_ctl; +#endif +#if defined(__BIG_ENDIAN) + u8 rctl; + u8 d_id[3]; +#elif defined(__LITTLE_ENDIAN) + u8 d_id[3]; + u8 rctl; +#endif +#if defined(__BIG_ENDIAN) + u16 sq_xfrq_lcq_confq_size; + u16 tx_max_fc_pay_len; +#elif defined(__LITTLE_ENDIAN) + u16 tx_max_fc_pay_len; + u16 sq_xfrq_lcq_confq_size; +#endif + u32 lcq_prod; +#if defined(__BIG_ENDIAN) + u8 port_id; + u8 func_id; + u8 seq_id; + struct xstorm_fcoe_context_flags tx_flags; +#elif defined(__LITTLE_ENDIAN) + struct xstorm_fcoe_context_flags tx_flags; + u8 seq_id; + u8 func_id; + u8 port_id; +#endif +#if defined(__BIG_ENDIAN) + u16 mtu; + u8 func_mode; + u8 vnic_id; +#elif defined(__LITTLE_ENDIAN) + u8 vnic_id; + u8 func_mode; + u16 mtu; +#endif + struct regpair confq_curr_page_addr; + struct fcoe_cached_wqe cached_wqe[8]; + struct regpair lcq_base_addr; + struct xstorm_fcoe_tce tce; + struct xstorm_fcoe_fcp_data fcp_data; +#if defined(__BIG_ENDIAN) + u8 tx_max_conc_seqs_c3; + u8 vlan_flag; + u8 dcb_val; + u8 data_pb_cmd_size; +#elif defined(__LITTLE_ENDIAN) + u8 data_pb_cmd_size; + u8 dcb_val; + u8 vlan_flag; + u8 tx_max_conc_seqs_c3; +#endif +#if defined(__BIG_ENDIAN) + u16 fcoe_tx_stat_params_ram_addr; + u16 fcoe_tx_fc_seq_ram_addr; +#elif defined(__LITTLE_ENDIAN) + u16 fcoe_tx_fc_seq_ram_addr; + u16 fcoe_tx_stat_params_ram_addr; +#endif +#if defined(__BIG_ENDIAN) + u8 fcp_cmd_line_credit; + u8 eth_hdr_size; + u16 pbf_addr; +#elif defined(__LITTLE_ENDIAN) + u16 pbf_addr; + u8 eth_hdr_size; + u8 fcp_cmd_line_credit; +#endif +#if defined(__BIG_ENDIAN) + union fcoe_vlan_vif_field_union multi_func_val; + u8 page_log_size; + struct xstorm_fcoe_vlan_conf orig_vlan_conf; +#elif defined(__LITTLE_ENDIAN) + struct xstorm_fcoe_vlan_conf orig_vlan_conf; + u8 page_log_size; + union fcoe_vlan_vif_field_union multi_func_val; +#endif +#if defined(__BIG_ENDIAN) + u16 fcp_cmd_frame_size; + u16 pbf_addr_ff; +#elif defined(__LITTLE_ENDIAN) + u16 pbf_addr_ff; + u16 fcp_cmd_frame_size; +#endif +#if defined(__BIG_ENDIAN) + u8 vlan_num; + u8 cos; + u8 cache_xfrq_cons; + u8 cache_sq_cons; +#elif defined(__LITTLE_ENDIAN) + u8 cache_sq_cons; + u8 cache_xfrq_cons; + u8 cos; + u8 vlan_num; +#endif + u32 verify_tx_seq; +}; + +/* + * Xstorm FCoE Storm Context + */ +struct xstorm_fcoe_st_context { + struct xstorm_fcoe_eth_context_section eth; + struct xstorm_fcoe_context_section fcoe; +}; + +/* + * Fcoe connection context + */ +struct fcoe_context { + struct ustorm_fcoe_st_context ustorm_st_context; + struct tstorm_fcoe_st_context tstorm_st_context; + struct xstorm_fcoe_ag_context xstorm_ag_context; + struct tstorm_fcoe_ag_context tstorm_ag_context; + struct ustorm_fcoe_ag_context ustorm_ag_context; + struct timers_block_context timers_context; + struct xstorm_fcoe_st_context xstorm_st_context; +}; + +/* + * FCoE init params passed by driver to FW in FCoE init ramrod + * $$KEEP_ENDIANNESS$$ */ -struct xstorm_ip_v4_context_section { -#if defined(__BIG_ENDIAN) - u16 __pbf_hdr_cmd_rsvd_id; - u16 __pbf_hdr_cmd_rsvd_flags_offset; -#elif defined(__LITTLE_ENDIAN) - u16 __pbf_hdr_cmd_rsvd_flags_offset; - u16 __pbf_hdr_cmd_rsvd_id; -#endif -#if defined(__BIG_ENDIAN) - u8 __pbf_hdr_cmd_rsvd_ver_ihl; - u8 tos; - u16 __pbf_hdr_cmd_rsvd_length; -#elif defined(__LITTLE_ENDIAN) - u16 __pbf_hdr_cmd_rsvd_length; - u8 tos; - u8 __pbf_hdr_cmd_rsvd_ver_ihl; -#endif - u32 ip_local_addr; -#if defined(__BIG_ENDIAN) - u8 ttl; - u8 __pbf_hdr_cmd_rsvd_protocol; - u16 __pbf_hdr_cmd_rsvd_csum; -#elif defined(__LITTLE_ENDIAN) - u16 __pbf_hdr_cmd_rsvd_csum; - u8 __pbf_hdr_cmd_rsvd_protocol; - u8 ttl; -#endif - u32 __pbf_hdr_cmd_rsvd_1; - u32 ip_remote_addr; +struct fcoe_init_ramrod_params { + struct fcoe_kwqe_init1 init_kwqe1; + struct fcoe_kwqe_init2 init_kwqe2; + struct fcoe_kwqe_init3 init_kwqe3; + struct regpair eq_pbl_base; + __le32 eq_pbl_size; + __le32 reserved2; + __le16 eq_prod; + __le16 sb_num; + u8 sb_id; + u8 reserved0; + __le16 reserved1; }; /* - * context section, shared in TOE, RDMA and ISCSI + * FCoE statistics params buffer passed by driver to FW in FCoE statistics + * ramrod $$KEEP_ENDIANNESS$$ */ -struct xstorm_padded_ip_v4_context_section { - struct xstorm_ip_v4_context_section ip_v4; - u32 reserved1[4]; +struct fcoe_stat_ramrod_params { + struct fcoe_kwqe_stat stat_kwqe; }; /* - * IpV6 context section, shared in TOE, RDMA and ISCSI + * CQ DB CQ producer and pending completion counter */ -struct xstorm_ip_v6_context_section { +struct iscsi_cq_db_prod_pnd_cmpltn_cnt { #if defined(__BIG_ENDIAN) - u16 pbf_hdr_cmd_rsvd_payload_len; - u8 pbf_hdr_cmd_rsvd_nxt_hdr; - u8 hop_limit; + u16 cntr; + u16 prod; #elif defined(__LITTLE_ENDIAN) - u8 hop_limit; - u8 pbf_hdr_cmd_rsvd_nxt_hdr; - u16 pbf_hdr_cmd_rsvd_payload_len; + u16 prod; + u16 cntr; #endif - u32 priority_flow_label; -#define XSTORM_IP_V6_CONTEXT_SECTION_FLOW_LABEL (0xFFFFF<<0) -#define XSTORM_IP_V6_CONTEXT_SECTION_FLOW_LABEL_SHIFT 0 -#define XSTORM_IP_V6_CONTEXT_SECTION_TRAFFIC_CLASS (0xFF<<20) -#define XSTORM_IP_V6_CONTEXT_SECTION_TRAFFIC_CLASS_SHIFT 20 -#define XSTORM_IP_V6_CONTEXT_SECTION_PBF_HDR_CMD_RSVD_VER (0xF<<28) -#define XSTORM_IP_V6_CONTEXT_SECTION_PBF_HDR_CMD_RSVD_VER_SHIFT 28 - u32 ip_local_addr_lo_hi; - u32 ip_local_addr_lo_lo; - u32 ip_local_addr_hi_hi; - u32 ip_local_addr_hi_lo; - u32 ip_remote_addr_lo_hi; - u32 ip_remote_addr_lo_lo; - u32 ip_remote_addr_hi_hi; - u32 ip_remote_addr_hi_lo; }; -union xstorm_ip_context_section_types { - struct xstorm_padded_ip_v4_context_section padded_ip_v4; - struct xstorm_ip_v6_context_section ip_v6; +/* + * CQ DB pending completion ITT array + */ +struct iscsi_cq_db_prod_pnd_cmpltn_cnt_arr { + struct iscsi_cq_db_prod_pnd_cmpltn_cnt prod_pend_comp[8]; }; /* - * TCP context section, shared in TOE, RDMA and ISCSI + * Cstorm CQ sequence to notify array, updated by driver */ -struct xstorm_tcp_context_section { - u32 snd_max; +struct iscsi_cq_db_sqn_2_notify_arr { + u16 sqn[8]; +}; + +/* + * Cstorm iSCSI Storm Context + */ +struct cstorm_iscsi_st_context { + struct iscsi_cq_db_prod_pnd_cmpltn_cnt_arr cq_c_prod_pend_comp_ctr_arr; + struct iscsi_cq_db_sqn_2_notify_arr cq_c_prod_sqn_arr; + struct iscsi_cq_db_sqn_2_notify_arr cq_c_sqn_2_notify_arr; + struct regpair hq_pbl_base; + struct regpair hq_curr_pbe; + struct regpair task_pbl_base; + struct regpair cq_db_base; #if defined(__BIG_ENDIAN) - u16 remote_port; - u16 local_port; + u16 hq_bd_itt; + u16 iscsi_conn_id; #elif defined(__LITTLE_ENDIAN) - u16 local_port; - u16 remote_port; + u16 iscsi_conn_id; + u16 hq_bd_itt; #endif + u32 hq_bd_data_segment_len; + u32 hq_bd_buffer_offset; #if defined(__BIG_ENDIAN) - u8 original_nagle_1b; - u8 ts_enabled; - u16 tcp_params; -#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0) -#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0 -#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT (0x1<<8) -#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT_SHIFT 8 -#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED (0x1<<9) -#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 -#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) -#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 -#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) -#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 -#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) -#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13 -#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14) -#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14 + u8 rsrv; + u8 cq_proc_en_bit_map; + u8 cq_pend_comp_itt_valid_bit_map; + u8 hq_bd_opcode; #elif defined(__LITTLE_ENDIAN) - u16 tcp_params; -#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0) -#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0 -#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT (0x1<<8) -#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT_SHIFT 8 -#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED (0x1<<9) -#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 -#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) -#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 -#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) -#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 -#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) -#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13 -#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14) -#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14 - u8 ts_enabled; - u8 original_nagle_1b; + u8 hq_bd_opcode; + u8 cq_pend_comp_itt_valid_bit_map; + u8 cq_proc_en_bit_map; + u8 rsrv; #endif + u32 hq_tcp_seq; #if defined(__BIG_ENDIAN) - u16 pseudo_csum; - u16 window_scaling_factor; + u16 flags; +#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN (0x1<<0) +#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN_SHIFT 0 +#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN (0x1<<1) +#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN_SHIFT 1 +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID (0x1<<2) +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID_SHIFT 2 +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG (0x1<<3) +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG_SHIFT 3 +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK (0x1<<4) +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK_SHIFT 4 +#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV (0x7FF<<5) +#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV_SHIFT 5 + u16 hq_cons; #elif defined(__LITTLE_ENDIAN) - u16 window_scaling_factor; - u16 pseudo_csum; + u16 hq_cons; + u16 flags; +#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN (0x1<<0) +#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN_SHIFT 0 +#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN (0x1<<1) +#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN_SHIFT 1 +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID (0x1<<2) +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID_SHIFT 2 +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG (0x1<<3) +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG_SHIFT 3 +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK (0x1<<4) +#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK_SHIFT 4 +#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV (0x7FF<<5) +#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV_SHIFT 5 #endif - u32 reserved2; - u32 ts_time_diff; - u32 __next_timer_expir; + struct regpair rsrv1; }; + /* - * Common context section, shared in TOE, RDMA and ISCSI + * SCSI read/write SQ WQE */ -struct xstorm_common_context_section { - struct xstorm_eth_context_section ethernet; - union xstorm_ip_context_section_types ip_union; - struct xstorm_tcp_context_section tcp; +struct iscsi_cmd_pdu_hdr_little_endian { #if defined(__BIG_ENDIAN) - u16 reserved; - u8 statistics_params; -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<0) -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 0 -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<1) -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 -#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) -#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 - u8 ip_version_1b; + u8 opcode; + u8 op_attr; +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_ATTRIBUTES (0x7<<0) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_ATTRIBUTES_SHIFT 0 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_RSRV1 (0x3<<3) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 3 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_WRITE_FLAG (0x1<<5) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_WRITE_FLAG_SHIFT 5 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_READ_FLAG (0x1<<6) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_READ_FLAG_SHIFT 6 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG (0x1<<7) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG_SHIFT 7 + u16 rsrv0; #elif defined(__LITTLE_ENDIAN) - u8 ip_version_1b; - u8 statistics_params; -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<0) -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 0 -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<1) -#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 -#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) -#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 - u16 reserved; + u16 rsrv0; + u8 op_attr; +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_ATTRIBUTES (0x7<<0) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_ATTRIBUTES_SHIFT 0 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_RSRV1 (0x3<<3) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 3 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_WRITE_FLAG (0x1<<5) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_WRITE_FLAG_SHIFT 5 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_READ_FLAG (0x1<<6) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_READ_FLAG_SHIFT 6 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG (0x1<<7) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG_SHIFT 7 + u8 opcode; #endif + u32 data_fields; +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH (0xFFFFFF<<0) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH_SHIFT 0 +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH (0xFF<<24) +#define ISCSI_CMD_PDU_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH_SHIFT 24 + struct regpair lun; + u32 itt; + u32 expected_data_transfer_length; + u32 cmd_sn; + u32 exp_stat_sn; + u32 scsi_command_block[4]; }; + /* - * Flags used in ISCSI context section + * Buffer per connection, used in Tstorm */ -struct xstorm_iscsi_context_flags { - u8 flags; -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA (0x1<<0) -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA_SHIFT 0 -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T (0x1<<1) -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T_SHIFT 1 -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_HEADER_DIGEST (0x1<<2) -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_HEADER_DIGEST_SHIFT 2 -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_DATA_DIGEST (0x1<<3) -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_DATA_DIGEST_SHIFT 3 -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_HQ_BD_WRITTEN (0x1<<4) -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_HQ_BD_WRITTEN_SHIFT 4 -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_LAST_OP_SQ (0x1<<5) -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_LAST_OP_SQ_SHIFT 5 -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_UPDATE_SND_NXT (0x1<<6) -#define XSTORM_ISCSI_CONTEXT_FLAGS_B_UPDATE_SND_NXT_SHIFT 6 -#define XSTORM_ISCSI_CONTEXT_FLAGS_RESERVED4 (0x1<<7) -#define XSTORM_ISCSI_CONTEXT_FLAGS_RESERVED4_SHIFT 7 +struct iscsi_conn_buf { + struct regpair reserved[8]; }; -struct iscsi_task_context_entry_x { - u32 data_out_buffer_offset; - u32 itt; - u32 data_sn; + +/* + * iSCSI context region, used only in iSCSI + */ +struct ustorm_iscsi_rq_db { + struct regpair pbl_base; + struct regpair curr_pbe; +}; + +/* + * iSCSI context region, used only in iSCSI + */ +struct ustorm_iscsi_r2tq_db { + struct regpair pbl_base; + struct regpair curr_pbe; +}; + +/* + * iSCSI context region, used only in iSCSI + */ +struct ustorm_iscsi_cq_db { +#if defined(__BIG_ENDIAN) + u16 cq_sn; + u16 prod; +#elif defined(__LITTLE_ENDIAN) + u16 prod; + u16 cq_sn; +#endif + struct regpair curr_pbe; }; -struct iscsi_task_context_entry_xuc_x_write_only { - u32 tx_r2t_sn; +/* + * iSCSI context region, used only in iSCSI + */ +struct rings_db { + struct ustorm_iscsi_rq_db rq; + struct ustorm_iscsi_r2tq_db r2tq; + struct ustorm_iscsi_cq_db cq[8]; +#if defined(__BIG_ENDIAN) + u16 rq_prod; + u16 r2tq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 r2tq_prod; + u16 rq_prod; +#endif + struct regpair cq_pbl_base; }; -struct iscsi_task_context_entry_xuc_xu_write_both { +/* + * iSCSI context region, used only in iSCSI + */ +struct ustorm_iscsi_placement_db { u32 sgl_base_lo; u32 sgl_base_hi; + u32 local_sge_0_address_hi; + u32 local_sge_0_address_lo; +#if defined(__BIG_ENDIAN) + u16 curr_sge_offset; + u16 local_sge_0_size; +#elif defined(__LITTLE_ENDIAN) + u16 local_sge_0_size; + u16 curr_sge_offset; +#endif + u32 local_sge_1_address_hi; + u32 local_sge_1_address_lo; +#if defined(__BIG_ENDIAN) + u8 exp_padding_2b; + u8 nal_len_3b; + u16 local_sge_1_size; +#elif defined(__LITTLE_ENDIAN) + u16 local_sge_1_size; + u8 nal_len_3b; + u8 exp_padding_2b; +#endif #if defined(__BIG_ENDIAN) u8 sgl_size; - u8 sge_index; - u16 sge_offset; + u8 local_sge_index_2b; + u16 reserved7; #elif defined(__LITTLE_ENDIAN) - u16 sge_offset; - u8 sge_index; + u16 reserved7; + u8 local_sge_index_2b; u8 sgl_size; #endif + u32 rem_pdu; + u32 place_db_bitfield_1; +#define USTORM_ISCSI_PLACEMENT_DB_REM_PDU_PAYLOAD (0xFFFFFF<<0) +#define USTORM_ISCSI_PLACEMENT_DB_REM_PDU_PAYLOAD_SHIFT 0 +#define USTORM_ISCSI_PLACEMENT_DB_CQ_ID (0xFF<<24) +#define USTORM_ISCSI_PLACEMENT_DB_CQ_ID_SHIFT 24 + u32 place_db_bitfield_2; +#define USTORM_ISCSI_PLACEMENT_DB_BYTES_2_TRUNCATE (0xFFFFFF<<0) +#define USTORM_ISCSI_PLACEMENT_DB_BYTES_2_TRUNCATE_SHIFT 0 +#define USTORM_ISCSI_PLACEMENT_DB_HOST_SGE_INDEX (0xFF<<24) +#define USTORM_ISCSI_PLACEMENT_DB_HOST_SGE_INDEX_SHIFT 24 + u32 nal; +#define USTORM_ISCSI_PLACEMENT_DB_REM_SGE_SIZE (0xFFFFFF<<0) +#define USTORM_ISCSI_PLACEMENT_DB_REM_SGE_SIZE_SHIFT 0 +#define USTORM_ISCSI_PLACEMENT_DB_EXP_DIGEST_3B (0xFF<<24) +#define USTORM_ISCSI_PLACEMENT_DB_EXP_DIGEST_3B_SHIFT 24 }; /* - * iSCSI context section + * Ustorm iSCSI Storm Context */ -struct xstorm_iscsi_context_section { - u32 first_burst_length; - u32 max_send_pdu_length; - struct regpair sq_pbl_base; - struct regpair sq_curr_pbe; - struct regpair hq_pbl_base; - struct regpair hq_curr_pbe_base; - struct regpair r2tq_pbl_base; - struct regpair r2tq_curr_pbe_base; +struct ustorm_iscsi_st_context { + u32 exp_stat_sn; + u32 exp_data_sn; + struct rings_db ring; struct regpair task_pbl_base; + struct regpair tce_phy_addr; + struct ustorm_iscsi_placement_db place_db; + u32 reserved8; + u32 rem_rcv_len; #if defined(__BIG_ENDIAN) - u16 data_out_count; - struct xstorm_iscsi_context_flags flags; - u8 task_pbl_cache_idx; + u16 hdr_itt; + u16 iscsi_conn_id; #elif defined(__LITTLE_ENDIAN) - u8 task_pbl_cache_idx; - struct xstorm_iscsi_context_flags flags; - u16 data_out_count; + u16 iscsi_conn_id; + u16 hdr_itt; #endif - u32 seq_more_2_send; - u32 pdu_more_2_send; - struct iscsi_task_context_entry_x temp_tce_x; - struct iscsi_task_context_entry_xuc_x_write_only temp_tce_x_wr; - struct iscsi_task_context_entry_xuc_xu_write_both temp_tce_xu_wr; - struct regpair lun; - u32 exp_data_transfer_len_ttt; - u32 pdu_data_2_rxmit; - u32 rxmit_bytes_2_dr; + u32 nal_bytes; #if defined(__BIG_ENDIAN) - u16 rxmit_sge_offset; - u16 hq_rxmit_cons; + u8 hdr_second_byte_union; + u8 bitfield_0; +#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU (0x1<<0) +#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 +#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) +#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 + u8 task_pdu_cache_index; + u8 task_pbe_cache_index; #elif defined(__LITTLE_ENDIAN) - u16 hq_rxmit_cons; - u16 rxmit_sge_offset; + u8 task_pbe_cache_index; + u8 task_pdu_cache_index; + u8 bitfield_0; +#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU (0x1<<0) +#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 +#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) +#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 + u8 hdr_second_byte_union; #endif #if defined(__BIG_ENDIAN) - u16 r2tq_cons; - u8 rxmit_flags; -#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD (0x1<<0) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD_SHIFT 0 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR (0x1<<1) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR_SHIFT 1 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU (0x1<<2) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU_SHIFT 2 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR (0x1<<3) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR_SHIFT 3 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR (0x1<<4) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR_SHIFT 4 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING (0x3<<5) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING_SHIFT 5 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT (0x1<<7) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT_SHIFT 7 - u8 rxmit_sge_idx; + u16 reserved3; + u8 reserved2; + u8 acDecrement; +#elif defined(__LITTLE_ENDIAN) + u8 acDecrement; + u8 reserved2; + u16 reserved3; +#endif + u32 task_stat; +#if defined(__BIG_ENDIAN) + u8 hdr_opcode; + u8 num_cqs; + u16 reserved5; +#elif defined(__LITTLE_ENDIAN) + u16 reserved5; + u8 num_cqs; + u8 hdr_opcode; +#endif + u32 negotiated_rx; +#define USTORM_ISCSI_ST_CONTEXT_MAX_RECV_PDU_LENGTH (0xFFFFFF<<0) +#define USTORM_ISCSI_ST_CONTEXT_MAX_RECV_PDU_LENGTH_SHIFT 0 +#define USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS (0xFF<<24) +#define USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS_SHIFT 24 + u32 negotiated_rx_and_flags; +#define USTORM_ISCSI_ST_CONTEXT_MAX_BURST_LENGTH (0xFFFFFF<<0) +#define USTORM_ISCSI_ST_CONTEXT_MAX_BURST_LENGTH_SHIFT 0 +#define USTORM_ISCSI_ST_CONTEXT_B_CQE_POSTED_OR_HEADER_CACHED (0x1<<24) +#define USTORM_ISCSI_ST_CONTEXT_B_CQE_POSTED_OR_HEADER_CACHED_SHIFT 24 +#define USTORM_ISCSI_ST_CONTEXT_B_HDR_DIGEST_EN (0x1<<25) +#define USTORM_ISCSI_ST_CONTEXT_B_HDR_DIGEST_EN_SHIFT 25 +#define USTORM_ISCSI_ST_CONTEXT_B_DATA_DIGEST_EN (0x1<<26) +#define USTORM_ISCSI_ST_CONTEXT_B_DATA_DIGEST_EN_SHIFT 26 +#define USTORM_ISCSI_ST_CONTEXT_B_PROTOCOL_ERROR (0x1<<27) +#define USTORM_ISCSI_ST_CONTEXT_B_PROTOCOL_ERROR_SHIFT 27 +#define USTORM_ISCSI_ST_CONTEXT_B_TASK_VALID (0x1<<28) +#define USTORM_ISCSI_ST_CONTEXT_B_TASK_VALID_SHIFT 28 +#define USTORM_ISCSI_ST_CONTEXT_TASK_TYPE (0x3<<29) +#define USTORM_ISCSI_ST_CONTEXT_TASK_TYPE_SHIFT 29 +#define USTORM_ISCSI_ST_CONTEXT_B_ALL_DATA_ACKED (0x1<<31) +#define USTORM_ISCSI_ST_CONTEXT_B_ALL_DATA_ACKED_SHIFT 31 +}; + +/* + * TCP context region, shared in TOE, RDMA and ISCSI + */ +struct tstorm_tcp_st_context_section { + u32 flags1; +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID (0x1<<24) +#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID_SHIFT 24 +#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS (0x1<<25) +#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS_SHIFT 25 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0 (0x1<<26) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0_SHIFT 26 +#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD (0x1<<27) +#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD_SHIFT 27 +#define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED (0x1<<28) +#define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED_SHIFT 28 +#define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE (0x1<<29) +#define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE_SHIFT 29 +#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN (0x1<<30) +#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN_SHIFT 30 +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN (0x1<<31) +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN_SHIFT 31 + u32 flags2; +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN (0x1<<24) +#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN_SHIFT 24 +#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN (0x1<<25) +#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN_SHIFT 25 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_KA_PROBE_SENT (0x1<<26) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_KA_PROBE_SENT_SHIFT 26 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_PERSIST_PROBE_SENT (0x1<<27) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_PERSIST_PROBE_SENT_SHIFT 27 +#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<28) +#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 28 +#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<29) +#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 29 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK (0x1<<30) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK_SHIFT 30 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK (0x1<<31) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK_SHIFT 31 +#if defined(__BIG_ENDIAN) + u16 mss; + u8 tcp_sm_state; + u8 rto_exp; +#elif defined(__LITTLE_ENDIAN) + u8 rto_exp; + u8 tcp_sm_state; + u16 mss; +#endif + u32 rcv_nxt; + u32 timestamp_recent; + u32 timestamp_recent_time; + u32 cwnd; + u32 ss_thresh; + u32 cwnd_accum; + u32 prev_seg_seq; + u32 expected_rel_seq; + u32 recover; +#if defined(__BIG_ENDIAN) + u8 retransmit_count; + u8 ka_max_probe_count; + u8 persist_probe_count; + u8 ka_probe_count; #elif defined(__LITTLE_ENDIAN) - u8 rxmit_sge_idx; - u8 rxmit_flags; -#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD (0x1<<0) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD_SHIFT 0 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR (0x1<<1) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR_SHIFT 1 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU (0x1<<2) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU_SHIFT 2 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR (0x1<<3) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR_SHIFT 3 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR (0x1<<4) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR_SHIFT 4 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING (0x3<<5) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING_SHIFT 5 -#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT (0x1<<7) -#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT_SHIFT 7 - u16 r2tq_cons; + u8 ka_probe_count; + u8 persist_probe_count; + u8 ka_max_probe_count; + u8 retransmit_count; #endif - u32 hq_rxmit_tcp_seq; -}; - -/* - * Xstorm iSCSI Storm Context - */ -struct xstorm_iscsi_st_context { - struct xstorm_common_context_section common; - struct xstorm_iscsi_context_section iscsi; -}; - -/* - * CQ DB CQ producer and pending completion counter - */ -struct iscsi_cq_db_prod_pnd_cmpltn_cnt { #if defined(__BIG_ENDIAN) - u16 cntr; - u16 prod; + u8 statistics_counter_id; + u8 ooo_support_mode; + u8 snd_wnd_scale; + u8 dup_ack_count; #elif defined(__LITTLE_ENDIAN) - u16 prod; - u16 cntr; + u8 dup_ack_count; + u8 snd_wnd_scale; + u8 ooo_support_mode; + u8 statistics_counter_id; #endif -}; - -/* - * CQ DB pending completion ITT array - */ -struct iscsi_cq_db_prod_pnd_cmpltn_cnt_arr { - struct iscsi_cq_db_prod_pnd_cmpltn_cnt prod_pend_comp[8]; -}; - -/* - * Cstorm CQ sequence to notify array, updated by driver - */ -struct iscsi_cq_db_sqn_2_notify_arr { - u16 sqn[8]; -}; - -/* - * Cstorm iSCSI Storm Context - */ -struct cstorm_iscsi_st_context { - struct iscsi_cq_db_prod_pnd_cmpltn_cnt_arr cq_c_prod_pend_comp_ctr_arr; - struct iscsi_cq_db_sqn_2_notify_arr cq_c_prod_sqn_arr; - struct iscsi_cq_db_sqn_2_notify_arr cq_c_sqn_2_notify_arr; - struct regpair hq_pbl_base; - struct regpair hq_curr_pbe; - struct regpair task_pbl_base; - struct regpair cq_db_base; + u32 retransmit_start_time; + u32 ka_timeout; + u32 ka_interval; + u32 isle_start_seq; + u32 isle_end_seq; #if defined(__BIG_ENDIAN) - u16 hq_bd_itt; - u16 iscsi_conn_id; + u16 second_isle_address; + u16 recent_seg_wnd; #elif defined(__LITTLE_ENDIAN) - u16 iscsi_conn_id; - u16 hq_bd_itt; + u16 recent_seg_wnd; + u16 second_isle_address; #endif - u32 hq_bd_data_segment_len; - u32 hq_bd_buffer_offset; #if defined(__BIG_ENDIAN) - u8 timer_entry_idx; - u8 cq_proc_en_bit_map; - u8 cq_pend_comp_itt_valid_bit_map; - u8 hq_bd_opcode; + u8 max_isles_ever_happened; + u8 isles_number; + u16 last_isle_address; #elif defined(__LITTLE_ENDIAN) - u8 hq_bd_opcode; - u8 cq_pend_comp_itt_valid_bit_map; - u8 cq_proc_en_bit_map; - u8 timer_entry_idx; + u16 last_isle_address; + u8 isles_number; + u8 max_isles_ever_happened; #endif - u32 hq_tcp_seq; + u32 max_rt_time; #if defined(__BIG_ENDIAN) - u16 flags; -#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN (0x1<<0) -#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN_SHIFT 0 -#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN (0x1<<1) -#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN_SHIFT 1 -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID (0x1<<2) -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID_SHIFT 2 -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG (0x1<<3) -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG_SHIFT 3 -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK (0x1<<4) -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK_SHIFT 4 -#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV (0x7FF<<5) -#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV_SHIFT 5 - u16 hq_cons; + u16 lsb_mac_address; + u16 vlan_id; #elif defined(__LITTLE_ENDIAN) - u16 hq_cons; - u16 flags; -#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN (0x1<<0) -#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN_SHIFT 0 -#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN (0x1<<1) -#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN_SHIFT 1 -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID (0x1<<2) -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID_SHIFT 2 -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG (0x1<<3) -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG_SHIFT 3 -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK (0x1<<4) -#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK_SHIFT 4 -#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV (0x7FF<<5) -#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV_SHIFT 5 + u16 vlan_id; + u16 lsb_mac_address; #endif - struct regpair rsrv1; -}; - -/* - * Iscsi connection context - */ -struct iscsi_context { - struct ustorm_iscsi_st_context ustorm_st_context; - struct tstorm_iscsi_st_context tstorm_st_context; - struct xstorm_iscsi_ag_context xstorm_ag_context; - struct tstorm_iscsi_ag_context tstorm_ag_context; - struct cstorm_iscsi_ag_context cstorm_ag_context; - struct ustorm_iscsi_ag_context ustorm_ag_context; - struct timers_block_context timers_context; - struct regpair upb_context; - struct xstorm_iscsi_st_context xstorm_st_context; - struct regpair xpb_context; - struct cstorm_iscsi_st_context cstorm_st_context; +#if defined(__BIG_ENDIAN) + u16 msb_mac_address; + u16 mid_mac_address; +#elif defined(__LITTLE_ENDIAN) + u16 mid_mac_address; + u16 msb_mac_address; +#endif + u32 rightmost_received_seq; }; /* - * FCoE KCQ CQE parameters + * Termination variables */ -union fcoe_kcqe_params { - u32 reserved0[4]; +struct iscsi_term_vars { + u8 BitMap; +#define ISCSI_TERM_VARS_TCP_STATE (0xF<<0) +#define ISCSI_TERM_VARS_TCP_STATE_SHIFT 0 +#define ISCSI_TERM_VARS_FIN_RECEIVED_SBIT (0x1<<4) +#define ISCSI_TERM_VARS_FIN_RECEIVED_SBIT_SHIFT 4 +#define ISCSI_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT (0x1<<5) +#define ISCSI_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT_SHIFT 5 +#define ISCSI_TERM_VARS_TERM_ON_CHIP (0x1<<6) +#define ISCSI_TERM_VARS_TERM_ON_CHIP_SHIFT 6 +#define ISCSI_TERM_VARS_RSRV (0x1<<7) +#define ISCSI_TERM_VARS_RSRV_SHIFT 7 }; /* - * FCoE KCQ CQE + * iSCSI context region, used only in iSCSI */ -struct fcoe_kcqe { - u32 fcoe_conn_id; - u32 completion_status; - u32 fcoe_conn_context_id; - union fcoe_kcqe_params params; +struct tstorm_iscsi_st_context_section { + u32 nalPayload; + u32 b2nh; #if defined(__BIG_ENDIAN) + u16 rq_cons; u8 flags; -#define FCOE_KCQE_RESERVED0 (0x7<<0) -#define FCOE_KCQE_RESERVED0_SHIFT 0 -#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3) -#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3 -#define FCOE_KCQE_LAYER_CODE (0x7<<4) -#define FCOE_KCQE_LAYER_CODE_SHIFT 4 -#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7) -#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7 - u8 op_code; - u16 qe_self_seq; +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN (0x1<<0) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN_SHIFT 0 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN (0x1<<1) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN_SHIFT 1 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER (0x1<<2) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER_SHIFT 2 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE (0x1<<3) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE_SHIFT 3 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS (0x1<<4) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS_SHIFT 4 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_NALLEN (0x3<<5) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_NALLEN_SHIFT 5 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_RSRV0 (0x1<<7) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_RSRV0_SHIFT 7 + u8 hdr_bytes_2_fetch; #elif defined(__LITTLE_ENDIAN) - u16 qe_self_seq; - u8 op_code; + u8 hdr_bytes_2_fetch; u8 flags; -#define FCOE_KCQE_RESERVED0 (0x7<<0) -#define FCOE_KCQE_RESERVED0_SHIFT 0 -#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3) -#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3 -#define FCOE_KCQE_LAYER_CODE (0x7<<4) -#define FCOE_KCQE_LAYER_CODE_SHIFT 4 -#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7) -#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN (0x1<<0) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN_SHIFT 0 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN (0x1<<1) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN_SHIFT 1 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER (0x1<<2) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER_SHIFT 2 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE (0x1<<3) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE_SHIFT 3 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS (0x1<<4) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS_SHIFT 4 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_NALLEN (0x3<<5) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_NALLEN_SHIFT 5 +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_RSRV0 (0x1<<7) +#define TSTORM_ISCSI_ST_CONTEXT_SECTION_RSRV0_SHIFT 7 + u16 rq_cons; +#endif + struct regpair rq_db_phy_addr; +#if defined(__BIG_ENDIAN) + struct iscsi_term_vars term_vars; + u8 rsrv1; + u16 iscsi_conn_id; +#elif defined(__LITTLE_ENDIAN) + u16 iscsi_conn_id; + u8 rsrv1; + struct iscsi_term_vars term_vars; #endif + u32 process_nxt; }; /* - * FCoE KWQE header + * The iSCSI non-aggregative context of Tstorm */ -struct fcoe_kwqe_header { -#if defined(__BIG_ENDIAN) - u8 flags; -#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0) -#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0 -#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4) -#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4 -#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7) -#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7 - u8 op_code; -#elif defined(__LITTLE_ENDIAN) - u8 op_code; - u8 flags; -#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0) -#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0 -#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4) -#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4 -#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7) -#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7 -#endif +struct tstorm_iscsi_st_context { + struct tstorm_tcp_st_context_section tcp; + struct tstorm_iscsi_st_context_section iscsi; }; /* - * FCoE firmware init request 1 + * Ethernet context section, shared in TOE, RDMA and ISCSI */ -struct fcoe_kwqe_init1 { +struct xstorm_eth_context_section { #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 num_tasks; + u8 remote_addr_4; + u8 remote_addr_5; + u8 local_addr_0; + u8 local_addr_1; #elif defined(__LITTLE_ENDIAN) - u16 num_tasks; - struct fcoe_kwqe_header hdr; + u8 local_addr_1; + u8 local_addr_0; + u8 remote_addr_5; + u8 remote_addr_4; #endif - u32 task_list_pbl_addr_lo; - u32 task_list_pbl_addr_hi; - u32 dummy_buffer_addr_lo; - u32 dummy_buffer_addr_hi; #if defined(__BIG_ENDIAN) - u16 rq_num_wqes; - u16 sq_num_wqes; + u8 remote_addr_0; + u8 remote_addr_1; + u8 remote_addr_2; + u8 remote_addr_3; #elif defined(__LITTLE_ENDIAN) - u16 sq_num_wqes; - u16 rq_num_wqes; + u8 remote_addr_3; + u8 remote_addr_2; + u8 remote_addr_1; + u8 remote_addr_0; #endif #if defined(__BIG_ENDIAN) - u16 cq_num_wqes; - u16 rq_buffer_log_size; + u16 reserved_vlan_type; + u16 params; +#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) +#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 +#define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12) +#define XSTORM_ETH_CONTEXT_SECTION_CFI_SHIFT 12 +#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) +#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 #elif defined(__LITTLE_ENDIAN) - u16 rq_buffer_log_size; - u16 cq_num_wqes; + u16 params; +#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0) +#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0 +#define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12) +#define XSTORM_ETH_CONTEXT_SECTION_CFI_SHIFT 12 +#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13) +#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13 + u16 reserved_vlan_type; #endif #if defined(__BIG_ENDIAN) - u8 flags; -#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0) -#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0 -#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4) -#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4 -#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7) -#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7 - u8 num_sessions_log; - u16 mtu; + u8 local_addr_2; + u8 local_addr_3; + u8 local_addr_4; + u8 local_addr_5; #elif defined(__LITTLE_ENDIAN) - u16 mtu; - u8 num_sessions_log; - u8 flags; -#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0) -#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0 -#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4) -#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4 -#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7) -#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7 + u8 local_addr_5; + u8 local_addr_4; + u8 local_addr_3; + u8 local_addr_2; #endif }; /* - * FCoE firmware init request 2 + * IpV4 context section, shared in TOE, RDMA and ISCSI */ -struct fcoe_kwqe_init2 { +struct xstorm_ip_v4_context_section { #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; + u16 __pbf_hdr_cmd_rsvd_id; + u16 __pbf_hdr_cmd_rsvd_flags_offset; #elif defined(__LITTLE_ENDIAN) - u16 reserved0; - struct fcoe_kwqe_header hdr; + u16 __pbf_hdr_cmd_rsvd_flags_offset; + u16 __pbf_hdr_cmd_rsvd_id; #endif - u32 hash_tbl_pbl_addr_lo; - u32 hash_tbl_pbl_addr_hi; - u32 t2_hash_tbl_addr_lo; - u32 t2_hash_tbl_addr_hi; - u32 t2_ptr_hash_tbl_addr_lo; - u32 t2_ptr_hash_tbl_addr_hi; - u32 free_list_count; -}; - -/* - * FCoE firmware init request 3 - */ -struct fcoe_kwqe_init3 { #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; + u8 __pbf_hdr_cmd_rsvd_ver_ihl; + u8 tos; + u16 __pbf_hdr_cmd_rsvd_length; #elif defined(__LITTLE_ENDIAN) - u16 reserved0; - struct fcoe_kwqe_header hdr; + u16 __pbf_hdr_cmd_rsvd_length; + u8 tos; + u8 __pbf_hdr_cmd_rsvd_ver_ihl; #endif - u32 error_bit_map_lo; - u32 error_bit_map_hi; + u32 ip_local_addr; #if defined(__BIG_ENDIAN) - u8 reserved21[3]; - u8 cached_session_enable; + u8 ttl; + u8 __pbf_hdr_cmd_rsvd_protocol; + u16 __pbf_hdr_cmd_rsvd_csum; #elif defined(__LITTLE_ENDIAN) - u8 cached_session_enable; - u8 reserved21[3]; + u16 __pbf_hdr_cmd_rsvd_csum; + u8 __pbf_hdr_cmd_rsvd_protocol; + u8 ttl; #endif - u32 reserved2[4]; + u32 __pbf_hdr_cmd_rsvd_1; + u32 ip_remote_addr; }; /* - * FCoE connection offload request 1 + * context section, shared in TOE, RDMA and ISCSI */ -struct fcoe_kwqe_conn_offload1 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 fcoe_conn_id; -#elif defined(__LITTLE_ENDIAN) - u16 fcoe_conn_id; - struct fcoe_kwqe_header hdr; -#endif - u32 sq_addr_lo; - u32 sq_addr_hi; - u32 rq_pbl_addr_lo; - u32 rq_pbl_addr_hi; - u32 rq_first_pbe_addr_lo; - u32 rq_first_pbe_addr_hi; -#if defined(__BIG_ENDIAN) - u16 reserved0; - u16 rq_prod; -#elif defined(__LITTLE_ENDIAN) - u16 rq_prod; - u16 reserved0; -#endif +struct xstorm_padded_ip_v4_context_section { + struct xstorm_ip_v4_context_section ip_v4; + u32 reserved1[4]; }; /* - * FCoE connection offload request 2 + * IpV6 context section, shared in TOE, RDMA and ISCSI */ -struct fcoe_kwqe_conn_offload2 { +struct xstorm_ip_v6_context_section { #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 tx_max_fc_pay_len; + u16 pbf_hdr_cmd_rsvd_payload_len; + u8 pbf_hdr_cmd_rsvd_nxt_hdr; + u8 hop_limit; #elif defined(__LITTLE_ENDIAN) - u16 tx_max_fc_pay_len; - struct fcoe_kwqe_header hdr; + u8 hop_limit; + u8 pbf_hdr_cmd_rsvd_nxt_hdr; + u16 pbf_hdr_cmd_rsvd_payload_len; #endif - u32 cq_addr_lo; - u32 cq_addr_hi; - u32 xferq_addr_lo; - u32 xferq_addr_hi; - u32 conn_db_addr_lo; - u32 conn_db_addr_hi; - u32 reserved1; + u32 priority_flow_label; +#define XSTORM_IP_V6_CONTEXT_SECTION_FLOW_LABEL (0xFFFFF<<0) +#define XSTORM_IP_V6_CONTEXT_SECTION_FLOW_LABEL_SHIFT 0 +#define XSTORM_IP_V6_CONTEXT_SECTION_TRAFFIC_CLASS (0xFF<<20) +#define XSTORM_IP_V6_CONTEXT_SECTION_TRAFFIC_CLASS_SHIFT 20 +#define XSTORM_IP_V6_CONTEXT_SECTION_PBF_HDR_CMD_RSVD_VER (0xF<<28) +#define XSTORM_IP_V6_CONTEXT_SECTION_PBF_HDR_CMD_RSVD_VER_SHIFT 28 + u32 ip_local_addr_lo_hi; + u32 ip_local_addr_lo_lo; + u32 ip_local_addr_hi_hi; + u32 ip_local_addr_hi_lo; + u32 ip_remote_addr_lo_hi; + u32 ip_remote_addr_lo_lo; + u32 ip_remote_addr_hi_hi; + u32 ip_remote_addr_hi_lo; +}; + +union xstorm_ip_context_section_types { + struct xstorm_padded_ip_v4_context_section padded_ip_v4; + struct xstorm_ip_v6_context_section ip_v6; }; /* - * FCoE connection offload request 3 + * TCP context section, shared in TOE, RDMA and ISCSI */ -struct fcoe_kwqe_conn_offload3 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 vlan_tag; -#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0) -#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0 -#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12) -#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12 -#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13) -#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13 -#elif defined(__LITTLE_ENDIAN) - u16 vlan_tag; -#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0) -#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0 -#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12) -#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12 -#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13) -#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13 - struct fcoe_kwqe_header hdr; -#endif +struct xstorm_tcp_context_section { + u32 snd_max; #if defined(__BIG_ENDIAN) - u8 tx_max_conc_seqs_c3; - u8 s_id[3]; + u16 remote_port; + u16 local_port; #elif defined(__LITTLE_ENDIAN) - u8 s_id[3]; - u8 tx_max_conc_seqs_c3; + u16 local_port; + u16 remote_port; #endif #if defined(__BIG_ENDIAN) - u8 flags; -#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0) -#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0 -#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1) -#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1 -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2) -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2 -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3) -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3 -#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4) -#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4 -#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5) -#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5 -#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6) -#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6 -#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7) -#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7 - u8 d_id[3]; + u8 original_nagle_1b; + u8 ts_enabled; + u16 tcp_params; +#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0) +#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0 +#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT (0x1<<8) +#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT_SHIFT 8 +#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED (0x1<<9) +#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 +#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) +#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) +#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 +#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) +#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13 +#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14) +#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14 #elif defined(__LITTLE_ENDIAN) - u8 d_id[3]; - u8 flags; -#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0) -#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0 -#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1) -#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1 -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2) -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2 -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3) -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3 -#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4) -#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4 -#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5) -#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5 -#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6) -#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6 -#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7) -#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7 + u16 tcp_params; +#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0) +#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0 +#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT (0x1<<8) +#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT_SHIFT 8 +#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED (0x1<<9) +#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 +#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) +#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) +#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 +#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) +#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13 +#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14) +#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14 + u8 ts_enabled; + u8 original_nagle_1b; #endif - u32 reserved; - u32 confq_first_pbe_addr_lo; - u32 confq_first_pbe_addr_hi; #if defined(__BIG_ENDIAN) - u16 rx_max_fc_pay_len; - u16 tx_total_conc_seqs; + u16 pseudo_csum; + u16 window_scaling_factor; #elif defined(__LITTLE_ENDIAN) - u16 tx_total_conc_seqs; - u16 rx_max_fc_pay_len; + u16 window_scaling_factor; + u16 pseudo_csum; #endif #if defined(__BIG_ENDIAN) - u8 rx_open_seqs_exch_c3; - u8 rx_max_conc_seqs_c3; - u16 rx_total_conc_seqs; + u16 reserved2; + u8 statistics_counter_id; + u8 statistics_params; +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<0) +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 0 +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<1) +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 +#define XSTORM_TCP_CONTEXT_SECTION_RESERVED (0x3F<<2) +#define XSTORM_TCP_CONTEXT_SECTION_RESERVED_SHIFT 2 #elif defined(__LITTLE_ENDIAN) - u16 rx_total_conc_seqs; - u8 rx_max_conc_seqs_c3; - u8 rx_open_seqs_exch_c3; + u8 statistics_params; +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<0) +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 0 +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<1) +#define XSTORM_TCP_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 +#define XSTORM_TCP_CONTEXT_SECTION_RESERVED (0x3F<<2) +#define XSTORM_TCP_CONTEXT_SECTION_RESERVED_SHIFT 2 + u8 statistics_counter_id; + u16 reserved2; #endif + u32 ts_time_diff; + u32 __next_timer_expir; }; /* - * FCoE connection offload request 4 + * Common context section, shared in TOE, RDMA and ISCSI */ -struct fcoe_kwqe_conn_offload4 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u8 reserved2; - u8 e_d_tov_timer_val; -#elif defined(__LITTLE_ENDIAN) - u8 e_d_tov_timer_val; - u8 reserved2; - struct fcoe_kwqe_header hdr; -#endif - u8 src_mac_addr_lo32[4]; +struct xstorm_common_context_section { + struct xstorm_eth_context_section ethernet; + union xstorm_ip_context_section_types ip_union; + struct xstorm_tcp_context_section tcp; #if defined(__BIG_ENDIAN) - u8 dst_mac_addr_hi16[2]; - u8 src_mac_addr_hi16[2]; + u8 __dcb_val; + u8 flags; +#define XSTORM_COMMON_CONTEXT_SECTION_PHYSQ_INITIALIZED (0x1<<0) +#define XSTORM_COMMON_CONTEXT_SECTION_PHYSQ_INITIALIZED_SHIFT 0 +#define XSTORM_COMMON_CONTEXT_SECTION_PBF_PORT (0x7<<1) +#define XSTORM_COMMON_CONTEXT_SECTION_PBF_PORT_SHIFT 1 +#define XSTORM_COMMON_CONTEXT_SECTION_VLAN_MODE (0x1<<4) +#define XSTORM_COMMON_CONTEXT_SECTION_VLAN_MODE_SHIFT 4 +#define XSTORM_COMMON_CONTEXT_SECTION_ORIGINAL_PRIORITY (0x7<<5) +#define XSTORM_COMMON_CONTEXT_SECTION_ORIGINAL_PRIORITY_SHIFT 5 + u8 reserved; + u8 ip_version_1b; #elif defined(__LITTLE_ENDIAN) - u8 src_mac_addr_hi16[2]; - u8 dst_mac_addr_hi16[2]; + u8 ip_version_1b; + u8 reserved; + u8 flags; +#define XSTORM_COMMON_CONTEXT_SECTION_PHYSQ_INITIALIZED (0x1<<0) +#define XSTORM_COMMON_CONTEXT_SECTION_PHYSQ_INITIALIZED_SHIFT 0 +#define XSTORM_COMMON_CONTEXT_SECTION_PBF_PORT (0x7<<1) +#define XSTORM_COMMON_CONTEXT_SECTION_PBF_PORT_SHIFT 1 +#define XSTORM_COMMON_CONTEXT_SECTION_VLAN_MODE (0x1<<4) +#define XSTORM_COMMON_CONTEXT_SECTION_VLAN_MODE_SHIFT 4 +#define XSTORM_COMMON_CONTEXT_SECTION_ORIGINAL_PRIORITY (0x7<<5) +#define XSTORM_COMMON_CONTEXT_SECTION_ORIGINAL_PRIORITY_SHIFT 5 + u8 __dcb_val; #endif - u8 dst_mac_addr_lo32[4]; - u32 lcq_addr_lo; - u32 lcq_addr_hi; - u32 confq_pbl_base_addr_lo; - u32 confq_pbl_base_addr_hi; }; /* - * FCoE connection enable request + * Flags used in ISCSI context section */ -struct fcoe_kwqe_conn_enable_disable { +struct xstorm_iscsi_context_flags { + u8 flags; +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA (0x1<<0) +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA_SHIFT 0 +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T (0x1<<1) +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T_SHIFT 1 +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_HEADER_DIGEST (0x1<<2) +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_HEADER_DIGEST_SHIFT 2 +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_DATA_DIGEST (0x1<<3) +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_DATA_DIGEST_SHIFT 3 +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_HQ_BD_WRITTEN (0x1<<4) +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_HQ_BD_WRITTEN_SHIFT 4 +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_LAST_OP_SQ (0x1<<5) +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_LAST_OP_SQ_SHIFT 5 +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_UPDATE_SND_NXT (0x1<<6) +#define XSTORM_ISCSI_CONTEXT_FLAGS_B_UPDATE_SND_NXT_SHIFT 6 +#define XSTORM_ISCSI_CONTEXT_FLAGS_RESERVED4 (0x1<<7) +#define XSTORM_ISCSI_CONTEXT_FLAGS_RESERVED4_SHIFT 7 +}; + +struct iscsi_task_context_entry_x { + u32 data_out_buffer_offset; + u32 itt; + u32 data_sn; +}; + +struct iscsi_task_context_entry_xuc_x_write_only { + u32 tx_r2t_sn; +}; + +struct iscsi_task_context_entry_xuc_xu_write_both { + u32 sgl_base_lo; + u32 sgl_base_hi; #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; + u8 sgl_size; + u8 sge_index; + u16 sge_offset; #elif defined(__LITTLE_ENDIAN) - u16 reserved0; - struct fcoe_kwqe_header hdr; + u16 sge_offset; + u8 sge_index; + u8 sgl_size; #endif - u8 src_mac_addr_lo32[4]; +}; + +/* + * iSCSI context section + */ +struct xstorm_iscsi_context_section { + u32 first_burst_length; + u32 max_send_pdu_length; + struct regpair sq_pbl_base; + struct regpair sq_curr_pbe; + struct regpair hq_pbl_base; + struct regpair hq_curr_pbe_base; + struct regpair r2tq_pbl_base; + struct regpair r2tq_curr_pbe_base; + struct regpair task_pbl_base; #if defined(__BIG_ENDIAN) - u16 vlan_tag; -#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0 -#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12 -#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13 - u8 src_mac_addr_hi16[2]; + u16 data_out_count; + struct xstorm_iscsi_context_flags flags; + u8 task_pbl_cache_idx; #elif defined(__LITTLE_ENDIAN) - u8 src_mac_addr_hi16[2]; - u16 vlan_tag; -#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0 -#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12 -#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13 + u8 task_pbl_cache_idx; + struct xstorm_iscsi_context_flags flags; + u16 data_out_count; #endif - u8 dst_mac_addr_lo32[4]; + u32 seq_more_2_send; + u32 pdu_more_2_send; + struct iscsi_task_context_entry_x temp_tce_x; + struct iscsi_task_context_entry_xuc_x_write_only temp_tce_x_wr; + struct iscsi_task_context_entry_xuc_xu_write_both temp_tce_xu_wr; + struct regpair lun; + u32 exp_data_transfer_len_ttt; + u32 pdu_data_2_rxmit; + u32 rxmit_bytes_2_dr; #if defined(__BIG_ENDIAN) - u16 reserved1; - u8 dst_mac_addr_hi16[2]; + u16 rxmit_sge_offset; + u16 hq_rxmit_cons; #elif defined(__LITTLE_ENDIAN) - u8 dst_mac_addr_hi16[2]; - u16 reserved1; + u16 hq_rxmit_cons; + u16 rxmit_sge_offset; #endif #if defined(__BIG_ENDIAN) - u8 vlan_flag; - u8 s_id[3]; + u16 r2tq_cons; + u8 rxmit_flags; +#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD (0x1<<0) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD_SHIFT 0 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR (0x1<<1) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR_SHIFT 1 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU (0x1<<2) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU_SHIFT 2 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR (0x1<<3) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR_SHIFT 3 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR (0x1<<4) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR_SHIFT 4 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING (0x3<<5) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING_SHIFT 5 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT (0x1<<7) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT_SHIFT 7 + u8 rxmit_sge_idx; #elif defined(__LITTLE_ENDIAN) - u8 s_id[3]; - u8 vlan_flag; + u8 rxmit_sge_idx; + u8 rxmit_flags; +#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD (0x1<<0) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD_SHIFT 0 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR (0x1<<1) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR_SHIFT 1 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU (0x1<<2) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU_SHIFT 2 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR (0x1<<3) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR_SHIFT 3 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR (0x1<<4) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR_SHIFT 4 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING (0x3<<5) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING_SHIFT 5 +#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT (0x1<<7) +#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT_SHIFT 7 + u16 r2tq_cons; #endif + u32 hq_rxmit_tcp_seq; +}; + +/* + * Xstorm iSCSI Storm Context + */ +struct xstorm_iscsi_st_context { + struct xstorm_common_context_section common; + struct xstorm_iscsi_context_section iscsi; +}; + +/* + * Iscsi connection context + */ +struct iscsi_context { + struct ustorm_iscsi_st_context ustorm_st_context; + struct tstorm_iscsi_st_context tstorm_st_context; + struct xstorm_iscsi_ag_context xstorm_ag_context; + struct tstorm_iscsi_ag_context tstorm_ag_context; + struct cstorm_iscsi_ag_context cstorm_ag_context; + struct ustorm_iscsi_ag_context ustorm_ag_context; + struct timers_block_context timers_context; + struct regpair upb_context; + struct xstorm_iscsi_st_context xstorm_st_context; + struct regpair xpb_context; + struct cstorm_iscsi_st_context cstorm_st_context; +}; + + +/* + * PDU header of an iSCSI DATA-OUT + */ +struct iscsi_data_pdu_hdr_little_endian { #if defined(__BIG_ENDIAN) - u8 reserved3; - u8 d_id[3]; + u8 opcode; + u8 op_attr; +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_RSRV1 (0x7F<<0) +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 0 +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG (0x1<<7) +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG_SHIFT 7 + u16 rsrv0; #elif defined(__LITTLE_ENDIAN) - u8 d_id[3]; - u8 reserved3; + u16 rsrv0; + u8 op_attr; +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_RSRV1 (0x7F<<0) +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 0 +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG (0x1<<7) +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_FINAL_FLAG_SHIFT 7 + u8 opcode; #endif - u32 context_id; - u32 conn_id; - u32 reserved4; + u32 data_fields; +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH (0xFFFFFF<<0) +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH_SHIFT 0 +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH (0xFF<<24) +#define ISCSI_DATA_PDU_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH_SHIFT 24 + struct regpair lun; + u32 itt; + u32 ttt; + u32 rsrv2; + u32 exp_stat_sn; + u32 rsrv3; + u32 data_sn; + u32 buffer_offset; + u32 rsrv4; }; + /* - * FCoE connection destroy request + * PDU header of an iSCSI login request */ -struct fcoe_kwqe_conn_destroy { +struct iscsi_login_req_hdr_little_endian { #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; + u8 opcode; + u8 op_attr; +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_NSG (0x3<<0) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_NSG_SHIFT 0 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CSG (0x3<<2) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CSG_SHIFT 2 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_RSRV0 (0x3<<4) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_RSRV0_SHIFT 4 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG (0x1<<6) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG_SHIFT 6 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_TRANSIT (0x1<<7) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_TRANSIT_SHIFT 7 + u8 version_max; + u8 version_min; +#elif defined(__LITTLE_ENDIAN) + u8 version_min; + u8 version_max; + u8 op_attr; +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_NSG (0x3<<0) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_NSG_SHIFT 0 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CSG (0x3<<2) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CSG_SHIFT 2 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_RSRV0 (0x3<<4) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_RSRV0_SHIFT 4 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG (0x1<<6) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG_SHIFT 6 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_TRANSIT (0x1<<7) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_TRANSIT_SHIFT 7 + u8 opcode; +#endif + u32 data_fields; +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH (0xFFFFFF<<0) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH_SHIFT 0 +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH (0xFF<<24) +#define ISCSI_LOGIN_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH_SHIFT 24 + u32 isid_lo; +#if defined(__BIG_ENDIAN) + u16 isid_hi; + u16 tsih; #elif defined(__LITTLE_ENDIAN) - u16 reserved0; - struct fcoe_kwqe_header hdr; + u16 tsih; + u16 isid_hi; #endif - u32 context_id; - u32 conn_id; - u32 reserved1[5]; + u32 itt; +#if defined(__BIG_ENDIAN) + u16 cid; + u16 rsrv1; +#elif defined(__LITTLE_ENDIAN) + u16 rsrv1; + u16 cid; +#endif + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsrv2[4]; }; /* - * FCoe destroy request + * PDU header of an iSCSI logout request */ -struct fcoe_kwqe_destroy { +struct iscsi_logout_req_hdr_little_endian { #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; + u8 opcode; + u8 op_attr; +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_REASON_CODE (0x7F<<0) +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_REASON_CODE_SHIFT 0 +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_RSRV1_1 (0x1<<7) +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_RSRV1_1_SHIFT 7 + u16 rsrv0; #elif defined(__LITTLE_ENDIAN) - u16 reserved0; - struct fcoe_kwqe_header hdr; + u16 rsrv0; + u8 op_attr; +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_REASON_CODE (0x7F<<0) +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_REASON_CODE_SHIFT 0 +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_RSRV1_1 (0x1<<7) +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_RSRV1_1_SHIFT 7 + u8 opcode; +#endif + u32 data_fields; +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH (0xFFFFFF<<0) +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH_SHIFT 0 +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH (0xFF<<24) +#define ISCSI_LOGOUT_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH_SHIFT 24 + u32 rsrv2[2]; + u32 itt; +#if defined(__BIG_ENDIAN) + u16 cid; + u16 rsrv1; +#elif defined(__LITTLE_ENDIAN) + u16 rsrv1; + u16 cid; #endif - u32 reserved1[7]; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsrv3[4]; }; /* - * FCoe statistics request + * PDU header of an iSCSI TMF request */ -struct fcoe_kwqe_stat { +struct iscsi_tmf_req_hdr_little_endian { #if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; + u8 opcode; + u8 op_attr; +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_FUNCTION (0x7F<<0) +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_FUNCTION_SHIFT 0 +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_RSRV1_1 (0x1<<7) +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_RSRV1_1_SHIFT 7 + u16 rsrv0; #elif defined(__LITTLE_ENDIAN) - u16 reserved0; - struct fcoe_kwqe_header hdr; + u16 rsrv0; + u8 op_attr; +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_FUNCTION (0x7F<<0) +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_FUNCTION_SHIFT 0 +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_RSRV1_1 (0x1<<7) +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_RSRV1_1_SHIFT 7 + u8 opcode; #endif - u32 stat_params_addr_lo; - u32 stat_params_addr_hi; - u32 reserved1[5]; + u32 data_fields; +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH (0xFFFFFF<<0) +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH_SHIFT 0 +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH (0xFF<<24) +#define ISCSI_TMF_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH_SHIFT 24 + struct regpair lun; + u32 itt; + u32 referenced_task_tag; + u32 cmd_sn; + u32 exp_stat_sn; + u32 ref_cmd_sn; + u32 exp_data_sn; + u32 rsrv2[2]; }; /* - * FCoE KWQ WQE + * PDU header of an iSCSI Text request */ -union fcoe_kwqe { - struct fcoe_kwqe_init1 init1; - struct fcoe_kwqe_init2 init2; - struct fcoe_kwqe_init3 init3; - struct fcoe_kwqe_conn_offload1 conn_offload1; - struct fcoe_kwqe_conn_offload2 conn_offload2; - struct fcoe_kwqe_conn_offload3 conn_offload3; - struct fcoe_kwqe_conn_offload4 conn_offload4; - struct fcoe_kwqe_conn_enable_disable conn_enable_disable; - struct fcoe_kwqe_conn_destroy conn_destroy; - struct fcoe_kwqe_destroy destroy; - struct fcoe_kwqe_stat statistics; -}; - -struct fcoe_task_ctx_entry { - struct fcoe_task_ctx_entry_tx_only tx_wr_only; - struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd; - struct fcoe_task_ctx_entry_tx_rx_cmn cmn; - struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd; - struct fcoe_task_ctx_entry_rx_only rx_wr_only; - u32 reserved[4]; +struct iscsi_text_req_hdr_little_endian { +#if defined(__BIG_ENDIAN) + u8 opcode; + u8 op_attr; +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_RSRV1 (0x3F<<0) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 0 +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG (0x1<<6) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG_SHIFT 6 +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_FINAL (0x1<<7) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_FINAL_SHIFT 7 + u16 rsrv0; +#elif defined(__LITTLE_ENDIAN) + u16 rsrv0; + u8 op_attr; +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_RSRV1 (0x3F<<0) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 0 +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG (0x1<<6) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_CONTINUE_FLG_SHIFT 6 +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_FINAL (0x1<<7) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_FINAL_SHIFT 7 + u8 opcode; +#endif + u32 data_fields; +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH (0xFFFFFF<<0) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH_SHIFT 0 +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH (0xFF<<24) +#define ISCSI_TEXT_REQ_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH_SHIFT 24 + struct regpair lun; + u32 itt; + u32 ttt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsrv3[4]; }; /* - * FCoE connection enable\disable params passed by driver to FW in FCoE enable ramrod + * PDU header of an iSCSI Nop-Out */ -struct fcoe_conn_enable_disable_ramrod_params { - struct fcoe_kwqe_conn_enable_disable enable_disable_kwqe; +struct iscsi_nop_out_hdr_little_endian { +#if defined(__BIG_ENDIAN) + u8 opcode; + u8 op_attr; +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV1 (0x7F<<0) +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 0 +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV2_1 (0x1<<7) +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV2_1_SHIFT 7 + u16 rsrv0; +#elif defined(__LITTLE_ENDIAN) + u16 rsrv0; + u8 op_attr; +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV1 (0x7F<<0) +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV1_SHIFT 0 +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV2_1 (0x1<<7) +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_RSRV2_1_SHIFT 7 + u8 opcode; +#endif + u32 data_fields; +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH (0xFFFFFF<<0) +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_DATA_SEGMENT_LENGTH_SHIFT 0 +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH (0xFF<<24) +#define ISCSI_NOP_OUT_HDR_LITTLE_ENDIAN_TOTAL_AHS_LENGTH_SHIFT 24 + struct regpair lun; + u32 itt; + u32 ttt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsrv3[4]; }; - /* - * FCoE connection offload params passed by driver to FW in FCoE offload ramrod + * iscsi pdu headers in little endian form. */ -struct fcoe_conn_offload_ramrod_params { - struct fcoe_kwqe_conn_offload1 offload_kwqe1; - struct fcoe_kwqe_conn_offload2 offload_kwqe2; - struct fcoe_kwqe_conn_offload3 offload_kwqe3; - struct fcoe_kwqe_conn_offload4 offload_kwqe4; +union iscsi_pdu_headers_little_endian { + u32 fullHeaderSize[12]; + struct iscsi_cmd_pdu_hdr_little_endian command_pdu_hdr; + struct iscsi_data_pdu_hdr_little_endian data_out_pdu_hdr; + struct iscsi_login_req_hdr_little_endian login_req_pdu_hdr; + struct iscsi_logout_req_hdr_little_endian logout_req_pdu_hdr; + struct iscsi_tmf_req_hdr_little_endian tmf_req_pdu_hdr; + struct iscsi_text_req_hdr_little_endian text_req_pdu_hdr; + struct iscsi_nop_out_hdr_little_endian nop_out_pdu_hdr; }; -/* - * FCoE init params passed by driver to FW in FCoE init ramrod - */ -struct fcoe_init_ramrod_params { - struct fcoe_kwqe_init1 init_kwqe1; - struct fcoe_kwqe_init2 init_kwqe2; - struct fcoe_kwqe_init3 init_kwqe3; - struct regpair eq_addr; - struct regpair eq_next_page_addr; +struct iscsi_hq_bd { + union iscsi_pdu_headers_little_endian pdu_header; #if defined(__BIG_ENDIAN) - u16 sb_num; - u16 eq_prod; + u16 reserved1; + u16 lcl_cmp_flg; #elif defined(__LITTLE_ENDIAN) - u16 eq_prod; - u16 sb_num; + u16 lcl_cmp_flg; + u16 reserved1; #endif + u32 sgl_base_lo; + u32 sgl_base_hi; #if defined(__BIG_ENDIAN) - u16 reserved1; - u8 reserved0; - u8 sb_id; + u8 sgl_size; + u8 sge_index; + u16 sge_offset; #elif defined(__LITTLE_ENDIAN) - u8 sb_id; - u8 reserved0; - u16 reserved1; + u16 sge_offset; + u8 sge_index; + u8 sgl_size; #endif }; /* - * FCoE statistics params buffer passed by driver to FW in FCoE statistics ramrod + * CQE data for L2 OOO connection $$KEEP_ENDIANNESS$$ */ -struct fcoe_stat_ramrod_params { - struct fcoe_kwqe_stat stat_kwqe; +struct iscsi_l2_ooo_data { + __le32 iscsi_cid; + u8 drop_isle; + u8 drop_size; + u8 ooo_opcode; + u8 ooo_isle; + u8 reserved[8]; }; -/* - * FCoE 16-bits vlan structure - */ -struct fcoe_vlan_fields { - u16 fields; -#define FCOE_VLAN_FIELDS_VID (0xFFF<<0) -#define FCOE_VLAN_FIELDS_VID_SHIFT 0 -#define FCOE_VLAN_FIELDS_CLI (0x1<<12) -#define FCOE_VLAN_FIELDS_CLI_SHIFT 12 -#define FCOE_VLAN_FIELDS_PRI (0x7<<13) -#define FCOE_VLAN_FIELDS_PRI_SHIFT 13 -}; -/* - * FCoE 16-bits vlan union - */ -union fcoe_vlan_field_union { - struct fcoe_vlan_fields fields; - u16 val; + + +struct iscsi_task_context_entry_xuc_c_write_only { + u32 total_data_acked; }; -/* - * Parameters used for Class 2 verifications - */ -struct ustorm_fcoe_c2_params { -#if defined(__BIG_ENDIAN) - u16 e2e_credit; - u16 con_seq; -#elif defined(__LITTLE_ENDIAN) - u16 con_seq; - u16 e2e_credit; -#endif +struct iscsi_task_context_r2t_table_entry { + u32 ttt; + u32 desired_data_len; +}; + +struct iscsi_task_context_entry_xuc_u_write_only { + u32 exp_r2t_sn; + struct iscsi_task_context_r2t_table_entry r2t_table[4]; #if defined(__BIG_ENDIAN) - u16 ackq_prod; - u16 open_seq_per_exch; + u16 data_in_count; + u8 cq_id; + u8 valid_1b; #elif defined(__LITTLE_ENDIAN) - u16 open_seq_per_exch; - u16 ackq_prod; + u8 valid_1b; + u8 cq_id; + u16 data_in_count; #endif - struct regpair ackq_pbl_base; - struct regpair ackq_cur_seg; }; -/* - * Parameters used for Class 2 verifications - */ -struct xstorm_fcoe_c2_params { +struct iscsi_task_context_entry_xuc { + struct iscsi_task_context_entry_xuc_c_write_only write_c; + u32 exp_data_transfer_len; + struct iscsi_task_context_entry_xuc_x_write_only write_x; + u32 lun_lo; + struct iscsi_task_context_entry_xuc_xu_write_both write_xu; + u32 lun_hi; + struct iscsi_task_context_entry_xuc_u_write_only write_u; +}; + +struct iscsi_task_context_entry_u { + u32 exp_r2t_buff_offset; + u32 rem_rcv_len; + u32 exp_data_sn; +}; + +struct iscsi_task_context_entry { + struct iscsi_task_context_entry_x tce_x; #if defined(__BIG_ENDIAN) - u16 reserved0; - u8 ackq_x_prod; - u8 max_conc_seqs_c2; + u16 data_out_count; + u16 rsrv0; #elif defined(__LITTLE_ENDIAN) - u8 max_conc_seqs_c2; - u8 ackq_x_prod; - u16 reserved0; + u16 rsrv0; + u16 data_out_count; #endif - struct regpair ackq_pbl_base; - struct regpair ackq_cur_seg; + struct iscsi_task_context_entry_xuc tce_xuc; + struct iscsi_task_context_entry_u tce_u; + u32 rsrv1[7]; }; -/* - * Buffer per connection, used in Tstorm - */ -struct iscsi_conn_buf { - struct regpair reserved[8]; + + + + + + + +struct iscsi_task_context_entry_xuc_x_init_only { + struct regpair lun; + u32 exp_data_transfer_len; }; + + + + + + + + + + + + + + + + /* * ipv6 structure */ @@ -4379,6 +5067,8 @@ struct ip_v6_addr { u32 ip_addr_hi_hi; }; + + /* * l5cm- connection identification params */ @@ -4460,8 +5150,7 @@ struct l5cm_xstorm_conn_buffer { * l5cm-tstorm connection buffer */ struct l5cm_tstorm_conn_buffer { - u32 snd_buf; - u32 rcv_buf; + u32 rsrv1[2]; #if defined(__BIG_ENDIAN) u16 params; #define L5CM_TSTORM_CONN_BUFFER_DELAYED_ACK_ENABLE (0x1<<0) @@ -4493,6 +5182,72 @@ struct l5cm_active_conn_buffer { struct l5cm_tstorm_conn_buffer tstorm_conn_buffer; }; + + +/* + * The l5cm opaque buffer passed in add new connection ramrod passive side + */ +struct l5cm_hash_input_string { + u32 __opaque1; +#if defined(__BIG_ENDIAN) + u16 __opaque3; + u16 __opaque2; +#elif defined(__LITTLE_ENDIAN) + u16 __opaque2; + u16 __opaque3; +#endif + struct ip_v6_addr __opaque4; + struct ip_v6_addr __opaque5; + u32 __opaque6; + u32 __opaque7[5]; +}; + + +/* + * syn cookie component + */ +struct l5cm_syn_cookie_comp { + u32 __opaque; +}; + +/* + * data related to listeners of a TCP port + */ +struct l5cm_port_listener_data { + u8 params; +#define L5CM_PORT_LISTENER_DATA_ENABLE (0x1<<0) +#define L5CM_PORT_LISTENER_DATA_ENABLE_SHIFT 0 +#define L5CM_PORT_LISTENER_DATA_IP_INDEX (0xF<<1) +#define L5CM_PORT_LISTENER_DATA_IP_INDEX_SHIFT 1 +#define L5CM_PORT_LISTENER_DATA_NET_FILTER (0x1<<5) +#define L5CM_PORT_LISTENER_DATA_NET_FILTER_SHIFT 5 +#define L5CM_PORT_LISTENER_DATA_DEFFERED_MODE (0x1<<6) +#define L5CM_PORT_LISTENER_DATA_DEFFERED_MODE_SHIFT 6 +#define L5CM_PORT_LISTENER_DATA_MPA_MODE (0x1<<7) +#define L5CM_PORT_LISTENER_DATA_MPA_MODE_SHIFT 7 +}; + +/* + * Opaque structure passed from U to X when final ack arrives + */ +struct l5cm_opaque_buf { + u32 __opaque1; + u32 __opaque2; + u32 __opaque3; + u32 __opaque4; + struct l5cm_syn_cookie_comp __opaque5; +#if defined(__BIG_ENDIAN) + u16 rsrv2; + u8 rsrv; + struct l5cm_port_listener_data __opaque6; +#elif defined(__LITTLE_ENDIAN) + struct l5cm_port_listener_data __opaque6; + u8 rsrv; + u16 rsrv2; +#endif +}; + + /* * l5cm slow path element */ @@ -4501,6 +5256,109 @@ struct l5cm_packet_size { u32 rsrv; }; + +/* + * The final-ack union structure in PCS entry after final ack arrived + */ +struct l5cm_pcse_ack { + struct l5cm_xstorm_conn_buffer tx_socket_params; + struct l5cm_opaque_buf opaque_buf; + struct l5cm_tstorm_conn_buffer rx_socket_params; +}; + + +/* + * The syn union structure in PCS entry after syn arrived + */ +struct l5cm_pcse_syn { + struct l5cm_opaque_buf opaque_buf; + u32 rsrv[12]; +}; + + +/* + * pcs entry data for passive connections + */ +struct l5cm_pcs_attributes { +#if defined(__BIG_ENDIAN) + u16 pcs_id; + u8 status; + u8 flags; +#define L5CM_PCS_ATTRIBUTES_NET_FILTER (0x1<<0) +#define L5CM_PCS_ATTRIBUTES_NET_FILTER_SHIFT 0 +#define L5CM_PCS_ATTRIBUTES_CALCULATE_HASH (0x1<<1) +#define L5CM_PCS_ATTRIBUTES_CALCULATE_HASH_SHIFT 1 +#define L5CM_PCS_ATTRIBUTES_COMPARE_HASH_RESULT (0x1<<2) +#define L5CM_PCS_ATTRIBUTES_COMPARE_HASH_RESULT_SHIFT 2 +#define L5CM_PCS_ATTRIBUTES_QUERY_ULP_ACCEPT (0x1<<3) +#define L5CM_PCS_ATTRIBUTES_QUERY_ULP_ACCEPT_SHIFT 3 +#define L5CM_PCS_ATTRIBUTES_FIND_DEST_MAC (0x1<<4) +#define L5CM_PCS_ATTRIBUTES_FIND_DEST_MAC_SHIFT 4 +#define L5CM_PCS_ATTRIBUTES_L4_OFFLOAD (0x1<<5) +#define L5CM_PCS_ATTRIBUTES_L4_OFFLOAD_SHIFT 5 +#define L5CM_PCS_ATTRIBUTES_FORWARD_PACKET (0x1<<6) +#define L5CM_PCS_ATTRIBUTES_FORWARD_PACKET_SHIFT 6 +#define L5CM_PCS_ATTRIBUTES_RSRV (0x1<<7) +#define L5CM_PCS_ATTRIBUTES_RSRV_SHIFT 7 +#elif defined(__LITTLE_ENDIAN) + u8 flags; +#define L5CM_PCS_ATTRIBUTES_NET_FILTER (0x1<<0) +#define L5CM_PCS_ATTRIBUTES_NET_FILTER_SHIFT 0 +#define L5CM_PCS_ATTRIBUTES_CALCULATE_HASH (0x1<<1) +#define L5CM_PCS_ATTRIBUTES_CALCULATE_HASH_SHIFT 1 +#define L5CM_PCS_ATTRIBUTES_COMPARE_HASH_RESULT (0x1<<2) +#define L5CM_PCS_ATTRIBUTES_COMPARE_HASH_RESULT_SHIFT 2 +#define L5CM_PCS_ATTRIBUTES_QUERY_ULP_ACCEPT (0x1<<3) +#define L5CM_PCS_ATTRIBUTES_QUERY_ULP_ACCEPT_SHIFT 3 +#define L5CM_PCS_ATTRIBUTES_FIND_DEST_MAC (0x1<<4) +#define L5CM_PCS_ATTRIBUTES_FIND_DEST_MAC_SHIFT 4 +#define L5CM_PCS_ATTRIBUTES_L4_OFFLOAD (0x1<<5) +#define L5CM_PCS_ATTRIBUTES_L4_OFFLOAD_SHIFT 5 +#define L5CM_PCS_ATTRIBUTES_FORWARD_PACKET (0x1<<6) +#define L5CM_PCS_ATTRIBUTES_FORWARD_PACKET_SHIFT 6 +#define L5CM_PCS_ATTRIBUTES_RSRV (0x1<<7) +#define L5CM_PCS_ATTRIBUTES_RSRV_SHIFT 7 + u8 status; + u16 pcs_id; +#endif +}; + + +union l5cm_seg_params { + struct l5cm_pcse_syn syn_seg_params; + struct l5cm_pcse_ack ack_seg_params; +}; + +/* + * pcs entry data for passive connections + */ +struct l5cm_pcs_hdr { + struct l5cm_hash_input_string hash_input_string; + struct l5cm_conn_addr_params conn_addr_buf; + u32 cid; + u32 hash_result; + union l5cm_seg_params seg_params; + struct l5cm_pcs_attributes att; +#if defined(__BIG_ENDIAN) + u16 rsrv; + u16 rx_seg_size; +#elif defined(__LITTLE_ENDIAN) + u16 rx_seg_size; + u16 rsrv; +#endif +}; + +/* + * pcs entry for passive connections + */ +struct l5cm_pcs_entry { + struct l5cm_pcs_hdr hdr; + u8 rx_segment[1516]; +}; + + + + /* * l5cm connection parameters */ @@ -4535,6 +5393,29 @@ struct l5cm_spe { union l5cm_specific_data data; }; + + + +/* + * Termination variables + */ +struct l5cm_term_vars { + u8 BitMap; +#define L5CM_TERM_VARS_TCP_STATE (0xF<<0) +#define L5CM_TERM_VARS_TCP_STATE_SHIFT 0 +#define L5CM_TERM_VARS_FIN_RECEIVED_SBIT (0x1<<4) +#define L5CM_TERM_VARS_FIN_RECEIVED_SBIT_SHIFT 4 +#define L5CM_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT (0x1<<5) +#define L5CM_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT_SHIFT 5 +#define L5CM_TERM_VARS_TERM_ON_CHIP (0x1<<6) +#define L5CM_TERM_VARS_TERM_ON_CHIP_SHIFT 6 +#define L5CM_TERM_VARS_RSRV (0x1<<7) +#define L5CM_TERM_VARS_RSRV_SHIFT 7 +}; + + + + /* * Tstorm Tcp flags */ @@ -4550,6 +5431,7 @@ struct tstorm_l5cm_tcp_flags { #define TSTORM_L5CM_TCP_FLAGS_RSRV1_SHIFT 14 }; + /* * Xstorm Tcp flags */ @@ -4565,4 +5447,38 @@ struct xstorm_l5cm_tcp_flags { #define XSTORM_L5CM_TCP_FLAGS_RSRV_SHIFT 3 }; -#endif /* CNIC_DEFS_H */ + + +/* + * Out-of-order states + */ +enum tcp_ooo_event { + TCP_EVENT_ADD_PEN = 0, + TCP_EVENT_ADD_NEW_ISLE = 1, + TCP_EVENT_ADD_ISLE_RIGHT = 2, + TCP_EVENT_ADD_ISLE_LEFT = 3, + TCP_EVENT_JOIN = 4, + TCP_EVENT_NOP = 5, + MAX_TCP_OOO_EVENT +}; + + +/* + * OOO support modes + */ +enum tcp_tstorm_ooo { + TCP_TSTORM_OOO_DROP_AND_PROC_ACK = 0, + TCP_TSTORM_OOO_SEND_PURE_ACK = 1, + TCP_TSTORM_OOO_SUPPORTED = 2, + MAX_TCP_TSTORM_OOO +}; + + + + + + + + + +#endif /* __5710_HSI_CNIC_LE__ */ diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index fdd8e46a905..bc7000a2d4e 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.2.14" -#define CNIC_MODULE_RELDATE "Mar 30, 2011" +#define CNIC_MODULE_VERSION "2.5.3" +#define CNIC_MODULE_RELDATE "June 6, 2011" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -99,6 +99,8 @@ struct kcqe { struct cnic_ctl_completion { u32 cid; + u8 opcode; + u8 error; }; struct cnic_ctl_info { @@ -169,7 +171,7 @@ struct cnic_eth_dev { struct pci_dev *pdev; void __iomem *io_base; void __iomem *io_base2; - void *iro_arr; + const void *iro_arr; u32 ctx_tbl_offset; u32 ctx_tbl_len; diff --git a/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h b/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h index 97a61b4d81b..e1f1e3448f9 100644 --- a/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h +++ b/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h @@ -16,6 +16,23 @@ struct b577xx_doorbell_hdr { #define B577XX_DOORBELL_HDR_CONN_TYPE_SHIFT 4 }; +/* + * doorbell message sent to the chip + */ +struct b577xx_doorbell { +#if defined(__BIG_ENDIAN) + u16 zero_fill2; + u8 zero_fill1; + struct b577xx_doorbell_hdr header; +#elif defined(__LITTLE_ENDIAN) + struct b577xx_doorbell_hdr header; + u8 zero_fill1; + u16 zero_fill2; +#endif +}; + + + /* * doorbell message sent to the chip */ @@ -39,106 +56,63 @@ struct regpair { /* - * Fixed size structure in order to plant it in Union structure + * ABTS info $$KEEP_ENDIANNESS$$ */ -struct fcoe_abts_rsp_union { - u32 r_ctl; - u32 abts_rsp_payload[7]; +struct fcoe_abts_info { + __le16 aborted_task_id; + __le16 reserved0; + __le32 reserved1; }; /* - * 4 regs size + * Fixed size structure in order to plant it in Union structure + * $$KEEP_ENDIANNESS$$ */ -struct fcoe_bd_ctx { - u32 buf_addr_hi; - u32 buf_addr_lo; -#if defined(__BIG_ENDIAN) - u16 rsrv0; - u16 buf_len; -#elif defined(__LITTLE_ENDIAN) - u16 buf_len; - u16 rsrv0; -#endif -#if defined(__BIG_ENDIAN) - u16 rsrv1; - u16 flags; -#elif defined(__LITTLE_ENDIAN) - u16 flags; - u16 rsrv1; -#endif +struct fcoe_abts_rsp_union { + u8 r_ctl; + u8 rsrv[3]; + __le32 abts_rsp_payload[7]; }; -struct fcoe_cleanup_flow_info { -#if defined(__BIG_ENDIAN) - u16 reserved1; - u16 task_id; -#elif defined(__LITTLE_ENDIAN) - u16 task_id; - u16 reserved1; -#endif - u32 reserved2[7]; +/* + * 4 regs size $$KEEP_ENDIANNESS$$ + */ +struct fcoe_bd_ctx { + __le32 buf_addr_hi; + __le32 buf_addr_lo; + __le16 buf_len; + __le16 rsrv0; + __le16 flags; + __le16 rsrv1; }; -struct fcoe_fcp_cmd_payload { - u32 opaque[8]; -}; - -struct fcoe_fc_hdr { -#if defined(__BIG_ENDIAN) - u8 cs_ctl; - u8 s_id[3]; -#elif defined(__LITTLE_ENDIAN) - u8 s_id[3]; - u8 cs_ctl; -#endif -#if defined(__BIG_ENDIAN) - u8 r_ctl; - u8 d_id[3]; -#elif defined(__LITTLE_ENDIAN) - u8 d_id[3]; - u8 r_ctl; -#endif -#if defined(__BIG_ENDIAN) - u8 seq_id; - u8 df_ctl; - u16 seq_cnt; -#elif defined(__LITTLE_ENDIAN) - u16 seq_cnt; - u8 df_ctl; - u8 seq_id; -#endif -#if defined(__BIG_ENDIAN) - u8 type; - u8 f_ctl[3]; -#elif defined(__LITTLE_ENDIAN) - u8 f_ctl[3]; - u8 type; -#endif - u32 parameters; -#if defined(__BIG_ENDIAN) - u16 ox_id; - u16 rx_id; -#elif defined(__LITTLE_ENDIAN) - u16 rx_id; - u16 ox_id; -#endif +/* + * FCoE cached sges context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_cached_sge_ctx { + struct regpair cur_buf_addr; + __le16 cur_buf_rem; + __le16 second_buf_rem; + struct regpair second_buf_addr; }; -struct fcoe_fc_frame { - struct fcoe_fc_hdr fc_hdr; - u32 reserved0[2]; -}; -union fcoe_cmd_flow_info { - struct fcoe_fcp_cmd_payload fcp_cmd_payload; - struct fcoe_fc_frame mp_fc_frame; +/* + * Cleanup info $$KEEP_ENDIANNESS$$ + */ +struct fcoe_cleanup_info { + __le16 cleaned_task_id; + __le16 rolled_tx_seq_cnt; + __le32 rolled_tx_data_offset; }; - +/* + * Fcp RSP flags $$KEEP_ENDIANNESS$$ + */ struct fcoe_fcp_rsp_flags { u8 flags; #define FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID (0x1<<0) @@ -155,95 +129,168 @@ struct fcoe_fcp_rsp_flags { #define FCOE_FCP_RSP_FLAGS_FCP_BIDI_FLAGS_SHIFT 5 }; - +/* + * Fcp RSP payload $$KEEP_ENDIANNESS$$ + */ struct fcoe_fcp_rsp_payload { struct regpair reserved0; - u32 fcp_resid; -#if defined(__BIG_ENDIAN) - u16 retry_delay_timer; - struct fcoe_fcp_rsp_flags fcp_flags; - u8 scsi_status_code; -#elif defined(__LITTLE_ENDIAN) + __le32 fcp_resid; u8 scsi_status_code; struct fcoe_fcp_rsp_flags fcp_flags; - u16 retry_delay_timer; -#endif - u32 fcp_rsp_len; - u32 fcp_sns_len; + __le16 retry_delay_timer; + __le32 fcp_rsp_len; + __le32 fcp_sns_len; }; - /* * Fixed size structure in order to plant it in Union structure + * $$KEEP_ENDIANNESS$$ */ struct fcoe_fcp_rsp_union { struct fcoe_fcp_rsp_payload payload; struct regpair reserved0; }; +/* + * FC header $$KEEP_ENDIANNESS$$ + */ +struct fcoe_fc_hdr { + u8 s_id[3]; + u8 cs_ctl; + u8 d_id[3]; + u8 r_ctl; + __le16 seq_cnt; + u8 df_ctl; + u8 seq_id; + u8 f_ctl[3]; + u8 type; + __le32 parameters; + __le16 rx_id; + __le16 ox_id; +}; -struct fcoe_fcp_xfr_rdy_payload { - u32 burst_len; - u32 data_ro; +/* + * FC header union $$KEEP_ENDIANNESS$$ + */ +struct fcoe_mp_rsp_union { + struct fcoe_fc_hdr fc_hdr; + __le32 mp_payload_len; + __le32 rsrv; }; -struct fcoe_read_flow_info { - struct fcoe_fc_hdr fc_data_in_hdr; - u32 reserved[2]; +/* + * Completion information $$KEEP_ENDIANNESS$$ + */ +union fcoe_comp_flow_info { + struct fcoe_fcp_rsp_union fcp_rsp; + struct fcoe_abts_rsp_union abts_rsp; + struct fcoe_mp_rsp_union mp_rsp; + __le32 opaque[8]; }; -struct fcoe_write_flow_info { - struct fcoe_fc_hdr fc_data_out_hdr; - struct fcoe_fcp_xfr_rdy_payload fcp_xfr_payload; + +/* + * External ABTS info $$KEEP_ENDIANNESS$$ + */ +struct fcoe_ext_abts_info { + __le32 rsrv0[6]; + struct fcoe_abts_info ctx; }; -union fcoe_rsp_flow_info { - struct fcoe_fcp_rsp_union fcp_rsp; - struct fcoe_abts_rsp_union abts_rsp; + +/* + * External cleanup info $$KEEP_ENDIANNESS$$ + */ +struct fcoe_ext_cleanup_info { + __le32 rsrv0[6]; + struct fcoe_cleanup_info ctx; }; + /* - * 32 bytes used for general purposes + * Fcoe FW Tx sequence context $$KEEP_ENDIANNESS$$ */ -union fcoe_general_task_ctx { - union fcoe_cmd_flow_info cmd_info; - struct fcoe_read_flow_info read_info; - struct fcoe_write_flow_info write_info; - union fcoe_rsp_flow_info rsp_info; - struct fcoe_cleanup_flow_info cleanup_info; - u32 comp_info[8]; +struct fcoe_fw_tx_seq_ctx { + __le32 data_offset; + __le16 seq_cnt; + __le16 rsrv0; +}; + +/* + * Fcoe external FW Tx sequence context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_ext_fw_tx_seq_ctx { + __le32 rsrv0[6]; + struct fcoe_fw_tx_seq_ctx ctx; +}; + + +/* + * FCoE multiple sges context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_mul_sges_ctx { + struct regpair cur_sge_addr; + __le16 cur_sge_off; + u8 cur_sge_idx; + u8 sgl_size; +}; + +/* + * FCoE external multiple sges context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_ext_mul_sges_ctx { + struct fcoe_mul_sges_ctx mul_sgl; + struct regpair rsrv0; }; /* - * FCoE KCQ CQE parameters + * FCP CMD payload $$KEEP_ENDIANNESS$$ + */ +struct fcoe_fcp_cmd_payload { + __le32 opaque[8]; +}; + + + + + +/* + * Fcp xfr rdy payload $$KEEP_ENDIANNESS$$ + */ +struct fcoe_fcp_xfr_rdy_payload { + __le32 burst_len; + __le32 data_ro; +}; + + +/* + * FC frame $$KEEP_ENDIANNESS$$ + */ +struct fcoe_fc_frame { + struct fcoe_fc_hdr fc_hdr; + __le32 reserved0[2]; +}; + + + + +/* + * FCoE KCQ CQE parameters $$KEEP_ENDIANNESS$$ */ union fcoe_kcqe_params { - u32 reserved0[4]; + __le32 reserved0[4]; }; /* - * FCoE KCQ CQE + * FCoE KCQ CQE $$KEEP_ENDIANNESS$$ */ struct fcoe_kcqe { - u32 fcoe_conn_id; - u32 completion_status; - u32 fcoe_conn_context_id; + __le32 fcoe_conn_id; + __le32 completion_status; + __le32 fcoe_conn_context_id; union fcoe_kcqe_params params; -#if defined(__BIG_ENDIAN) - u8 flags; -#define FCOE_KCQE_RESERVED0 (0x7<<0) -#define FCOE_KCQE_RESERVED0_SHIFT 0 -#define FCOE_KCQE_RAMROD_COMPLETION (0x1<<3) -#define FCOE_KCQE_RAMROD_COMPLETION_SHIFT 3 -#define FCOE_KCQE_LAYER_CODE (0x7<<4) -#define FCOE_KCQE_LAYER_CODE_SHIFT 4 -#define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7) -#define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7 - u8 op_code; - u16 qe_self_seq; -#elif defined(__LITTLE_ENDIAN) - u16 qe_self_seq; + __le16 qe_self_seq; u8 op_code; u8 flags; #define FCOE_KCQE_RESERVED0 (0x7<<0) @@ -254,23 +301,14 @@ struct fcoe_kcqe { #define FCOE_KCQE_LAYER_CODE_SHIFT 4 #define FCOE_KCQE_LINKED_WITH_NEXT (0x1<<7) #define FCOE_KCQE_LINKED_WITH_NEXT_SHIFT 7 -#endif }; + + /* - * FCoE KWQE header + * FCoE KWQE header $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_header { -#if defined(__BIG_ENDIAN) - u8 flags; -#define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0) -#define FCOE_KWQE_HEADER_RESERVED0_SHIFT 0 -#define FCOE_KWQE_HEADER_LAYER_CODE (0x7<<4) -#define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4 -#define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7) -#define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7 - u8 op_code; -#elif defined(__LITTLE_ENDIAN) u8 op_code; u8 flags; #define FCOE_KWQE_HEADER_RESERVED0 (0xF<<0) @@ -279,50 +317,23 @@ struct fcoe_kwqe_header { #define FCOE_KWQE_HEADER_LAYER_CODE_SHIFT 4 #define FCOE_KWQE_HEADER_RESERVED1 (0x1<<7) #define FCOE_KWQE_HEADER_RESERVED1_SHIFT 7 -#endif }; /* - * FCoE firmware init request 1 + * FCoE firmware init request 1 $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_init1 { -#if defined(__BIG_ENDIAN) + __le16 num_tasks; struct fcoe_kwqe_header hdr; - u16 num_tasks; -#elif defined(__LITTLE_ENDIAN) - u16 num_tasks; - struct fcoe_kwqe_header hdr; -#endif - u32 task_list_pbl_addr_lo; - u32 task_list_pbl_addr_hi; - u32 dummy_buffer_addr_lo; - u32 dummy_buffer_addr_hi; -#if defined(__BIG_ENDIAN) - u16 rq_num_wqes; - u16 sq_num_wqes; -#elif defined(__LITTLE_ENDIAN) - u16 sq_num_wqes; - u16 rq_num_wqes; -#endif -#if defined(__BIG_ENDIAN) - u16 cq_num_wqes; - u16 rq_buffer_log_size; -#elif defined(__LITTLE_ENDIAN) - u16 rq_buffer_log_size; - u16 cq_num_wqes; -#endif -#if defined(__BIG_ENDIAN) - u8 flags; -#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0) -#define FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT 0 -#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC (0x7<<4) -#define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4 -#define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7) -#define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7 - u8 num_sessions_log; - u16 mtu; -#elif defined(__LITTLE_ENDIAN) - u16 mtu; + __le32 task_list_pbl_addr_lo; + __le32 task_list_pbl_addr_hi; + __le32 dummy_buffer_addr_lo; + __le32 dummy_buffer_addr_hi; + __le16 sq_num_wqes; + __le16 rq_num_wqes; + __le16 rq_buffer_log_size; + __le16 cq_num_wqes; + __le16 mtu; u8 num_sessions_log; u8 flags; #define FCOE_KWQE_INIT1_LOG_PAGE_SIZE (0xF<<0) @@ -331,113 +342,73 @@ struct fcoe_kwqe_init1 { #define FCOE_KWQE_INIT1_LOG_CACHED_PBES_PER_FUNC_SHIFT 4 #define FCOE_KWQE_INIT1_RESERVED1 (0x1<<7) #define FCOE_KWQE_INIT1_RESERVED1_SHIFT 7 -#endif }; /* - * FCoE firmware init request 2 + * FCoE firmware init request 2 $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_init2 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; -#elif defined(__LITTLE_ENDIAN) - u16 reserved0; + u8 hsi_major_version; + u8 hsi_minor_version; struct fcoe_kwqe_header hdr; -#endif - u32 hash_tbl_pbl_addr_lo; - u32 hash_tbl_pbl_addr_hi; - u32 t2_hash_tbl_addr_lo; - u32 t2_hash_tbl_addr_hi; - u32 t2_ptr_hash_tbl_addr_lo; - u32 t2_ptr_hash_tbl_addr_hi; - u32 free_list_count; + __le32 hash_tbl_pbl_addr_lo; + __le32 hash_tbl_pbl_addr_hi; + __le32 t2_hash_tbl_addr_lo; + __le32 t2_hash_tbl_addr_hi; + __le32 t2_ptr_hash_tbl_addr_lo; + __le32 t2_ptr_hash_tbl_addr_hi; + __le32 free_list_count; }; /* - * FCoE firmware init request 3 + * FCoE firmware init request 3 $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_init3 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; -#elif defined(__LITTLE_ENDIAN) - u16 reserved0; + __le16 reserved0; struct fcoe_kwqe_header hdr; -#endif - u32 error_bit_map_lo; - u32 error_bit_map_hi; -#if defined(__BIG_ENDIAN) - u8 reserved21[3]; - u8 cached_session_enable; -#elif defined(__LITTLE_ENDIAN) - u8 cached_session_enable; + __le32 error_bit_map_lo; + __le32 error_bit_map_hi; + u8 perf_config; u8 reserved21[3]; -#endif - u32 reserved2[4]; + __le32 reserved2[4]; }; /* - * FCoE connection offload request 1 + * FCoE connection offload request 1 $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_conn_offload1 { -#if defined(__BIG_ENDIAN) + __le16 fcoe_conn_id; struct fcoe_kwqe_header hdr; - u16 fcoe_conn_id; -#elif defined(__LITTLE_ENDIAN) - u16 fcoe_conn_id; - struct fcoe_kwqe_header hdr; -#endif - u32 sq_addr_lo; - u32 sq_addr_hi; - u32 rq_pbl_addr_lo; - u32 rq_pbl_addr_hi; - u32 rq_first_pbe_addr_lo; - u32 rq_first_pbe_addr_hi; -#if defined(__BIG_ENDIAN) - u16 reserved0; - u16 rq_prod; -#elif defined(__LITTLE_ENDIAN) - u16 rq_prod; - u16 reserved0; -#endif + __le32 sq_addr_lo; + __le32 sq_addr_hi; + __le32 rq_pbl_addr_lo; + __le32 rq_pbl_addr_hi; + __le32 rq_first_pbe_addr_lo; + __le32 rq_first_pbe_addr_hi; + __le16 rq_prod; + __le16 reserved0; }; /* - * FCoE connection offload request 2 + * FCoE connection offload request 2 $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_conn_offload2 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 tx_max_fc_pay_len; -#elif defined(__LITTLE_ENDIAN) - u16 tx_max_fc_pay_len; + __le16 tx_max_fc_pay_len; struct fcoe_kwqe_header hdr; -#endif - u32 cq_addr_lo; - u32 cq_addr_hi; - u32 xferq_addr_lo; - u32 xferq_addr_hi; - u32 conn_db_addr_lo; - u32 conn_db_addr_hi; - u32 reserved1; + __le32 cq_addr_lo; + __le32 cq_addr_hi; + __le32 xferq_addr_lo; + __le32 xferq_addr_hi; + __le32 conn_db_addr_lo; + __le32 conn_db_addr_hi; + __le32 reserved1; }; /* - * FCoE connection offload request 3 + * FCoE connection offload request 3 $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_conn_offload3 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 vlan_tag; -#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0) -#define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0 -#define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12) -#define FCOE_KWQE_CONN_OFFLOAD3_CFI_SHIFT 12 -#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13) -#define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13 -#elif defined(__LITTLE_ENDIAN) - u16 vlan_tag; + __le16 vlan_tag; #define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID (0xFFF<<0) #define FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT 0 #define FCOE_KWQE_CONN_OFFLOAD3_CFI (0x1<<12) @@ -445,34 +416,8 @@ struct fcoe_kwqe_conn_offload3 { #define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY (0x7<<13) #define FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT 13 struct fcoe_kwqe_header hdr; -#endif -#if defined(__BIG_ENDIAN) - u8 tx_max_conc_seqs_c3; - u8 s_id[3]; -#elif defined(__LITTLE_ENDIAN) u8 s_id[3]; u8 tx_max_conc_seqs_c3; -#endif -#if defined(__BIG_ENDIAN) - u8 flags; -#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0) -#define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT 0 -#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES (0x1<<1) -#define FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT 1 -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT (0x1<<2) -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT 2 -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ (0x1<<3) -#define FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT 3 -#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID (0x1<<4) -#define FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT 4 -#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID (0x1<<5) -#define FCOE_KWQE_CONN_OFFLOAD3_B_C2_VALID_SHIFT 5 -#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0 (0x1<<6) -#define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6 -#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7) -#define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7 - u8 d_id[3]; -#elif defined(__LITTLE_ENDIAN) u8 d_id[3]; u8 flags; #define FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS (0x1<<0) @@ -491,79 +436,44 @@ struct fcoe_kwqe_conn_offload3 { #define FCOE_KWQE_CONN_OFFLOAD3_B_ACK_0_SHIFT 6 #define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG (0x1<<7) #define FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT 7 -#endif - u32 reserved; - u32 confq_first_pbe_addr_lo; - u32 confq_first_pbe_addr_hi; -#if defined(__BIG_ENDIAN) - u16 rx_max_fc_pay_len; - u16 tx_total_conc_seqs; -#elif defined(__LITTLE_ENDIAN) - u16 tx_total_conc_seqs; - u16 rx_max_fc_pay_len; -#endif -#if defined(__BIG_ENDIAN) - u8 rx_open_seqs_exch_c3; - u8 rx_max_conc_seqs_c3; - u16 rx_total_conc_seqs; -#elif defined(__LITTLE_ENDIAN) - u16 rx_total_conc_seqs; + __le32 reserved; + __le32 confq_first_pbe_addr_lo; + __le32 confq_first_pbe_addr_hi; + __le16 tx_total_conc_seqs; + __le16 rx_max_fc_pay_len; + __le16 rx_total_conc_seqs; u8 rx_max_conc_seqs_c3; u8 rx_open_seqs_exch_c3; -#endif }; /* - * FCoE connection offload request 4 + * FCoE connection offload request 4 $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_conn_offload4 { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u8 reserved2; - u8 e_d_tov_timer_val; -#elif defined(__LITTLE_ENDIAN) u8 e_d_tov_timer_val; u8 reserved2; struct fcoe_kwqe_header hdr; -#endif - u8 src_mac_addr_lo32[4]; -#if defined(__BIG_ENDIAN) - u8 dst_mac_addr_hi16[2]; - u8 src_mac_addr_hi16[2]; -#elif defined(__LITTLE_ENDIAN) - u8 src_mac_addr_hi16[2]; - u8 dst_mac_addr_hi16[2]; -#endif - u8 dst_mac_addr_lo32[4]; - u32 lcq_addr_lo; - u32 lcq_addr_hi; - u32 confq_pbl_base_addr_lo; - u32 confq_pbl_base_addr_hi; + u8 src_mac_addr_lo[2]; + u8 src_mac_addr_mid[2]; + u8 src_mac_addr_hi[2]; + u8 dst_mac_addr_hi[2]; + u8 dst_mac_addr_lo[2]; + u8 dst_mac_addr_mid[2]; + __le32 lcq_addr_lo; + __le32 lcq_addr_hi; + __le32 confq_pbl_base_addr_lo; + __le32 confq_pbl_base_addr_hi; }; /* - * FCoE connection enable request + * FCoE connection enable request $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_conn_enable_disable { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; -#elif defined(__LITTLE_ENDIAN) - u16 reserved0; + __le16 reserved0; struct fcoe_kwqe_header hdr; -#endif - u8 src_mac_addr_lo32[4]; -#if defined(__BIG_ENDIAN) - u16 vlan_tag; -#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0 -#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI (0x1<<12) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12 -#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13) -#define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13 - u8 src_mac_addr_hi16[2]; -#elif defined(__LITTLE_ENDIAN) - u8 src_mac_addr_hi16[2]; + u8 src_mac_addr_lo[2]; + u8 src_mac_addr_mid[2]; + u8 src_mac_addr_hi[2]; u16 vlan_tag; #define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID (0xFFF<<0) #define FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT 0 @@ -571,82 +481,52 @@ struct fcoe_kwqe_conn_enable_disable { #define FCOE_KWQE_CONN_ENABLE_DISABLE_CFI_SHIFT 12 #define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY (0x7<<13) #define FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT 13 -#endif - u8 dst_mac_addr_lo32[4]; -#if defined(__BIG_ENDIAN) - u16 reserved1; - u8 dst_mac_addr_hi16[2]; -#elif defined(__LITTLE_ENDIAN) - u8 dst_mac_addr_hi16[2]; - u16 reserved1; -#endif -#if defined(__BIG_ENDIAN) - u8 vlan_flag; - u8 s_id[3]; -#elif defined(__LITTLE_ENDIAN) + u8 dst_mac_addr_lo[2]; + u8 dst_mac_addr_mid[2]; + u8 dst_mac_addr_hi[2]; + __le16 reserved1; u8 s_id[3]; u8 vlan_flag; -#endif -#if defined(__BIG_ENDIAN) - u8 reserved3; - u8 d_id[3]; -#elif defined(__LITTLE_ENDIAN) u8 d_id[3]; u8 reserved3; -#endif - u32 context_id; - u32 conn_id; - u32 reserved4; + __le32 context_id; + __le32 conn_id; + __le32 reserved4; }; /* - * FCoE connection destroy request + * FCoE connection destroy request $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_conn_destroy { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; -#elif defined(__LITTLE_ENDIAN) - u16 reserved0; + __le16 reserved0; struct fcoe_kwqe_header hdr; -#endif - u32 context_id; - u32 conn_id; - u32 reserved1[5]; + __le32 context_id; + __le32 conn_id; + __le32 reserved1[5]; }; /* - * FCoe destroy request + * FCoe destroy request $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_destroy { -#if defined(__BIG_ENDIAN) - struct fcoe_kwqe_header hdr; - u16 reserved0; -#elif defined(__LITTLE_ENDIAN) - u16 reserved0; + __le16 reserved0; struct fcoe_kwqe_header hdr; -#endif - u32 reserved1[7]; + __le32 reserved1[7]; }; /* - * FCoe statistics request + * FCoe statistics request $$KEEP_ENDIANNESS$$ */ struct fcoe_kwqe_stat { -#if defined(__BIG_ENDIAN) + __le16 reserved0; struct fcoe_kwqe_header hdr; - u16 reserved0; -#elif defined(__LITTLE_ENDIAN) - u16 reserved0; - struct fcoe_kwqe_header hdr; -#endif - u32 stat_params_addr_lo; - u32 stat_params_addr_hi; - u32 reserved1[5]; + __le32 stat_params_addr_lo; + __le32 stat_params_addr_hi; + __le32 reserved1[5]; }; /* - * FCoE KWQ WQE + * FCoE KWQ WQE $$KEEP_ENDIANNESS$$ */ union fcoe_kwqe { struct fcoe_kwqe_init1 init1; @@ -662,19 +542,42 @@ union fcoe_kwqe { struct fcoe_kwqe_stat statistics; }; -struct fcoe_mul_sges_ctx { - struct regpair cur_sge_addr; -#if defined(__BIG_ENDIAN) - u8 sgl_size; - u8 cur_sge_idx; - u16 cur_sge_off; -#elif defined(__LITTLE_ENDIAN) - u16 cur_sge_off; - u8 cur_sge_idx; - u8 sgl_size; -#endif + + + + + + + + + + + + + + + +/* + * TX SGL context $$KEEP_ENDIANNESS$$ + */ +union fcoe_sgl_union_ctx { + struct fcoe_cached_sge_ctx cached_sge; + struct fcoe_ext_mul_sges_ctx sgl; + __le32 opaque[5]; }; +/* + * Data-In/ELS/BLS information $$KEEP_ENDIANNESS$$ + */ +struct fcoe_read_flow_info { + union fcoe_sgl_union_ctx sgl_ctx; + __le32 rsrv0[3]; +}; + + +/* + * Fcoe stat context $$KEEP_ENDIANNESS$$ + */ struct fcoe_s_stat_ctx { u8 flags; #define FCOE_S_STAT_CTX_ACTIVE (0x1<<0) @@ -693,51 +596,34 @@ struct fcoe_s_stat_ctx { #define FCOE_S_STAT_CTX_RSRV1_SHIFT 6 }; -struct fcoe_seq_ctx { -#if defined(__BIG_ENDIAN) - u16 low_seq_cnt; - struct fcoe_s_stat_ctx s_stat; - u8 seq_id; -#elif defined(__LITTLE_ENDIAN) +/* + * Fcoe rx seq context $$KEEP_ENDIANNESS$$ + */ +struct fcoe_rx_seq_ctx { u8 seq_id; struct fcoe_s_stat_ctx s_stat; - u16 low_seq_cnt; -#endif -#if defined(__BIG_ENDIAN) - u16 err_seq_cnt; - u16 high_seq_cnt; -#elif defined(__LITTLE_ENDIAN) - u16 high_seq_cnt; - u16 err_seq_cnt; -#endif - u32 low_exp_ro; - u32 high_exp_ro; + __le16 seq_cnt; + __le32 low_exp_ro; + __le32 high_exp_ro; }; -struct fcoe_single_sge_ctx { - struct regpair cur_buf_addr; -#if defined(__BIG_ENDIAN) - u16 reserved0; - u16 cur_buf_rem; -#elif defined(__LITTLE_ENDIAN) - u16 cur_buf_rem; - u16 reserved0; -#endif -}; - -union fcoe_sgl_ctx { - struct fcoe_single_sge_ctx single_sge; - struct fcoe_mul_sges_ctx mul_sges; +/* + * Fcoe rx_wr union context $$KEEP_ENDIANNESS$$ + */ +union fcoe_rx_wr_union_ctx { + struct fcoe_read_flow_info read_info; + union fcoe_comp_flow_info comp_info; + __le32 opaque[8]; }; /* - * FCoE SQ element + * FCoE SQ element $$KEEP_ENDIANNESS$$ */ struct fcoe_sqe { - u16 wqe; + __le16 wqe; #define FCOE_SQE_TASK_ID (0x7FFF<<0) #define FCOE_SQE_TASK_ID_SHIFT 0 #define FCOE_SQE_TOGGLE_BIT (0x1<<15) @@ -746,135 +632,141 @@ struct fcoe_sqe { -struct fcoe_task_ctx_entry_tx_only { - union fcoe_sgl_ctx sgl_ctx; +/* + * 14 regs $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_tx_only { + union fcoe_sgl_union_ctx sgl_ctx; + __le32 rsrv0; }; -struct fcoe_task_ctx_entry_txwr_rxrd { -#if defined(__BIG_ENDIAN) - u16 verify_tx_seq; +/* + * 32 bytes (8 regs) used for TX only purposes $$KEEP_ENDIANNESS$$ + */ +union fcoe_tx_wr_rx_rd_union_ctx { + struct fcoe_fc_frame tx_frame; + struct fcoe_fcp_cmd_payload fcp_cmd; + struct fcoe_ext_cleanup_info cleanup; + struct fcoe_ext_abts_info abts; + struct fcoe_ext_fw_tx_seq_ctx tx_seq; + __le32 opaque[8]; +}; + +/* + * tce_tx_wr_rx_rd_const $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_tx_wr_rx_rd_const { u8 init_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6 - u8 tx_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4 -#elif defined(__LITTLE_ENDIAN) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE (0x7<<0) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT 0 +#define FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE (0x1<<3) +#define FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT 3 +#define FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE (0x1<<4) +#define FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT 4 +#define FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE (0x3<<5) +#define FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT 5 +#define FCOE_TCE_TX_WR_RX_RD_CONST_SUPPORT_REC_TOV (0x1<<7) +#define FCOE_TCE_TX_WR_RX_RD_CONST_SUPPORT_REC_TOV_SHIFT 7 u8 tx_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4 (0xF<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV4_SHIFT 4 - u8 init_flags; -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE (0x7<<0) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE (0x1<<3) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT 3 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE (0x1<<4) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE (0x1<<5) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT 5 -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5 (0x3<<6) -#define FCOE_TASK_CTX_ENTRY_TXWR_RXRD_RSRV5_SHIFT 6 - u16 verify_tx_seq; -#endif +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_VALID (0x1<<0) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_VALID_SHIFT 0 +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE (0xF<<1) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT 1 +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV1 (0x1<<5) +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV1_SHIFT 5 +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_SEQ_INIT (0x1<<6) +#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_SEQ_INIT_SHIFT 6 +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV2 (0x1<<7) +#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV2_SHIFT 7 + __le16 rsrv3; + __le32 verify_tx_seq; }; /* - * Common section. Both TX and RX processing might write and read from it in - * different flows + * tce_tx_wr_rx_rd $$KEEP_ENDIANNESS$$ */ -struct fcoe_task_ctx_entry_tx_rx_cmn { - u32 data_2_trns; - union fcoe_general_task_ctx general; -#if defined(__BIG_ENDIAN) - u16 tx_low_seq_cnt; - struct fcoe_s_stat_ctx tx_s_stat; - u8 tx_seq_id; -#elif defined(__LITTLE_ENDIAN) - u8 tx_seq_id; - struct fcoe_s_stat_ctx tx_s_stat; - u16 tx_low_seq_cnt; -#endif - u32 common_flags; -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID (0xFFFFFF<<0) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID (0x1<<24) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID_SHIFT 24 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT (0x1<<25) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT_SHIFT 25 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER (0x1<<26) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_XFER_SHIFT 26 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF (0x1<<27) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_PEND_CONF_SHIFT 27 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME (0x1<<28) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME_SHIFT 28 -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV (0x7<<29) -#define FCOE_TASK_CTX_ENTRY_TX_RX_CMN_RSRV_SHIFT 29 -}; - -struct fcoe_task_ctx_entry_rxwr_txrd { -#if defined(__BIG_ENDIAN) - u16 rx_id; - u16 rx_flags; -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9 -#elif defined(__LITTLE_ENDIAN) - u16 rx_flags; -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE (0xF<<0) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT 0 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE (0x7<<4) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT 4 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ (0x1<<7) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_CONF_REQ_SHIFT 7 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME (0x1<<8) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_MISS_FRAME_SHIFT 8 -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0 (0x7F<<9) -#define FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RESERVED0_SHIFT 9 - u16 rx_id; -#endif +struct fcoe_tce_tx_wr_rx_rd { + union fcoe_tx_wr_rx_rd_union_ctx union_ctx; + struct fcoe_tce_tx_wr_rx_rd_const const_ctx; }; -struct fcoe_task_ctx_entry_rx_only { - struct fcoe_seq_ctx seq_ctx; - struct fcoe_seq_ctx ooo_seq_ctx; - u32 rsrv3; - union fcoe_sgl_ctx sgl_ctx; +/* + * tce_rx_wr_tx_rd_const $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_wr_tx_rd_const { + __le32 data_2_trns; + __le32 init_flags; +#define FCOE_TCE_RX_WR_TX_RD_CONST_CID (0xFFFFFF<<0) +#define FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT 0 +#define FCOE_TCE_RX_WR_TX_RD_CONST_RSRV0 (0xFF<<24) +#define FCOE_TCE_RX_WR_TX_RD_CONST_RSRV0_SHIFT 24 +}; + +/* + * tce_rx_wr_tx_rd_var $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_wr_tx_rd_var { + __le16 rx_flags; +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV1 (0xF<<0) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV1_SHIFT 0 +#define FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE (0x7<<4) +#define FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE_SHIFT 4 +#define FCOE_TCE_RX_WR_TX_RD_VAR_CONF_REQ (0x1<<7) +#define FCOE_TCE_RX_WR_TX_RD_VAR_CONF_REQ_SHIFT 7 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE (0xF<<8) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE_SHIFT 8 +#define FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME (0x1<<12) +#define FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT 12 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_SEQ_INIT (0x1<<13) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_SEQ_INIT_SHIFT 13 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV2 (0x1<<14) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RSRV2_SHIFT 14 +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_VALID (0x1<<15) +#define FCOE_TCE_RX_WR_TX_RD_VAR_RX_VALID_SHIFT 15 + __le16 rx_id; + struct fcoe_fcp_xfr_rdy_payload fcp_xfr_rdy; +}; + +/* + * tce_rx_wr_tx_rd $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_wr_tx_rd { + struct fcoe_tce_rx_wr_tx_rd_const const_ctx; + struct fcoe_tce_rx_wr_tx_rd_var var_ctx; +}; + +/* + * tce_rx_only $$KEEP_ENDIANNESS$$ + */ +struct fcoe_tce_rx_only { + struct fcoe_rx_seq_ctx rx_seq_ctx; + union fcoe_rx_wr_union_ctx union_ctx; }; +/* + * task_ctx_entry $$KEEP_ENDIANNESS$$ + */ struct fcoe_task_ctx_entry { - struct fcoe_task_ctx_entry_tx_only tx_wr_only; - struct fcoe_task_ctx_entry_txwr_rxrd tx_wr_rx_rd; - struct fcoe_task_ctx_entry_tx_rx_cmn cmn; - struct fcoe_task_ctx_entry_rxwr_txrd rx_wr_tx_rd; - struct fcoe_task_ctx_entry_rx_only rx_wr_only; - u32 reserved[4]; + struct fcoe_tce_tx_only txwr_only; + struct fcoe_tce_tx_wr_rx_rd txwr_rxrd; + struct fcoe_tce_rx_wr_tx_rd rxwr_txrd; + struct fcoe_tce_rx_only rxwr_only; }; + + + + + + + + /* - * FCoE XFRQ element + * FCoE XFRQ element $$KEEP_ENDIANNESS$$ */ struct fcoe_xfrqe { - u16 wqe; + __le16 wqe; #define FCOE_XFRQE_TASK_ID (0x7FFF<<0) #define FCOE_XFRQE_TASK_ID_SHIFT 0 #define FCOE_XFRQE_TOGGLE_BIT (0x1<<15) @@ -883,22 +775,31 @@ struct fcoe_xfrqe { /* - * FCoE CONFQ element + * fcoe rx doorbell message sent to the chip $$KEEP_ENDIANNESS$$ + */ +struct b577xx_fcoe_rx_doorbell { + struct b577xx_doorbell_hdr hdr; + u8 params; +#define B577XX_FCOE_RX_DOORBELL_NEGATIVE_ARM (0x1F<<0) +#define B577XX_FCOE_RX_DOORBELL_NEGATIVE_ARM_SHIFT 0 +#define B577XX_FCOE_RX_DOORBELL_OPCODE (0x7<<5) +#define B577XX_FCOE_RX_DOORBELL_OPCODE_SHIFT 5 + __le16 doorbell_cq_cons; +}; + + +/* + * FCoE CONFQ element $$KEEP_ENDIANNESS$$ */ struct fcoe_confqe { -#if defined(__BIG_ENDIAN) - u16 rx_id; - u16 ox_id; -#elif defined(__LITTLE_ENDIAN) - u16 ox_id; - u16 rx_id; -#endif - u32 param; + __le16 ox_id; + __le16 rx_id; + __le32 param; }; /* - * FCoE connection data base + * FCoE conection data base */ struct fcoe_conn_db { #if defined(__BIG_ENDIAN) @@ -914,10 +815,10 @@ struct fcoe_conn_db { /* - * FCoE CQ element + * FCoE CQ element $$KEEP_ENDIANNESS$$ */ struct fcoe_cqe { - u16 wqe; + __le16 wqe; #define FCOE_CQE_CQE_INFO (0x3FFF<<0) #define FCOE_CQE_CQE_INFO_SHIFT 0 #define FCOE_CQE_CQE_TYPE (0x1<<14) @@ -928,61 +829,46 @@ struct fcoe_cqe { /* - * FCoE error/warning resporting entry + * FCoE error/warning reporting entry $$KEEP_ENDIANNESS$$ + */ +struct fcoe_partial_err_report_entry { + __le32 err_warn_bitmap_lo; + __le32 err_warn_bitmap_hi; + __le32 tx_buf_off; + __le32 rx_buf_off; +}; + +/* + * FCoE error/warning reporting entry $$KEEP_ENDIANNESS$$ */ struct fcoe_err_report_entry { - u32 err_warn_bitmap_lo; - u32 err_warn_bitmap_hi; - u32 tx_buf_off; - u32 rx_buf_off; + struct fcoe_partial_err_report_entry data; struct fcoe_fc_hdr fc_hdr; }; /* - * FCoE hash table entry (32 bytes) + * FCoE hash table entry (32 bytes) $$KEEP_ENDIANNESS$$ */ struct fcoe_hash_table_entry { -#if defined(__BIG_ENDIAN) - u8 d_id_0; - u8 s_id_2; - u8 s_id_1; - u8 s_id_0; -#elif defined(__LITTLE_ENDIAN) u8 s_id_0; u8 s_id_1; u8 s_id_2; u8 d_id_0; -#endif -#if defined(__BIG_ENDIAN) - u16 dst_mac_addr_hi; - u8 d_id_2; - u8 d_id_1; -#elif defined(__LITTLE_ENDIAN) u8 d_id_1; u8 d_id_2; - u16 dst_mac_addr_hi; -#endif - u32 dst_mac_addr_lo; -#if defined(__BIG_ENDIAN) - u16 vlan_id; - u16 src_mac_addr_hi; -#elif defined(__LITTLE_ENDIAN) - u16 src_mac_addr_hi; - u16 vlan_id; -#endif - u32 src_mac_addr_lo; -#if defined(__BIG_ENDIAN) - u16 reserved1; - u8 reserved0; - u8 vlan_flag; -#elif defined(__LITTLE_ENDIAN) + __le16 dst_mac_addr_hi; + __le16 dst_mac_addr_mid; + __le16 dst_mac_addr_lo; + __le16 src_mac_addr_hi; + __le16 vlan_id; + __le16 src_mac_addr_lo; + __le16 src_mac_addr_mid; u8 vlan_flag; u8 reserved0; - u16 reserved1; -#endif - u32 reserved2; - u32 field_id; + __le16 reserved1; + __le32 reserved2; + __le32 field_id; #define FCOE_HASH_TABLE_ENTRY_CID (0xFFFFFF<<0) #define FCOE_HASH_TABLE_ENTRY_CID_SHIFT 0 #define FCOE_HASH_TABLE_ENTRY_RESERVED3 (0x7F<<24) @@ -991,11 +877,27 @@ struct fcoe_hash_table_entry { #define FCOE_HASH_TABLE_ENTRY_VALID_SHIFT 31 }; + /* - * FCoE pending work request CQE + * FCoE LCQ element $$KEEP_ENDIANNESS$$ + */ +struct fcoe_lcqe { + __le32 wqe; +#define FCOE_LCQE_TASK_ID (0xFFFF<<0) +#define FCOE_LCQE_TASK_ID_SHIFT 0 +#define FCOE_LCQE_LCQE_TYPE (0xFF<<16) +#define FCOE_LCQE_LCQE_TYPE_SHIFT 16 +#define FCOE_LCQE_RESERVED (0xFF<<24) +#define FCOE_LCQE_RESERVED_SHIFT 24 +}; + + + +/* + * FCoE pending work request CQE $$KEEP_ENDIANNESS$$ */ struct fcoe_pend_wq_cqe { - u16 wqe; + __le16 wqe; #define FCOE_PEND_WQ_CQE_TASK_ID (0x3FFF<<0) #define FCOE_PEND_WQ_CQE_TASK_ID_SHIFT 0 #define FCOE_PEND_WQ_CQE_CQE_TYPE (0x1<<14) @@ -1006,53 +908,61 @@ struct fcoe_pend_wq_cqe { /* - * FCoE RX statistics parameters section#0 + * FCoE RX statistics parameters section#0 $$KEEP_ENDIANNESS$$ */ struct fcoe_rx_stat_params_section0 { - u32 fcoe_ver_cnt; - u32 fcoe_rx_pkt_cnt; - u32 fcoe_rx_byte_cnt; - u32 fcoe_rx_drop_pkt_cnt; + __le32 fcoe_rx_pkt_cnt; + __le32 fcoe_rx_byte_cnt; }; /* - * FCoE RX statistics parameters section#1 + * FCoE RX statistics parameters section#1 $$KEEP_ENDIANNESS$$ */ struct fcoe_rx_stat_params_section1 { - u32 fc_crc_cnt; - u32 eofa_del_cnt; - u32 miss_frame_cnt; - u32 seq_timeout_cnt; - u32 drop_seq_cnt; - u32 fcoe_rx_drop_pkt_cnt; - u32 fcp_rx_pkt_cnt; - u32 reserved0; + __le32 fcoe_ver_cnt; + __le32 fcoe_rx_drop_pkt_cnt; +}; + + +/* + * FCoE RX statistics parameters section#2 $$KEEP_ENDIANNESS$$ + */ +struct fcoe_rx_stat_params_section2 { + __le32 fc_crc_cnt; + __le32 eofa_del_cnt; + __le32 miss_frame_cnt; + __le32 seq_timeout_cnt; + __le32 drop_seq_cnt; + __le32 fcoe_rx_drop_pkt_cnt; + __le32 fcp_rx_pkt_cnt; + __le32 reserved0; }; /* - * FCoE TX statistics parameters + * FCoE TX statistics parameters $$KEEP_ENDIANNESS$$ */ struct fcoe_tx_stat_params { - u32 fcoe_tx_pkt_cnt; - u32 fcoe_tx_byte_cnt; - u32 fcp_tx_pkt_cnt; - u32 reserved0; + __le32 fcoe_tx_pkt_cnt; + __le32 fcoe_tx_byte_cnt; + __le32 fcp_tx_pkt_cnt; + __le32 reserved0; }; /* - * FCoE statistics parameters + * FCoE statistics parameters $$KEEP_ENDIANNESS$$ */ struct fcoe_statistics_params { struct fcoe_tx_stat_params tx_stat; struct fcoe_rx_stat_params_section0 rx_stat0; struct fcoe_rx_stat_params_section1 rx_stat1; + struct fcoe_rx_stat_params_section2 rx_stat2; }; /* - * FCoE t2 hash table entry (64 bytes) + * FCoE t2 hash table entry (64 bytes) $$KEEP_ENDIANNESS$$ */ struct fcoe_t2_hash_table_entry { struct fcoe_hash_table_entry data; @@ -1060,11 +970,13 @@ struct fcoe_t2_hash_table_entry { struct regpair reserved0[3]; }; + + /* - * FCoE unsolicited CQE + * FCoE unsolicited CQE $$KEEP_ENDIANNESS$$ */ struct fcoe_unsolicited_cqe { - u16 wqe; + __le16 wqe; #define FCOE_UNSOLICITED_CQE_SUBTYPE (0x3<<0) #define FCOE_UNSOLICITED_CQE_SUBTYPE_SHIFT 0 #define FCOE_UNSOLICITED_CQE_PKT_LEN (0xFFF<<2) @@ -1075,6 +987,4 @@ struct fcoe_unsolicited_cqe { #define FCOE_UNSOLICITED_CQE_TOGGLE_BIT_SHIFT 15 }; - - #endif /* __57XX_FCOE_HSI_LINUX_LE__ */ diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index 0a404bfb44f..907672e8606 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h @@ -62,7 +62,7 @@ #include "bnx2fc_constants.h" #define BNX2FC_NAME "bnx2fc" -#define BNX2FC_VERSION "1.0.1" +#define BNX2FC_VERSION "1.0.3" #define PFX "bnx2fc: " @@ -262,9 +262,14 @@ struct bnx2fc_rport { #define BNX2FC_FLAG_UPLD_REQ_COMPL 0x8 #define BNX2FC_FLAG_EXPL_LOGO 0x9 + u8 src_addr[ETH_ALEN]; u32 max_sqes; u32 max_rqes; u32 max_cqes; + atomic_t free_sqes; + + struct b577xx_doorbell_set_prod sq_db; + struct b577xx_fcoe_rx_doorbell rx_db; struct fcoe_sqe *sq; dma_addr_t sq_dma; @@ -274,7 +279,7 @@ struct bnx2fc_rport { struct fcoe_cqe *cq; dma_addr_t cq_dma; - u32 cq_cons_idx; + u16 cq_cons_idx; u8 cq_curr_toggle_bit; u32 cq_mem_size; @@ -505,6 +510,7 @@ struct fc_seq *bnx2fc_elsct_send(struct fc_lport *lport, u32 did, struct fc_frame *, void *), void *arg, u32 timeout); +void bnx2fc_arm_cq(struct bnx2fc_rport *tgt); int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt); void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe); struct bnx2fc_rport *bnx2fc_tgt_lookup(struct fcoe_port *port, diff --git a/drivers/scsi/bnx2fc/bnx2fc_constants.h b/drivers/scsi/bnx2fc/bnx2fc_constants.h index fe7769173c4..399cda047a7 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_constants.h +++ b/drivers/scsi/bnx2fc/bnx2fc_constants.h @@ -5,6 +5,12 @@ * This file defines HSI constants for the FCoE flows */ +/* Current FCoE HSI version number composed of two fields (16 bit) */ +/* Implies on a change broken previous HSI */ +#define FCOE_HSI_MAJOR_VERSION (1) +/* Implies on a change which does not broken previous HSI */ +#define FCOE_HSI_MINOR_VERSION (1) + /* KWQ/KCQ FCoE layer code */ #define FCOE_KWQE_LAYER_CODE (7) @@ -40,21 +46,62 @@ #define FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE (0x3) #define FCOE_KCQE_COMPLETION_STATUS_CTX_FREE_FAILURE (0x4) #define FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR (0x5) +#define FCOE_KCQE_COMPLETION_STATUS_WRONG_HSI_VERSION (0x6) + +/* CQE type */ +#define FCOE_PENDING_CQE_TYPE 0 +#define FCOE_UNSOLIC_CQE_TYPE 1 /* Unsolicited CQE type */ #define FCOE_UNSOLICITED_FRAME_CQE_TYPE 0 #define FCOE_ERROR_DETECTION_CQE_TYPE 1 #define FCOE_WARNING_DETECTION_CQE_TYPE 2 +/* E_D_TOV timer resolution in ms */ +#define FCOE_E_D_TOV_TIMER_RESOLUTION_MS (20) + +/* E_D_TOV timer resolution for SDM (4 micro) */ +#define FCOE_E_D_TOV_SDM_TIMER_RESOLUTION \ + (FCOE_E_D_TOV_TIMER_RESOLUTION_MS * 1000 / 4) + +/* REC timer resolution in ms */ +#define FCOE_REC_TIMER_RESOLUTION_MS (20) + +/* REC timer resolution for SDM (4 micro) */ +#define FCOE_REC_SDM_TIMER_RESOLUTION (FCOE_REC_TIMER_RESOLUTION_MS * 1000 / 4) + +/* E_D_TOV timer default wraparound value (2 sec) in 20 ms resolution */ +#define FCOE_E_D_TOV_DEFAULT_WRAPAROUND_VAL \ + (2000 / FCOE_E_D_TOV_TIMER_RESOLUTION_MS) + +/* REC_TOV timer default wraparound value (3 sec) in 20 ms resolution */ +#define FCOE_REC_TOV_DEFAULT_WRAPAROUND_VAL \ + (3000 / FCOE_REC_TIMER_RESOLUTION_MS) + +#define FCOE_NUM_OF_TIMER_TASKS (8 * 1024) + +#define FCOE_NUM_OF_CACHED_TASKS_TIMER (8) + /* Task context constants */ +/******** Remove FCP_CMD write tce sleep ***********************/ +/* In case timer services are required then shall be updated by Xstorm after + * start processing the task. In case no timer facilities are required then the + * driver would initialize the state to this value + * +#define FCOE_TASK_TX_STATE_NORMAL 0 + * After driver has initialize the task in case timer services required * +#define FCOE_TASK_TX_STATE_INIT 1 +******** Remove FCP_CMD write tce sleep ***********************/ /* After driver has initialize the task in case timer services required */ #define FCOE_TASK_TX_STATE_INIT 0 /* In case timer services are required then shall be updated by Xstorm after * start processing the task. In case no timer facilities are required then the - * driver would initialize the state to this value */ + * driver would initialize the state to this value + */ #define FCOE_TASK_TX_STATE_NORMAL 1 /* Task is under abort procedure. Updated in order to stop processing of - * pending WQEs on this task */ + * pending WQEs on this task + */ #define FCOE_TASK_TX_STATE_ABORT 2 /* For E_D_T_TOV timer expiration in Xstorm (Class 2 only) */ #define FCOE_TASK_TX_STATE_ERROR 3 @@ -66,17 +113,8 @@ #define FCOE_TASK_TX_STATE_EXCHANGE_CLEANUP 6 /* For sequence cleanup request task */ #define FCOE_TASK_TX_STATE_SEQUENCE_CLEANUP 7 -/* Mark task as aborted and indicate that ABTS was not transmitted */ -#define FCOE_TASK_TX_STATE_BEFORE_ABTS_TX 8 -/* Mark task as aborted and indicate that ABTS was transmitted */ -#define FCOE_TASK_TX_STATE_AFTER_ABTS_TX 9 /* For completion the ABTS task. */ -#define FCOE_TASK_TX_STATE_ABTS_TX_COMPLETED 10 -/* Mark task as aborted and indicate that Exchange cleanup was not transmitted - */ -#define FCOE_TASK_TX_STATE_BEFORE_EXCHANGE_CLEANUP_TX 11 -/* Mark task as aborted and indicate that Exchange cleanup was transmitted */ -#define FCOE_TASK_TX_STATE_AFTER_EXCHANGE_CLEANUP_TX 12 +#define FCOE_TASK_TX_STATE_ABTS_TX 8 #define FCOE_TASK_RX_STATE_NORMAL 0 #define FCOE_TASK_RX_STATE_COMPLETED 1 @@ -86,25 +124,25 @@ #define FCOE_TASK_RX_STATE_WARNING 3 /* For E_D_T_TOV timer expiration in Ustorm */ #define FCOE_TASK_RX_STATE_ERROR 4 -/* ABTS ACC arrived wait for local completion to finally complete the task. */ -#define FCOE_TASK_RX_STATE_ABTS_ACC_ARRIVED 5 -/* local completion arrived wait for ABTS ACC to finally complete the task. */ -#define FCOE_TASK_RX_STATE_ABTS_LOCAL_COMP_ARRIVED 6 +/* FW only: First visit at rx-path, part of the abts round trip */ +#define FCOE_TASK_RX_STATE_ABTS_IN_PROCESS 5 +/* FW only: Second visit at rx-path, after ABTS frame transmitted */ +#define FCOE_TASK_RX_STATE_ABTS_TRANSMITTED 6 /* Special completion indication in case of task was aborted. */ #define FCOE_TASK_RX_STATE_ABTS_COMPLETED 7 -/* Special completion indication in case of task was cleaned. */ -#define FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_COMPLETED 8 -/* Special completion indication (in task requested the exchange cleanup) in - * case cleaned task is in non-valid. */ -#define FCOE_TASK_RX_STATE_ABORT_CLEANUP_COMPLETED 9 +/* FW only: First visit at rx-path, part of the cleanup round trip */ +#define FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_IN_PROCESS 8 +/* FW only: Special completion indication in case of task was cleaned. */ +#define FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_COMPLETED 9 +/* Not in used: Special completion indication (in task requested the exchange + * cleanup) in case cleaned task is in non-valid. + */ +#define FCOE_TASK_RX_STATE_ABORT_CLEANUP_COMPLETED 10 /* Special completion indication (in task requested the sequence cleanup) in - * case cleaned task was already returned to normal. */ -#define FCOE_TASK_RX_STATE_IGNORED_SEQUENCE_CLEANUP 10 -/* Exchange cleanup arrived wait until xfer will be handled to finally - * complete the task. */ -#define FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_ARRIVED 11 -/* Xfer handled, wait for exchange cleanup to finally complete the task. */ -#define FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_HANDLED_XFER 12 + * case cleaned task was already returned to normal. + */ +#define FCOE_TASK_RX_STATE_IGNORED_SEQUENCE_CLEANUP 11 + #define FCOE_TASK_TYPE_WRITE 0 #define FCOE_TASK_TYPE_READ 1 @@ -120,11 +158,40 @@ #define FCOE_TASK_CLASS_TYPE_3 0 #define FCOE_TASK_CLASS_TYPE_2 1 +/* FCoE/FC packet fields */ +#define FCOE_ETH_TYPE 0x8906 + +/* FCoE maximum elements in hash table */ +#define FCOE_MAX_ELEMENTS_IN_HASH_TABLE_ROW 8 + +/* FCoE half of the elements in hash table */ +#define FCOE_HALF_ELEMENTS_IN_HASH_TABLE_ROW \ + (FCOE_MAX_ELEMENTS_IN_HASH_TABLE_ROW / 2) + +/* FcoE number of cached T2 entries */ +#define T_FCOE_NUMBER_OF_CACHED_T2_ENTRIES (4) + +/* FCoE maximum elements in hash table */ +#define FCOE_HASH_TBL_CHUNK_SIZE 16384 + /* Everest FCoE connection type */ #define B577XX_FCOE_CONNECTION_TYPE 4 -/* Error codes for Error Reporting in fast path flows */ -/* XFER error codes */ +/* FCoE number of rows (in log). This number derives + * from the maximum connections supported which is 2048. + * TBA: Need a different constant for E2 + */ +#define FCOE_MAX_NUM_SESSIONS_LOG 11 + +#define FC_ABTS_REPLY_MAX_PAYLOAD_LEN 12 + +/* Error codes for Error Reporting in slow path flows */ +#define FCOE_SLOW_PATH_ERROR_CODE_TOO_MANY_FUNCS 0 +#define FCOE_SLOW_PATH_ERROR_CODE_NO_LICENSE 1 + +/* Error codes for Error Reporting in fast path flows + * XFER error codes + */ #define FCOE_ERROR_CODE_XFER_OOO_RO 0 #define FCOE_ERROR_CODE_XFER_RO_NOT_ALIGNED 1 #define FCOE_ERROR_CODE_XFER_NULL_BURST_LEN 2 @@ -155,17 +222,17 @@ #define FCOE_ERROR_CODE_DATA_SOFI3_SEQ_ACTIVE_SET 23 #define FCOE_ERROR_CODE_DATA_SOFN_SEQ_ACTIVE_RESET 24 #define FCOE_ERROR_CODE_DATA_EOFN_END_SEQ_SET 25 -#define FCOE_ERROR_CODE_DATA_EOFT_END_SEQ_RESET 26 -#define FCOE_ERROR_CODE_DATA_TASK_TYPE_NOT_READ 27 +#define FCOE_ERROR_CODE_DATA_EOFT_END_SEQ_RESET 26 +#define FCOE_ERROR_CODE_DATA_TASK_TYPE_NOT_READ 27 #define FCOE_ERROR_CODE_DATA_FCTL 28 /* Middle path error codes */ -#define FCOE_ERROR_CODE_MIDPATH_TYPE_NOT_ELS 29 +#define FCOE_ERROR_CODE_MIDPATH_INVALID_TYPE 29 #define FCOE_ERROR_CODE_MIDPATH_SOFI3_SEQ_ACTIVE_SET 30 #define FCOE_ERROR_CODE_MIDPATH_SOFN_SEQ_ACTIVE_RESET 31 #define FCOE_ERROR_CODE_MIDPATH_EOFN_END_SEQ_SET 32 #define FCOE_ERROR_CODE_MIDPATH_EOFT_END_SEQ_RESET 33 -#define FCOE_ERROR_CODE_MIDPATH_ELS_REPLY_FCTL 34 +#define FCOE_ERROR_CODE_MIDPATH_REPLY_FCTL 34 #define FCOE_ERROR_CODE_MIDPATH_INVALID_REPLY 35 #define FCOE_ERROR_CODE_MIDPATH_ELS_REPLY_RCTL 36 @@ -173,7 +240,7 @@ #define FCOE_ERROR_CODE_ABTS_REPLY_F_CTL 37 #define FCOE_ERROR_CODE_ABTS_REPLY_DDF_RCTL_FIELD 38 #define FCOE_ERROR_CODE_ABTS_REPLY_INVALID_BLS_RCTL 39 -#define FCOE_ERROR_CODE_ABTS_REPLY_INVALID_RCTL 40 +#define FCOE_ERROR_CODE_ABTS_REPLY_INVALID_RCTL 40 #define FCOE_ERROR_CODE_ABTS_REPLY_RCTL_GENERAL_MISMATCH 41 /* Common error codes */ @@ -185,7 +252,7 @@ #define FCOE_ERROR_CODE_COMMON_DATA_NO_MORE_SGES 47 #define FCOE_ERROR_CODE_COMMON_OPTIONAL_FC_HDR 48 #define FCOE_ERROR_CODE_COMMON_READ_TCE_OX_ID_TOO_BIG 49 -#define FCOE_ERROR_CODE_COMMON_DATA_WAS_NOT_TRANSMITTED 50 +#define FCOE_ERROR_CODE_COMMON_DATA_WAS_NOT_TRANSMITTED 50 /* Unsolicited Rx error codes */ #define FCOE_ERROR_CODE_UNSOLICITED_TYPE_NOT_ELS 51 diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c index 52c358427ce..7e89143f15c 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/drivers/scsi/bnx2fc/bnx2fc_els.c @@ -83,7 +83,7 @@ int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req) rrq.rrq_cmd = ELS_RRQ; hton24(rrq.rrq_s_id, sid); rrq.rrq_ox_id = htons(aborted_io_req->xid); - rrq.rrq_rx_id = htons(aborted_io_req->task->rx_wr_tx_rd.rx_id); + rrq.rrq_rx_id = htons(aborted_io_req->task->rxwr_txrd.var_ctx.rx_id); retry_rrq: rc = bnx2fc_initiate_els(tgt, ELS_RRQ, &rrq, sizeof(rrq), @@ -417,12 +417,13 @@ void bnx2fc_process_els_compl(struct bnx2fc_cmd *els_req, hdr = (u64 *)fc_hdr; temp_hdr = (u64 *) - &task->cmn.general.cmd_info.mp_fc_frame.fc_hdr; + &task->rxwr_only.union_ctx.comp_info.mp_rsp.fc_hdr; hdr[0] = cpu_to_be64(temp_hdr[0]); hdr[1] = cpu_to_be64(temp_hdr[1]); hdr[2] = cpu_to_be64(temp_hdr[2]); - mp_req->resp_len = task->rx_wr_only.sgl_ctx.mul_sges.cur_sge_off; + mp_req->resp_len = + task->rxwr_only.union_ctx.comp_info.mp_rsp.mp_payload_len; /* Parse ELS response */ if ((els_req->cb_func) && (els_req->cb_arg)) { diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index ab255fbc7f3..7a16ca1c3ec 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -21,7 +21,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu); #define DRV_MODULE_NAME "bnx2fc" #define DRV_MODULE_VERSION BNX2FC_VERSION -#define DRV_MODULE_RELDATE "Mar 17, 2011" +#define DRV_MODULE_RELDATE "Jun 10, 2011" static char version[] __devinitdata = @@ -612,7 +612,7 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost) BNX2FC_HBA_DBG(lport, "FW stat req timed out\n"); return bnx2fc_stats; } - bnx2fc_stats->invalid_crc_count += fw_stats->rx_stat1.fc_crc_cnt; + bnx2fc_stats->invalid_crc_count += fw_stats->rx_stat2.fc_crc_cnt; bnx2fc_stats->tx_frames += fw_stats->tx_stat.fcoe_tx_pkt_cnt; bnx2fc_stats->tx_words += (fw_stats->tx_stat.fcoe_tx_byte_cnt) / 4; bnx2fc_stats->rx_frames += fw_stats->rx_stat0.fcoe_rx_pkt_cnt; diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index f756d5f85c7..d8e8a825560 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -100,6 +100,9 @@ int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba *hba) fcoe_init2.hdr.flags = (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); + fcoe_init2.hsi_major_version = FCOE_HSI_MAJOR_VERSION; + fcoe_init2.hsi_minor_version = FCOE_HSI_MINOR_VERSION; + fcoe_init2.hash_tbl_pbl_addr_lo = (u32) hba->hash_tbl_pbl_dma; fcoe_init2.hash_tbl_pbl_addr_hi = (u32) ((u64) hba->hash_tbl_pbl_dma >> 32); @@ -122,6 +125,7 @@ int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba *hba) fcoe_init3.error_bit_map_lo = 0xffffffff; fcoe_init3.error_bit_map_hi = 0xffffffff; + fcoe_init3.perf_config = 1; kwqe_arr[0] = (struct kwqe *) &fcoe_init1; kwqe_arr[1] = (struct kwqe *) &fcoe_init2; @@ -289,19 +293,19 @@ int bnx2fc_send_session_ofld_req(struct fcoe_port *port, ofld_req4.e_d_tov_timer_val = lport->e_d_tov / 20; - ofld_req4.src_mac_addr_lo32[0] = port->data_src_addr[5]; + ofld_req4.src_mac_addr_lo[0] = port->data_src_addr[5]; /* local mac */ - ofld_req4.src_mac_addr_lo32[1] = port->data_src_addr[4]; - ofld_req4.src_mac_addr_lo32[2] = port->data_src_addr[3]; - ofld_req4.src_mac_addr_lo32[3] = port->data_src_addr[2]; - ofld_req4.src_mac_addr_hi16[0] = port->data_src_addr[1]; - ofld_req4.src_mac_addr_hi16[1] = port->data_src_addr[0]; - ofld_req4.dst_mac_addr_lo32[0] = hba->ctlr.dest_addr[5];/* fcf mac */ - ofld_req4.dst_mac_addr_lo32[1] = hba->ctlr.dest_addr[4]; - ofld_req4.dst_mac_addr_lo32[2] = hba->ctlr.dest_addr[3]; - ofld_req4.dst_mac_addr_lo32[3] = hba->ctlr.dest_addr[2]; - ofld_req4.dst_mac_addr_hi16[0] = hba->ctlr.dest_addr[1]; - ofld_req4.dst_mac_addr_hi16[1] = hba->ctlr.dest_addr[0]; + ofld_req4.src_mac_addr_lo[1] = port->data_src_addr[4]; + ofld_req4.src_mac_addr_mid[0] = port->data_src_addr[3]; + ofld_req4.src_mac_addr_mid[1] = port->data_src_addr[2]; + ofld_req4.src_mac_addr_hi[0] = port->data_src_addr[1]; + ofld_req4.src_mac_addr_hi[1] = port->data_src_addr[0]; + ofld_req4.dst_mac_addr_lo[0] = hba->ctlr.dest_addr[5];/* fcf mac */ + ofld_req4.dst_mac_addr_lo[1] = hba->ctlr.dest_addr[4]; + ofld_req4.dst_mac_addr_mid[0] = hba->ctlr.dest_addr[3]; + ofld_req4.dst_mac_addr_mid[1] = hba->ctlr.dest_addr[2]; + ofld_req4.dst_mac_addr_hi[0] = hba->ctlr.dest_addr[1]; + ofld_req4.dst_mac_addr_hi[1] = hba->ctlr.dest_addr[0]; ofld_req4.lcq_addr_lo = (u32) tgt->lcq_dma; ofld_req4.lcq_addr_hi = (u32)((u64) tgt->lcq_dma >> 32); @@ -345,20 +349,21 @@ static int bnx2fc_send_session_enable_req(struct fcoe_port *port, enbl_req.hdr.flags = (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); - enbl_req.src_mac_addr_lo32[0] = port->data_src_addr[5]; + enbl_req.src_mac_addr_lo[0] = port->data_src_addr[5]; /* local mac */ - enbl_req.src_mac_addr_lo32[1] = port->data_src_addr[4]; - enbl_req.src_mac_addr_lo32[2] = port->data_src_addr[3]; - enbl_req.src_mac_addr_lo32[3] = port->data_src_addr[2]; - enbl_req.src_mac_addr_hi16[0] = port->data_src_addr[1]; - enbl_req.src_mac_addr_hi16[1] = port->data_src_addr[0]; - - enbl_req.dst_mac_addr_lo32[0] = hba->ctlr.dest_addr[5];/* fcf mac */ - enbl_req.dst_mac_addr_lo32[1] = hba->ctlr.dest_addr[4]; - enbl_req.dst_mac_addr_lo32[2] = hba->ctlr.dest_addr[3]; - enbl_req.dst_mac_addr_lo32[3] = hba->ctlr.dest_addr[2]; - enbl_req.dst_mac_addr_hi16[0] = hba->ctlr.dest_addr[1]; - enbl_req.dst_mac_addr_hi16[1] = hba->ctlr.dest_addr[0]; + enbl_req.src_mac_addr_lo[1] = port->data_src_addr[4]; + enbl_req.src_mac_addr_mid[0] = port->data_src_addr[3]; + enbl_req.src_mac_addr_mid[1] = port->data_src_addr[2]; + enbl_req.src_mac_addr_hi[0] = port->data_src_addr[1]; + enbl_req.src_mac_addr_hi[1] = port->data_src_addr[0]; + memcpy(tgt->src_addr, port->data_src_addr, ETH_ALEN); + + enbl_req.dst_mac_addr_lo[0] = hba->ctlr.dest_addr[5];/* fcf mac */ + enbl_req.dst_mac_addr_lo[1] = hba->ctlr.dest_addr[4]; + enbl_req.dst_mac_addr_mid[0] = hba->ctlr.dest_addr[3]; + enbl_req.dst_mac_addr_mid[1] = hba->ctlr.dest_addr[2]; + enbl_req.dst_mac_addr_hi[0] = hba->ctlr.dest_addr[1]; + enbl_req.dst_mac_addr_hi[1] = hba->ctlr.dest_addr[0]; port_id = fc_host_port_id(lport->host); if (port_id != tgt->sid) { @@ -411,18 +416,19 @@ int bnx2fc_send_session_disable_req(struct fcoe_port *port, disable_req.hdr.flags = (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); - disable_req.src_mac_addr_lo32[0] = port->data_src_addr[5]; - disable_req.src_mac_addr_lo32[2] = port->data_src_addr[3]; - disable_req.src_mac_addr_lo32[3] = port->data_src_addr[2]; - disable_req.src_mac_addr_hi16[0] = port->data_src_addr[1]; - disable_req.src_mac_addr_hi16[1] = port->data_src_addr[0]; + disable_req.src_mac_addr_lo[0] = tgt->src_addr[5]; + disable_req.src_mac_addr_lo[1] = tgt->src_addr[4]; + disable_req.src_mac_addr_mid[0] = tgt->src_addr[3]; + disable_req.src_mac_addr_mid[1] = tgt->src_addr[2]; + disable_req.src_mac_addr_hi[0] = tgt->src_addr[1]; + disable_req.src_mac_addr_hi[1] = tgt->src_addr[0]; - disable_req.dst_mac_addr_lo32[0] = hba->ctlr.dest_addr[5];/* fcf mac */ - disable_req.dst_mac_addr_lo32[1] = hba->ctlr.dest_addr[4]; - disable_req.dst_mac_addr_lo32[2] = hba->ctlr.dest_addr[3]; - disable_req.dst_mac_addr_lo32[3] = hba->ctlr.dest_addr[2]; - disable_req.dst_mac_addr_hi16[0] = hba->ctlr.dest_addr[1]; - disable_req.dst_mac_addr_hi16[1] = hba->ctlr.dest_addr[0]; + disable_req.dst_mac_addr_lo[0] = hba->ctlr.dest_addr[5];/* fcf mac */ + disable_req.dst_mac_addr_lo[1] = hba->ctlr.dest_addr[4]; + disable_req.dst_mac_addr_mid[0] = hba->ctlr.dest_addr[3]; + disable_req.dst_mac_addr_mid[1] = hba->ctlr.dest_addr[2]; + disable_req.dst_mac_addr_hi[0] = hba->ctlr.dest_addr[1]; + disable_req.dst_mac_addr_hi[1] = hba->ctlr.dest_addr[0]; port_id = tgt->sid; disable_req.s_id[0] = (port_id & 0x000000FF); @@ -640,10 +646,10 @@ static void bnx2fc_process_unsol_compl(struct bnx2fc_rport *tgt, u16 wqe) xid = err_entry->fc_hdr.ox_id; BNX2FC_TGT_DBG(tgt, "Unsol Error Frame OX_ID = 0x%x\n", xid); BNX2FC_TGT_DBG(tgt, "err_warn_bitmap = %08x:%08x\n", - err_entry->err_warn_bitmap_hi, - err_entry->err_warn_bitmap_lo); + err_entry->data.err_warn_bitmap_hi, + err_entry->data.err_warn_bitmap_lo); BNX2FC_TGT_DBG(tgt, "buf_offsets - tx = 0x%x, rx = 0x%x\n", - err_entry->tx_buf_off, err_entry->rx_buf_off); + err_entry->data.tx_buf_off, err_entry->data.rx_buf_off); bnx2fc_return_rqe(tgt, 1); @@ -722,10 +728,10 @@ static void bnx2fc_process_unsol_compl(struct bnx2fc_rport *tgt, u16 wqe) xid = cpu_to_be16(err_entry->fc_hdr.ox_id); BNX2FC_TGT_DBG(tgt, "Unsol Warning Frame OX_ID = 0x%x\n", xid); BNX2FC_TGT_DBG(tgt, "err_warn_bitmap = %08x:%08x", - err_entry->err_warn_bitmap_hi, - err_entry->err_warn_bitmap_lo); + err_entry->data.err_warn_bitmap_hi, + err_entry->data.err_warn_bitmap_lo); BNX2FC_TGT_DBG(tgt, "buf_offsets - tx = 0x%x, rx = 0x%x", - err_entry->tx_buf_off, err_entry->rx_buf_off); + err_entry->data.tx_buf_off, err_entry->data.rx_buf_off); bnx2fc_return_rqe(tgt, 1); spin_unlock_bh(&tgt->tgt_lock); @@ -762,9 +768,9 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe) task_page = (struct fcoe_task_ctx_entry *)hba->task_ctx[task_idx]; task = &(task_page[index]); - num_rq = ((task->rx_wr_tx_rd.rx_flags & - FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE) >> - FCOE_TASK_CTX_ENTRY_RXWR_TXRD_NUM_RQ_WQE_SHIFT); + num_rq = ((task->rxwr_txrd.var_ctx.rx_flags & + FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE) >> + FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE_SHIFT); io_req = (struct bnx2fc_cmd *)hba->cmd_mgr->cmds[xid]; @@ -777,22 +783,19 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe) /* Timestamp IO completion time */ cmd_type = io_req->cmd_type; - /* optimized completion path */ - if (cmd_type == BNX2FC_SCSI_CMD) { - rx_state = ((task->rx_wr_tx_rd.rx_flags & - FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE) >> - FCOE_TASK_CTX_ENTRY_RXWR_TXRD_RX_STATE_SHIFT); + rx_state = ((task->rxwr_txrd.var_ctx.rx_flags & + FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE) >> + FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE_SHIFT); + /* Process other IO completion types */ + switch (cmd_type) { + case BNX2FC_SCSI_CMD: if (rx_state == FCOE_TASK_RX_STATE_COMPLETED) { bnx2fc_process_scsi_cmd_compl(io_req, task, num_rq); spin_unlock_bh(&tgt->tgt_lock); return; } - } - /* Process other IO completion types */ - switch (cmd_type) { - case BNX2FC_SCSI_CMD: if (rx_state == FCOE_TASK_RX_STATE_ABTS_COMPLETED) bnx2fc_process_abts_compl(io_req, task, num_rq); else if (rx_state == @@ -819,8 +822,16 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe) break; case BNX2FC_ELS: - BNX2FC_IO_DBG(io_req, "cq_compl - call process_els_compl\n"); - bnx2fc_process_els_compl(io_req, task, num_rq); + if (rx_state == FCOE_TASK_RX_STATE_COMPLETED) + bnx2fc_process_els_compl(io_req, task, num_rq); + else if (rx_state == FCOE_TASK_RX_STATE_ABTS_COMPLETED) + bnx2fc_process_abts_compl(io_req, task, num_rq); + else if (rx_state == + FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_COMPLETED) + bnx2fc_process_cleanup_compl(io_req, task, num_rq); + else + printk(KERN_ERR PFX "Invalid rx state = %d\n", + rx_state); break; case BNX2FC_CLEANUP: @@ -835,6 +846,20 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe) spin_unlock_bh(&tgt->tgt_lock); } +void bnx2fc_arm_cq(struct bnx2fc_rport *tgt) +{ + struct b577xx_fcoe_rx_doorbell *rx_db = &tgt->rx_db; + u32 msg; + + wmb(); + rx_db->doorbell_cq_cons = tgt->cq_cons_idx | (tgt->cq_curr_toggle_bit << + FCOE_CQE_TOGGLE_BIT_SHIFT); + msg = *((u32 *)rx_db); + writel(cpu_to_le32(msg), tgt->ctx_base); + mmiowb(); + +} + struct bnx2fc_work *bnx2fc_alloc_work(struct bnx2fc_rport *tgt, u16 wqe) { struct bnx2fc_work *work; @@ -853,8 +878,8 @@ int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt) struct fcoe_cqe *cq; u32 cq_cons; struct fcoe_cqe *cqe; + u32 num_free_sqes = 0; u16 wqe; - bool more_cqes_found = false; /* * cq_lock is a low contention lock used to protect @@ -872,62 +897,51 @@ int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt) cq_cons = tgt->cq_cons_idx; cqe = &cq[cq_cons]; - do { - more_cqes_found ^= true; - - while (((wqe = cqe->wqe) & FCOE_CQE_TOGGLE_BIT) == - (tgt->cq_curr_toggle_bit << - FCOE_CQE_TOGGLE_BIT_SHIFT)) { + while (((wqe = cqe->wqe) & FCOE_CQE_TOGGLE_BIT) == + (tgt->cq_curr_toggle_bit << + FCOE_CQE_TOGGLE_BIT_SHIFT)) { - /* new entry on the cq */ - if (wqe & FCOE_CQE_CQE_TYPE) { - /* Unsolicited event notification */ - bnx2fc_process_unsol_compl(tgt, wqe); - } else { - struct bnx2fc_work *work = NULL; - struct bnx2fc_percpu_s *fps = NULL; - unsigned int cpu = wqe % num_possible_cpus(); - - fps = &per_cpu(bnx2fc_percpu, cpu); - spin_lock_bh(&fps->fp_work_lock); - if (unlikely(!fps->iothread)) - goto unlock; - - work = bnx2fc_alloc_work(tgt, wqe); - if (work) - list_add_tail(&work->list, - &fps->work_list); + /* new entry on the cq */ + if (wqe & FCOE_CQE_CQE_TYPE) { + /* Unsolicited event notification */ + bnx2fc_process_unsol_compl(tgt, wqe); + } else { + /* Pending work request completion */ + struct bnx2fc_work *work = NULL; + struct bnx2fc_percpu_s *fps = NULL; + unsigned int cpu = wqe % num_possible_cpus(); + + fps = &per_cpu(bnx2fc_percpu, cpu); + spin_lock_bh(&fps->fp_work_lock); + if (unlikely(!fps->iothread)) + goto unlock; + + work = bnx2fc_alloc_work(tgt, wqe); + if (work) + list_add_tail(&work->list, + &fps->work_list); unlock: - spin_unlock_bh(&fps->fp_work_lock); + spin_unlock_bh(&fps->fp_work_lock); - /* Pending work request completion */ - if (fps->iothread && work) - wake_up_process(fps->iothread); - else - bnx2fc_process_cq_compl(tgt, wqe); - } - cqe++; - tgt->cq_cons_idx++; - - if (tgt->cq_cons_idx == BNX2FC_CQ_WQES_MAX) { - tgt->cq_cons_idx = 0; - cqe = cq; - tgt->cq_curr_toggle_bit = - 1 - tgt->cq_curr_toggle_bit; - } + /* Pending work request completion */ + if (fps->iothread && work) + wake_up_process(fps->iothread); + else + bnx2fc_process_cq_compl(tgt, wqe); } - /* Re-arm CQ */ - if (more_cqes_found) { - tgt->conn_db->cq_arm.lo = -1; - wmb(); + cqe++; + tgt->cq_cons_idx++; + num_free_sqes++; + + if (tgt->cq_cons_idx == BNX2FC_CQ_WQES_MAX) { + tgt->cq_cons_idx = 0; + cqe = cq; + tgt->cq_curr_toggle_bit = + 1 - tgt->cq_curr_toggle_bit; } - } while (more_cqes_found); - - /* - * Commit tgt->cq_cons_idx change to the memory - * spin_lock implies full memory barrier, no need to smp_wmb - */ - + } + bnx2fc_arm_cq(tgt); + atomic_add(num_free_sqes, &tgt->free_sqes); spin_unlock_bh(&tgt->cq_lock); return 0; } @@ -1141,7 +1155,11 @@ static void bnx2fc_init_failure(struct bnx2fc_hba *hba, u32 err_code) case FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR: printk(KERN_ERR PFX "init_failure due to NIC error\n"); break; - + case FCOE_KCQE_COMPLETION_STATUS_ERROR: + printk(KERN_ERR PFX "init failure due to compl status err\n"); + break; + case FCOE_KCQE_COMPLETION_STATUS_WRONG_HSI_VERSION: + printk(KERN_ERR PFX "init failure due to HSI mismatch\n"); default: printk(KERN_ERR PFX "Unknown Error code %d\n", err_code); } @@ -1247,21 +1265,14 @@ void bnx2fc_add_2_sq(struct bnx2fc_rport *tgt, u16 xid) void bnx2fc_ring_doorbell(struct bnx2fc_rport *tgt) { - struct b577xx_doorbell_set_prod ev_doorbell; + struct b577xx_doorbell_set_prod *sq_db = &tgt->sq_db; u32 msg; wmb(); - - memset(&ev_doorbell, 0, sizeof(struct b577xx_doorbell_set_prod)); - ev_doorbell.header.header = B577XX_DOORBELL_HDR_DB_TYPE; - - ev_doorbell.prod = tgt->sq_prod_idx | + sq_db->prod = tgt->sq_prod_idx | (tgt->sq_curr_toggle_bit << 15); - ev_doorbell.header.header |= B577XX_FCOE_CONNECTION_TYPE << - B577XX_DOORBELL_HDR_CONN_TYPE_SHIFT; - msg = *((u32 *)&ev_doorbell); + msg = *((u32 *)sq_db); writel(cpu_to_le32(msg), tgt->ctx_base); - mmiowb(); } @@ -1322,18 +1333,26 @@ void bnx2fc_init_cleanup_task(struct bnx2fc_cmd *io_req, memset(task, 0, sizeof(struct fcoe_task_ctx_entry)); /* Tx Write Rx Read */ - task->tx_wr_rx_rd.tx_flags = FCOE_TASK_TX_STATE_EXCHANGE_CLEANUP << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT; - task->tx_wr_rx_rd.init_flags = task_type << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT; - task->tx_wr_rx_rd.init_flags |= FCOE_TASK_CLASS_TYPE_3 << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT; - /* Common */ - task->cmn.common_flags = context_id << - FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID_SHIFT; - task->cmn.general.cleanup_info.task_id = orig_xid; - - + /* init flags */ + task->txwr_rxrd.const_ctx.init_flags = task_type << + FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT; + task->txwr_rxrd.const_ctx.init_flags |= FCOE_TASK_CLASS_TYPE_3 << + FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT; + task->txwr_rxrd.const_ctx.init_flags |= + FCOE_TASK_DEV_TYPE_DISK << + FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT; + task->txwr_rxrd.union_ctx.cleanup.ctx.cleaned_task_id = orig_xid; + + /* Tx flags */ + task->txwr_rxrd.const_ctx.tx_flags = + FCOE_TASK_TX_STATE_EXCHANGE_CLEANUP << + FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT; + + /* Rx Read Tx Write */ + task->rxwr_txrd.const_ctx.init_flags = context_id << + FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT; + task->rxwr_txrd.var_ctx.rx_flags |= 1 << + FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT; } void bnx2fc_init_mp_task(struct bnx2fc_cmd *io_req, @@ -1342,6 +1361,7 @@ void bnx2fc_init_mp_task(struct bnx2fc_cmd *io_req, struct bnx2fc_mp_req *mp_req = &(io_req->mp_req); struct bnx2fc_rport *tgt = io_req->tgt; struct fc_frame_header *fc_hdr; + struct fcoe_ext_mul_sges_ctx *sgl; u8 task_type = 0; u64 *hdr; u64 temp_hdr[3]; @@ -1367,47 +1387,49 @@ void bnx2fc_init_mp_task(struct bnx2fc_cmd *io_req, /* Tx only */ if ((task_type == FCOE_TASK_TYPE_MIDPATH) || (task_type == FCOE_TASK_TYPE_UNSOLICITED)) { - task->tx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.lo = + task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.lo = (u32)mp_req->mp_req_bd_dma; - task->tx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.hi = + task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.hi = (u32)((u64)mp_req->mp_req_bd_dma >> 32); - task->tx_wr_only.sgl_ctx.mul_sges.sgl_size = 1; - BNX2FC_IO_DBG(io_req, "init_mp_task - bd_dma = 0x%llx\n", - (unsigned long long)mp_req->mp_req_bd_dma); + task->txwr_only.sgl_ctx.sgl.mul_sgl.sgl_size = 1; } /* Tx Write Rx Read */ - task->tx_wr_rx_rd.tx_flags = FCOE_TASK_TX_STATE_INIT << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT; - task->tx_wr_rx_rd.init_flags = task_type << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT; - task->tx_wr_rx_rd.init_flags |= FCOE_TASK_DEV_TYPE_DISK << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT; - task->tx_wr_rx_rd.init_flags |= FCOE_TASK_CLASS_TYPE_3 << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT; - - /* Common */ - task->cmn.data_2_trns = io_req->data_xfer_len; - context_id = tgt->context_id; - task->cmn.common_flags = context_id << - FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID_SHIFT; - task->cmn.common_flags |= 1 << - FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID_SHIFT; - task->cmn.common_flags |= 1 << - FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME_SHIFT; + /* init flags */ + task->txwr_rxrd.const_ctx.init_flags = task_type << + FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT; + task->txwr_rxrd.const_ctx.init_flags |= + FCOE_TASK_DEV_TYPE_DISK << + FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT; + task->txwr_rxrd.const_ctx.init_flags |= FCOE_TASK_CLASS_TYPE_3 << + FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT; + + /* tx flags */ + task->txwr_rxrd.const_ctx.tx_flags = FCOE_TASK_TX_STATE_INIT << + FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT; /* Rx Write Tx Read */ + task->rxwr_txrd.const_ctx.data_2_trns = io_req->data_xfer_len; + + /* rx flags */ + task->rxwr_txrd.var_ctx.rx_flags |= 1 << + FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT; + + context_id = tgt->context_id; + task->rxwr_txrd.const_ctx.init_flags = context_id << + FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT; + fc_hdr = &(mp_req->req_fc_hdr); if (task_type == FCOE_TASK_TYPE_MIDPATH) { fc_hdr->fh_ox_id = cpu_to_be16(io_req->xid); fc_hdr->fh_rx_id = htons(0xffff); - task->rx_wr_tx_rd.rx_id = 0xffff; + task->rxwr_txrd.var_ctx.rx_id = 0xffff; } else if (task_type == FCOE_TASK_TYPE_UNSOLICITED) { fc_hdr->fh_rx_id = cpu_to_be16(io_req->xid); } /* Fill FC Header into middle path buffer */ - hdr = (u64 *) &task->cmn.general.cmd_info.mp_fc_frame.fc_hdr; + hdr = (u64 *) &task->txwr_rxrd.union_ctx.tx_frame.fc_hdr; memcpy(temp_hdr, fc_hdr, sizeof(temp_hdr)); hdr[0] = cpu_to_be64(temp_hdr[0]); hdr[1] = cpu_to_be64(temp_hdr[1]); @@ -1415,12 +1437,12 @@ void bnx2fc_init_mp_task(struct bnx2fc_cmd *io_req, /* Rx Only */ if (task_type == FCOE_TASK_TYPE_MIDPATH) { + sgl = &task->rxwr_only.union_ctx.read_info.sgl_ctx.sgl; - task->rx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.lo = - (u32)mp_req->mp_resp_bd_dma; - task->rx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.hi = + sgl->mul_sgl.cur_sge_addr.lo = (u32)mp_req->mp_resp_bd_dma; + sgl->mul_sgl.cur_sge_addr.hi = (u32)((u64)mp_req->mp_resp_bd_dma >> 32); - task->rx_wr_only.sgl_ctx.mul_sges.sgl_size = 1; + sgl->mul_sgl.sgl_size = 1; } } @@ -1431,6 +1453,8 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req, struct scsi_cmnd *sc_cmd = io_req->sc_cmd; struct io_bdt *bd_tbl = io_req->bd_tbl; struct bnx2fc_rport *tgt = io_req->tgt; + struct fcoe_cached_sge_ctx *cached_sge; + struct fcoe_ext_mul_sges_ctx *sgl; u64 *fcp_cmnd; u64 tmp_fcp_cmnd[4]; u32 context_id; @@ -1449,47 +1473,33 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req, /* Tx only */ if (task_type == FCOE_TASK_TYPE_WRITE) { - task->tx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.lo = + task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.lo = (u32)bd_tbl->bd_tbl_dma; - task->tx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.hi = + task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.hi = (u32)((u64)bd_tbl->bd_tbl_dma >> 32); - task->tx_wr_only.sgl_ctx.mul_sges.sgl_size = + task->txwr_only.sgl_ctx.sgl.mul_sgl.sgl_size = bd_tbl->bd_valid; } /*Tx Write Rx Read */ /* Init state to NORMAL */ - task->tx_wr_rx_rd.tx_flags = FCOE_TASK_TX_STATE_NORMAL << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TX_STATE_SHIFT; - task->tx_wr_rx_rd.init_flags = task_type << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_TASK_TYPE_SHIFT; - task->tx_wr_rx_rd.init_flags |= FCOE_TASK_DEV_TYPE_DISK << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_DEV_TYPE_SHIFT; - task->tx_wr_rx_rd.init_flags |= FCOE_TASK_CLASS_TYPE_3 << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_CLASS_TYPE_SHIFT; - - /* Common */ - task->cmn.data_2_trns = io_req->data_xfer_len; - context_id = tgt->context_id; - task->cmn.common_flags = context_id << - FCOE_TASK_CTX_ENTRY_TX_RX_CMN_CID_SHIFT; - task->cmn.common_flags |= 1 << - FCOE_TASK_CTX_ENTRY_TX_RX_CMN_VALID_SHIFT; - task->cmn.common_flags |= 1 << - FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME_SHIFT; - - /* Set initiative ownership */ - task->cmn.common_flags |= FCOE_TASK_CTX_ENTRY_TX_RX_CMN_SEQ_INIT; + task->txwr_rxrd.const_ctx.init_flags = task_type << + FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT; + task->txwr_rxrd.const_ctx.init_flags |= + FCOE_TASK_DEV_TYPE_DISK << + FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT; + task->txwr_rxrd.const_ctx.init_flags |= FCOE_TASK_CLASS_TYPE_3 << + FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT; + /* tx flags */ + task->txwr_rxrd.const_ctx.tx_flags = FCOE_TASK_TX_STATE_NORMAL << + FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT; /* Set initial seq counter */ - task->cmn.tx_low_seq_cnt = 1; - - /* Set state to "waiting for the first packet" */ - task->cmn.common_flags |= FCOE_TASK_CTX_ENTRY_TX_RX_CMN_EXP_FIRST_FRAME; + task->txwr_rxrd.union_ctx.tx_seq.ctx.seq_cnt = 1; /* Fill FCP_CMND IU */ fcp_cmnd = (u64 *) - task->cmn.general.cmd_info.fcp_cmd_payload.opaque; + task->txwr_rxrd.union_ctx.fcp_cmd.opaque; bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)&tmp_fcp_cmnd); /* swap fcp_cmnd */ @@ -1501,32 +1511,54 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req, } /* Rx Write Tx Read */ - task->rx_wr_tx_rd.rx_id = 0xffff; + task->rxwr_txrd.const_ctx.data_2_trns = io_req->data_xfer_len; + + context_id = tgt->context_id; + task->rxwr_txrd.const_ctx.init_flags = context_id << + FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT; + + /* rx flags */ + /* Set state to "waiting for the first packet" */ + task->rxwr_txrd.var_ctx.rx_flags |= 1 << + FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT; + + task->rxwr_txrd.var_ctx.rx_id = 0xffff; /* Rx Only */ + cached_sge = &task->rxwr_only.union_ctx.read_info.sgl_ctx.cached_sge; + sgl = &task->rxwr_only.union_ctx.read_info.sgl_ctx.sgl; + bd_count = bd_tbl->bd_valid; if (task_type == FCOE_TASK_TYPE_READ) { - - bd_count = bd_tbl->bd_valid; if (bd_count == 1) { struct fcoe_bd_ctx *fcoe_bd_tbl = bd_tbl->bd_tbl; - task->rx_wr_only.sgl_ctx.single_sge.cur_buf_addr.lo = - fcoe_bd_tbl->buf_addr_lo; - task->rx_wr_only.sgl_ctx.single_sge.cur_buf_addr.hi = - fcoe_bd_tbl->buf_addr_hi; - task->rx_wr_only.sgl_ctx.single_sge.cur_buf_rem = - fcoe_bd_tbl->buf_len; - task->tx_wr_rx_rd.init_flags |= 1 << - FCOE_TASK_CTX_ENTRY_TXWR_RXRD_SINGLE_SGE_SHIFT; + cached_sge->cur_buf_addr.lo = fcoe_bd_tbl->buf_addr_lo; + cached_sge->cur_buf_addr.hi = fcoe_bd_tbl->buf_addr_hi; + cached_sge->cur_buf_rem = fcoe_bd_tbl->buf_len; + task->txwr_rxrd.const_ctx.init_flags |= 1 << + FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT; + } else if (bd_count == 2) { + struct fcoe_bd_ctx *fcoe_bd_tbl = bd_tbl->bd_tbl; + + cached_sge->cur_buf_addr.lo = fcoe_bd_tbl->buf_addr_lo; + cached_sge->cur_buf_addr.hi = fcoe_bd_tbl->buf_addr_hi; + cached_sge->cur_buf_rem = fcoe_bd_tbl->buf_len; + + fcoe_bd_tbl++; + cached_sge->second_buf_addr.lo = + fcoe_bd_tbl->buf_addr_lo; + cached_sge->second_buf_addr.hi = + fcoe_bd_tbl->buf_addr_hi; + cached_sge->second_buf_rem = fcoe_bd_tbl->buf_len; + task->txwr_rxrd.const_ctx.init_flags |= 1 << + FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT; } else { - task->rx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.lo = - (u32)bd_tbl->bd_tbl_dma; - task->rx_wr_only.sgl_ctx.mul_sges.cur_sge_addr.hi = + sgl->mul_sgl.cur_sge_addr.lo = (u32)bd_tbl->bd_tbl_dma; + sgl->mul_sgl.cur_sge_addr.hi = (u32)((u64)bd_tbl->bd_tbl_dma >> 32); - task->rx_wr_only.sgl_ctx.mul_sges.sgl_size = - bd_tbl->bd_valid; + sgl->mul_sgl.sgl_size = bd_count; } } } diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index b5b5c346d77..5dc4205ed8a 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -425,6 +425,7 @@ struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type) struct list_head *listp; struct io_bdt *bd_tbl; int index = RESERVE_FREE_LIST_INDEX; + u32 free_sqes; u32 max_sqes; u16 xid; @@ -445,8 +446,10 @@ struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type) * cmgr lock */ spin_lock_bh(&cmd_mgr->free_list_lock[index]); + free_sqes = atomic_read(&tgt->free_sqes); if ((list_empty(&(cmd_mgr->free_list[index]))) || - (tgt->num_active_ios.counter >= max_sqes)) { + (tgt->num_active_ios.counter >= max_sqes) || + (free_sqes + max_sqes <= BNX2FC_SQ_WQES_MAX)) { BNX2FC_TGT_DBG(tgt, "No free els_tm cmds available " "ios(%d):sqes(%d)\n", tgt->num_active_ios.counter, tgt->max_sqes); @@ -463,6 +466,7 @@ struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type) xid = io_req->xid; cmd_mgr->cmds[xid] = io_req; atomic_inc(&tgt->num_active_ios); + atomic_dec(&tgt->free_sqes); spin_unlock_bh(&cmd_mgr->free_list_lock[index]); INIT_LIST_HEAD(&io_req->link); @@ -489,6 +493,7 @@ static struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt) struct bnx2fc_cmd *io_req; struct list_head *listp; struct io_bdt *bd_tbl; + u32 free_sqes; u32 max_sqes; u16 xid; int index = get_cpu(); @@ -499,8 +504,10 @@ static struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt) * cmgr lock */ spin_lock_bh(&cmd_mgr->free_list_lock[index]); + free_sqes = atomic_read(&tgt->free_sqes); if ((list_empty(&cmd_mgr->free_list[index])) || - (tgt->num_active_ios.counter >= max_sqes)) { + (tgt->num_active_ios.counter >= max_sqes) || + (free_sqes + max_sqes <= BNX2FC_SQ_WQES_MAX)) { spin_unlock_bh(&cmd_mgr->free_list_lock[index]); put_cpu(); return NULL; @@ -513,6 +520,7 @@ static struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt) xid = io_req->xid; cmd_mgr->cmds[xid] = io_req; atomic_inc(&tgt->num_active_ios); + atomic_dec(&tgt->free_sqes); spin_unlock_bh(&cmd_mgr->free_list_lock[index]); put_cpu(); @@ -873,7 +881,7 @@ int bnx2fc_initiate_abts(struct bnx2fc_cmd *io_req) /* Obtain oxid and rxid for the original exchange to be aborted */ fc_hdr->fh_ox_id = htons(io_req->xid); - fc_hdr->fh_rx_id = htons(io_req->task->rx_wr_tx_rd.rx_id); + fc_hdr->fh_rx_id = htons(io_req->task->rxwr_txrd.var_ctx.rx_id); sid = tgt->sid; did = rport->port_id; @@ -1189,7 +1197,7 @@ void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, kref_put(&io_req->refcount, bnx2fc_cmd_release); /* drop timer hold */ - r_ctl = task->cmn.general.rsp_info.abts_rsp.r_ctl; + r_ctl = (u8)task->rxwr_only.union_ctx.comp_info.abts_rsp.r_ctl; switch (r_ctl) { case FC_RCTL_BA_ACC: @@ -1344,12 +1352,13 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req, fc_hdr = &(tm_req->resp_fc_hdr); hdr = (u64 *)fc_hdr; temp_hdr = (u64 *) - &task->cmn.general.cmd_info.mp_fc_frame.fc_hdr; + &task->rxwr_only.union_ctx.comp_info.mp_rsp.fc_hdr; hdr[0] = cpu_to_be64(temp_hdr[0]); hdr[1] = cpu_to_be64(temp_hdr[1]); hdr[2] = cpu_to_be64(temp_hdr[2]); - tm_req->resp_len = task->rx_wr_only.sgl_ctx.mul_sges.cur_sge_off; + tm_req->resp_len = + task->rxwr_only.union_ctx.comp_info.mp_rsp.mp_payload_len; rsp_buf = tm_req->resp_buf; @@ -1724,7 +1733,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req, /* Fetch fcp_rsp from task context and perform cmd completion */ fcp_rsp = (struct fcoe_fcp_rsp_payload *) - &(task->cmn.general.rsp_info.fcp_rsp.payload); + &(task->rxwr_only.union_ctx.comp_info.fcp_rsp.payload); /* parse fcp_rsp and obtain sense data from RQ if available */ bnx2fc_parse_fcp_rsp(io_req, fcp_rsp, num_rq); diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index a2e3830bd26..3e892bd66fb 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -133,6 +133,8 @@ retry_ofld: /* upload will take care of cleaning up sess resc */ lport->tt.rport_logoff(rdata); } + /* Arm CQ */ + bnx2fc_arm_cq(tgt); return; ofld_err: @@ -315,6 +317,8 @@ static int bnx2fc_init_tgt(struct bnx2fc_rport *tgt, struct fc_rport *rport = rdata->rport; struct bnx2fc_hba *hba = port->priv; + struct b577xx_doorbell_set_prod *sq_db = &tgt->sq_db; + struct b577xx_fcoe_rx_doorbell *rx_db = &tgt->rx_db; tgt->rport = rport; tgt->rdata = rdata; @@ -335,6 +339,7 @@ static int bnx2fc_init_tgt(struct bnx2fc_rport *tgt, tgt->max_sqes = BNX2FC_SQ_WQES_MAX; tgt->max_rqes = BNX2FC_RQ_WQES_MAX; tgt->max_cqes = BNX2FC_CQ_WQES_MAX; + atomic_set(&tgt->free_sqes, BNX2FC_SQ_WQES_MAX); /* Initialize the toggle bit */ tgt->sq_curr_toggle_bit = 1; @@ -345,7 +350,17 @@ static int bnx2fc_init_tgt(struct bnx2fc_rport *tgt, tgt->rq_cons_idx = 0; atomic_set(&tgt->num_active_ios, 0); - tgt->work_time_slice = 2; + /* initialize sq doorbell */ + sq_db->header.header = B577XX_DOORBELL_HDR_DB_TYPE; + sq_db->header.header |= B577XX_FCOE_CONNECTION_TYPE << + B577XX_DOORBELL_HDR_CONN_TYPE_SHIFT; + /* initialize rx doorbell */ + rx_db->hdr.header = ((0x1 << B577XX_DOORBELL_HDR_RX_SHIFT) | + (0x1 << B577XX_DOORBELL_HDR_DB_TYPE_SHIFT) | + (B577XX_FCOE_CONNECTION_TYPE << + B577XX_DOORBELL_HDR_CONN_TYPE_SHIFT)); + rx_db->params = (0x2 << B577XX_FCOE_RX_DOORBELL_NEGATIVE_ARM_SHIFT) | + (0x3 << B577XX_FCOE_RX_DOORBELL_OPCODE_SHIFT); spin_lock_init(&tgt->tgt_lock); spin_lock_init(&tgt->cq_lock); @@ -758,8 +773,6 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, } memset(tgt->lcq, 0, tgt->lcq_mem_size); - /* Arm CQ */ - tgt->conn_db->cq_arm.lo = -1; tgt->conn_db->rq_prod = 0x8000; return 0; @@ -787,6 +800,8 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, iounmap(tgt->ctx_base); tgt->ctx_base = NULL; } + + spin_lock_bh(&tgt->cq_lock); /* Free LCQ */ if (tgt->lcq) { dma_free_coherent(&hba->pcidev->dev, tgt->lcq_mem_size, @@ -828,17 +843,16 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, tgt->rq = NULL; } /* Free CQ */ - spin_lock_bh(&tgt->cq_lock); if (tgt->cq) { dma_free_coherent(&hba->pcidev->dev, tgt->cq_mem_size, tgt->cq, tgt->cq_dma); tgt->cq = NULL; } - spin_unlock_bh(&tgt->cq_lock); /* Free SQ */ if (tgt->sq) { dma_free_coherent(&hba->pcidev->dev, tgt->sq_mem_size, tgt->sq, tgt->sq_dma); tgt->sq = NULL; } + spin_unlock_bh(&tgt->cq_lock); } diff --git a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h index dad6c8a3431..71890a063cd 100644 --- a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h +++ b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h @@ -707,8 +707,10 @@ struct iscsi_kwqe_conn_update { #define ISCSI_KWQE_CONN_UPDATE_INITIAL_R2T_SHIFT 2 #define ISCSI_KWQE_CONN_UPDATE_IMMEDIATE_DATA (0x1<<3) #define ISCSI_KWQE_CONN_UPDATE_IMMEDIATE_DATA_SHIFT 3 -#define ISCSI_KWQE_CONN_UPDATE_RESERVED1 (0xF<<4) -#define ISCSI_KWQE_CONN_UPDATE_RESERVED1_SHIFT 4 +#define ISCSI_KWQE_CONN_UPDATE_OOO_SUPPORT_MODE (0x3<<4) +#define ISCSI_KWQE_CONN_UPDATE_OOO_SUPPORT_MODE_SHIFT 4 +#define ISCSI_KWQE_CONN_UPDATE_RESERVED1 (0x3<<6) +#define ISCSI_KWQE_CONN_UPDATE_RESERVED1_SHIFT 6 #elif defined(__LITTLE_ENDIAN) u8 conn_flags; #define ISCSI_KWQE_CONN_UPDATE_HEADER_DIGEST (0x1<<0) @@ -719,8 +721,10 @@ struct iscsi_kwqe_conn_update { #define ISCSI_KWQE_CONN_UPDATE_INITIAL_R2T_SHIFT 2 #define ISCSI_KWQE_CONN_UPDATE_IMMEDIATE_DATA (0x1<<3) #define ISCSI_KWQE_CONN_UPDATE_IMMEDIATE_DATA_SHIFT 3 -#define ISCSI_KWQE_CONN_UPDATE_RESERVED1 (0xF<<4) -#define ISCSI_KWQE_CONN_UPDATE_RESERVED1_SHIFT 4 +#define ISCSI_KWQE_CONN_UPDATE_OOO_SUPPORT_MODE (0x3<<4) +#define ISCSI_KWQE_CONN_UPDATE_OOO_SUPPORT_MODE_SHIFT 4 +#define ISCSI_KWQE_CONN_UPDATE_RESERVED1 (0x3<<6) +#define ISCSI_KWQE_CONN_UPDATE_RESERVED1_SHIFT 6 u8 reserved2; u8 max_outstanding_r2ts; u8 session_error_recovery_level; -- cgit v1.2.3-70-g09d2 From c9ee92062424375fe6e73c4af5d52df289ccf9eb Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 14 Jun 2011 01:33:51 +0000 Subject: bnx2x: 57712 parity handling - Added support for a parity error handling for a 57712 chip. - Changed the parity recovery scheme from per-chip to per-engine. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 25 +- drivers/net/bnx2x/bnx2x_cmn.c | 57 ++- drivers/net/bnx2x/bnx2x_cmn.h | 16 +- drivers/net/bnx2x/bnx2x_ethtool.c | 3 +- drivers/net/bnx2x/bnx2x_init.h | 11 +- drivers/net/bnx2x/bnx2x_main.c | 753 +++++++++++++++++++++++++++++--------- drivers/net/bnx2x/bnx2x_reg.h | 158 ++++---- 7 files changed, 769 insertions(+), 254 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index b4b3abe9e7c..c108e4cf633 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -733,7 +733,6 @@ struct bnx2x_common { #define CHIP_METAL(bp) (bp->common.chip_id & 0x00000ff0) #define CHIP_BOND_ID(bp) (bp->common.chip_id & 0x0000000f) -#define CHIP_PARITY_ENABLED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) #define CHIP_REV_SIM(bp) (((CHIP_REV_MASK - CHIP_REV_VAL(bp)) >>\ (CHIP_REV_SHIFT + 1)) \ << CHIP_REV_SHIFT) @@ -986,11 +985,13 @@ struct hw_context { /* forward */ struct bnx2x_ilt; -typedef enum { + +enum bnx2x_recovery_state { BNX2X_RECOVERY_DONE, BNX2X_RECOVERY_INIT, BNX2X_RECOVERY_WAIT, -} bnx2x_recovery_state_t; + BNX2X_RECOVERY_FAILED +}; /* * Event queue (EQ or event ring) MC hsi @@ -1076,7 +1077,7 @@ struct bnx2x { const struct iro *iro_arr; #define IRO (bp->iro_arr) - bnx2x_recovery_state_t recovery_state; + enum bnx2x_recovery_state recovery_state; int is_leader; struct msix_entry *msix_table; @@ -1800,12 +1801,14 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, (AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT | \ AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT | \ AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT | \ - AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT) + AEU_INPUTS_ATTN_BITS_PBCLIENT_HW_INTERRUPT) #define HW_PRTY_ASSERT_SET_0 (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR |\ - AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR) + AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR) #define HW_INTERRUT_ASSERT_SET_1 \ (AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT | \ AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT | \ @@ -1818,17 +1821,22 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT | \ AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT | \ AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT) -#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR |\ +#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR | \ - AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR) + AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR) #define HW_INTERRUT_ASSERT_SET_2 \ (AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT | \ AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT | \ @@ -1840,6 +1848,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR |\ AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index ebd8b1cdd58..04cacbf5d71 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1918,13 +1918,23 @@ load_error0: int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) { int i; - - if (bp->state == BNX2X_STATE_CLOSED) { - /* Interface has been removed - nothing to recover */ + bool global = false; + + if ((bp->state == BNX2X_STATE_CLOSED) || + (bp->state == BNX2X_STATE_ERROR)) { + /* We can get here if the driver has been unloaded + * during parity error recovery and is either waiting for a + * leader to complete or for other functions to unload and + * then ifdown has been issued. In this case we want to + * unload and let other functions to complete a recovery + * process. + */ bp->recovery_state = BNX2X_RECOVERY_DONE; bp->is_leader = 0; - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08); - smp_wmb(); + bnx2x_release_leader_lock(bp); + smp_mb(); + + DP(NETIF_MSG_HW, "Releasing a leadership...\n"); return -EINVAL; } @@ -1953,11 +1963,27 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) if (unload_mode != UNLOAD_RECOVERY) bnx2x_chip_cleanup(bp, unload_mode); else { - /* Disable HW interrupts, NAPI and Tx */ + /* Send the UNLOAD_REQUEST to the MCP */ + bnx2x_send_unload_req(bp, unload_mode); + + /* + * Prevent transactions to host from the functions on the + * engine that doesn't reset global blocks in case of global + * attention once gloabl blocks are reset and gates are opened + * (the engine which leader will perform the recovery + * last). + */ + if (!CHIP_IS_E1x(bp)) + bnx2x_pf_disable(bp); + + /* Disable HW interrupts, NAPI */ bnx2x_netif_stop(bp, 1); /* Release IRQs */ bnx2x_free_irq(bp); + + /* Report UNLOAD_DONE to MCP */ + bnx2x_send_unload_done(bp); } /* @@ -1977,17 +2003,24 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->state = BNX2X_STATE_CLOSED; + /* Check if there are pending parity attentions. If there are - set + * RECOVERY_IN_PROGRESS. + */ + if (bnx2x_chk_parity_attn(bp, &global, false)) { + bnx2x_set_reset_in_progress(bp); + + /* Set RESET_IS_GLOBAL if needed */ + if (global) + bnx2x_set_reset_global(bp); + } + + /* The last driver must disable a "close the gate" if there is no * parity attention or "process kill" pending. */ - if ((!bnx2x_dec_load_cnt(bp)) && (!bnx2x_chk_parity_attn(bp)) && - bnx2x_reset_is_done(bp)) + if (!bnx2x_dec_load_cnt(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp))) bnx2x_disable_close_the_gate(bp); - /* Reset MCP mail box sequence if there is on going recovery */ - if (unload_mode == UNLOAD_RECOVERY) - bp->fw_seq = 0; - return 0; } diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 944bcaeeba4..c016e20c5c2 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -181,6 +181,9 @@ void bnx2x_drv_pulse(struct bnx2x *bp); void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, u16 index, u8 op, u8 update); +/* Disable transactions from chip to host */ +void bnx2x_pf_disable(struct bnx2x *bp); + /** * bnx2x__link_status_update - handles link status change. * @@ -320,6 +323,13 @@ int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource); */ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); +/** + * bnx2x_release_leader_lock - release recovery leader lock + * + * @bp: driver handle + */ +int bnx2x_release_leader_lock(struct bnx2x *bp); + /** * bnx2x_set_eth_mac - configure eth MAC address in the HW * @@ -370,8 +380,10 @@ void bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, /* Parity errors related */ void bnx2x_inc_load_cnt(struct bnx2x *bp); u32 bnx2x_dec_load_cnt(struct bnx2x *bp); -bool bnx2x_chk_parity_attn(struct bnx2x *bp); -bool bnx2x_reset_is_done(struct bnx2x *bp); +bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print); +bool bnx2x_reset_is_done(struct bnx2x *bp, int engine); +void bnx2x_set_reset_in_progress(struct bnx2x *bp); +void bnx2x_set_reset_global(struct bnx2x *bp); void bnx2x_disable_close_the_gate(struct bnx2x *bp); /** diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 1b4fa1d9800..965fb071fbe 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -634,8 +634,7 @@ static void bnx2x_get_regs(struct net_device *dev, } /* Re-enable parity attentions */ bnx2x_clear_blocks_parity(bp); - if (CHIP_PARITY_ENABLED(bp)) - bnx2x_enable_blocks_parity(bp); + bnx2x_enable_blocks_parity(bp); } static void bnx2x_get_drvinfo(struct net_device *dev, diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 8b1d6258443..df9f196dd6e 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -377,12 +377,15 @@ static const struct { BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), + BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0), + BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff), + BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xffff), BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff), BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1), BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff), BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3), {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, - GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0, + GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf, {0xf, 0xf, 0xf}, "UPB"}, {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0, @@ -394,10 +397,16 @@ static const struct { BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf), BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf), BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff), + BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffffff), + BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f), BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff), BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff), BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff), BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff), BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f), BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 63c92091586..7ffb6e651e1 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1606,6 +1606,34 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) return false; } +/** + * bnx2x_get_leader_lock_resource - get the recovery leader resource id + * + * @bp: driver handle + * + * Returns the recovery leader resource id according to the engine this function + * belongs to. Currently only only 2 engines is supported. + */ +static inline int bnx2x_get_leader_lock_resource(struct bnx2x *bp) +{ + if (BP_PATH(bp)) + return HW_LOCK_RESOURCE_RECOVERY_LEADER_1; + else + return HW_LOCK_RESOURCE_RECOVERY_LEADER_0; +} + +/** + * bnx2x_trylock_leader_lock- try to aquire a leader lock. + * + * @bp: driver handle + * + * Tries to aquire a leader lock for cuurent engine. + */ +static inline bool bnx2x_trylock_leader_lock(struct bnx2x *bp) +{ + return bnx2x_trylock_hw_lock(bp, bnx2x_get_leader_lock_resource(bp)); +} + #ifdef BCM_CNIC static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid, u8 err); #endif @@ -1802,6 +1830,11 @@ int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource) return -EAGAIN; } +int bnx2x_release_leader_lock(struct bnx2x *bp) +{ + return bnx2x_release_hw_lock(bp, bnx2x_get_leader_lock_resource(bp)); +} + int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource) { u32 lock_status; @@ -3323,72 +3356,185 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) } } -#define BNX2X_MISC_GEN_REG MISC_REG_GENERIC_POR_1 -#define LOAD_COUNTER_BITS 16 /* Number of bits for load counter */ -#define LOAD_COUNTER_MASK (((u32)0x1 << LOAD_COUNTER_BITS) - 1) -#define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK) -#define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS +/* + * Bits map: + * 0-7 - Engine0 load counter. + * 8-15 - Engine1 load counter. + * 16 - Engine0 RESET_IN_PROGRESS bit. + * 17 - Engine1 RESET_IN_PROGRESS bit. + * 18 - Engine0 ONE_IS_LOADED. Set when there is at least one active function + * on the engine + * 19 - Engine1 ONE_IS_LOADED. + * 20 - Chip reset flow bit. When set none-leader must wait for both engines + * leader to complete (check for both RESET_IN_PROGRESS bits and not for + * just the one belonging to its engine). + * + */ +#define BNX2X_RECOVERY_GLOB_REG MISC_REG_GENERIC_POR_1 + +#define BNX2X_PATH0_LOAD_CNT_MASK 0x000000ff +#define BNX2X_PATH0_LOAD_CNT_SHIFT 0 +#define BNX2X_PATH1_LOAD_CNT_MASK 0x0000ff00 +#define BNX2X_PATH1_LOAD_CNT_SHIFT 8 +#define BNX2X_PATH0_RST_IN_PROG_BIT 0x00010000 +#define BNX2X_PATH1_RST_IN_PROG_BIT 0x00020000 +#define BNX2X_GLOBAL_RESET_BIT 0x00040000 /* + * Set the GLOBAL_RESET bit. + * + * Should be run under rtnl lock + */ +void bnx2x_set_reset_global(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val | BNX2X_GLOBAL_RESET_BIT); + barrier(); + mmiowb(); +} + +/* + * Clear the GLOBAL_RESET bit. + * + * Should be run under rtnl lock + */ +static inline void bnx2x_clear_reset_global(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~BNX2X_GLOBAL_RESET_BIT)); + barrier(); + mmiowb(); +} + +/* + * Checks the GLOBAL_RESET bit. + * * should be run under rtnl lock */ +static inline bool bnx2x_reset_is_global(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + + DP(NETIF_MSG_HW, "GEN_REG_VAL=0x%08x\n", val); + return (val & BNX2X_GLOBAL_RESET_BIT) ? true : false; +} + +/* + * Clear RESET_IN_PROGRESS bit for the current engine. + * + * Should be run under rtnl lock + */ static inline void bnx2x_set_reset_done(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - val &= ~(1 << RESET_DONE_FLAG_SHIFT); - REG_WR(bp, BNX2X_MISC_GEN_REG, val); + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 bit = BP_PATH(bp) ? + BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; + + /* Clear the bit */ + val &= ~bit; + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); barrier(); mmiowb(); } /* + * Set RESET_IN_PROGRESS for the current engine. + * * should be run under rtnl lock */ -static inline void bnx2x_set_reset_in_progress(struct bnx2x *bp) +void bnx2x_set_reset_in_progress(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - val |= (1 << 16); - REG_WR(bp, BNX2X_MISC_GEN_REG, val); + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 bit = BP_PATH(bp) ? + BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; + + /* Set the bit */ + val |= bit; + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); barrier(); mmiowb(); } /* + * Checks the RESET_IN_PROGRESS bit for the given engine. * should be run under rtnl lock */ -bool bnx2x_reset_is_done(struct bnx2x *bp) +bool bnx2x_reset_is_done(struct bnx2x *bp, int engine) { - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - DP(NETIF_MSG_HW, "GEN_REG_VAL=0x%08x\n", val); - return (val & RESET_DONE_FLAG_MASK) ? false : true; + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 bit = engine ? + BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; + + /* return false if bit is set */ + return (val & bit) ? false : true; } /* + * Increment the load counter for the current engine. + * * should be run under rtnl lock */ -inline void bnx2x_inc_load_cnt(struct bnx2x *bp) +void bnx2x_inc_load_cnt(struct bnx2x *bp) { - u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG); + u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : + BNX2X_PATH0_LOAD_CNT_MASK; + u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : + BNX2X_PATH0_LOAD_CNT_SHIFT; DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); - val1 = ((val & LOAD_COUNTER_MASK) + 1) & LOAD_COUNTER_MASK; - REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1); + /* get the current counter value */ + val1 = (val & mask) >> shift; + + /* increment... */ + val1++; + + /* clear the old value */ + val &= ~mask; + + /* set the new one */ + val |= ((val1 << shift) & mask); + + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); barrier(); mmiowb(); } -/* - * should be run under rtnl lock +/** + * bnx2x_dec_load_cnt - decrement the load counter + * + * @bp: driver handle + * + * Should be run under rtnl lock. + * Decrements the load counter for the current engine. Returns + * the new counter value. */ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) { - u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG); + u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : + BNX2X_PATH0_LOAD_CNT_MASK; + u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : + BNX2X_PATH0_LOAD_CNT_SHIFT; DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); - val1 = ((val & LOAD_COUNTER_MASK) - 1) & LOAD_COUNTER_MASK; - REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1); + /* get the current counter value */ + val1 = (val & mask) >> shift; + + /* decrement... */ + val1--; + + /* clear the old value */ + val &= ~mask; + + /* set the new one */ + val |= ((val1 << shift) & mask); + + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); barrier(); mmiowb(); @@ -3396,17 +3542,39 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) } /* + * Read the load counter for the current engine. + * * should be run under rtnl lock */ -static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp) +static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine) { - return REG_RD(bp, BNX2X_MISC_GEN_REG) & LOAD_COUNTER_MASK; + u32 mask = (engine ? BNX2X_PATH1_LOAD_CNT_MASK : + BNX2X_PATH0_LOAD_CNT_MASK); + u32 shift = (engine ? BNX2X_PATH1_LOAD_CNT_SHIFT : + BNX2X_PATH0_LOAD_CNT_SHIFT); + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + + DP(NETIF_MSG_HW, "GLOB_REG=0x%08x\n", val); + + val = (val & mask) >> shift; + + DP(NETIF_MSG_HW, "load_cnt for engine %d = %d\n", engine, val); + + return val; } +/* + * Reset the load counter for the current engine. + * + * should be run under rtnl lock + */ static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - REG_WR(bp, BNX2X_MISC_GEN_REG, val & (~LOAD_COUNTER_MASK)); + u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : + BNX2X_PATH0_LOAD_CNT_MASK); + + REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); } static inline void _print_next_block(int idx, const char *blk) @@ -3416,7 +3584,8 @@ static inline void _print_next_block(int idx, const char *blk) pr_cont("%s", blk); } -static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num) +static inline int bnx2x_check_blocks_with_parity0(u32 sig, int par_num, + bool print) { int i = 0; u32 cur_bit = 0; @@ -3425,19 +3594,33 @@ static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num) if (sig & cur_bit) { switch (cur_bit) { case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR: - _print_next_block(par_num++, "BRB"); + if (print) + _print_next_block(par_num++, "BRB"); break; case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR: - _print_next_block(par_num++, "PARSER"); + if (print) + _print_next_block(par_num++, "PARSER"); break; case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR: - _print_next_block(par_num++, "TSDM"); + if (print) + _print_next_block(par_num++, "TSDM"); break; case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR: - _print_next_block(par_num++, "SEARCHER"); + if (print) + _print_next_block(par_num++, + "SEARCHER"); + break; + case AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "TCM"); break; case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR: - _print_next_block(par_num++, "TSEMI"); + if (print) + _print_next_block(par_num++, "TSEMI"); + break; + case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "XPB"); break; } @@ -3449,7 +3632,8 @@ static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num) return par_num; } -static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num) +static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num, + bool *global, bool print) { int i = 0; u32 cur_bit = 0; @@ -3457,38 +3641,64 @@ static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num) cur_bit = ((u32)0x1 << i); if (sig & cur_bit) { switch (cur_bit) { - case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR: - _print_next_block(par_num++, "PBCLIENT"); + case AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "PBF"); break; case AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR: - _print_next_block(par_num++, "QM"); + if (print) + _print_next_block(par_num++, "QM"); + break; + case AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "TM"); break; case AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR: - _print_next_block(par_num++, "XSDM"); + if (print) + _print_next_block(par_num++, "XSDM"); + break; + case AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "XCM"); break; case AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR: - _print_next_block(par_num++, "XSEMI"); + if (print) + _print_next_block(par_num++, "XSEMI"); break; case AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR: - _print_next_block(par_num++, "DOORBELLQ"); + if (print) + _print_next_block(par_num++, + "DOORBELLQ"); + break; + case AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "NIG"); break; case AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR: - _print_next_block(par_num++, "VAUX PCI CORE"); + if (print) + _print_next_block(par_num++, + "VAUX PCI CORE"); + *global = true; break; case AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR: - _print_next_block(par_num++, "DEBUG"); + if (print) + _print_next_block(par_num++, "DEBUG"); break; case AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR: - _print_next_block(par_num++, "USDM"); + if (print) + _print_next_block(par_num++, "USDM"); break; case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR: - _print_next_block(par_num++, "USEMI"); + if (print) + _print_next_block(par_num++, "USEMI"); break; case AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR: - _print_next_block(par_num++, "UPB"); + if (print) + _print_next_block(par_num++, "UPB"); break; case AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR: - _print_next_block(par_num++, "CSDM"); + if (print) + _print_next_block(par_num++, "CSDM"); break; } @@ -3500,7 +3710,8 @@ static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num) return par_num; } -static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num) +static inline int bnx2x_check_blocks_with_parity2(u32 sig, int par_num, + bool print) { int i = 0; u32 cur_bit = 0; @@ -3509,26 +3720,37 @@ static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num) if (sig & cur_bit) { switch (cur_bit) { case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR: - _print_next_block(par_num++, "CSEMI"); + if (print) + _print_next_block(par_num++, "CSEMI"); break; case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR: - _print_next_block(par_num++, "PXP"); + if (print) + _print_next_block(par_num++, "PXP"); break; case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR: - _print_next_block(par_num++, + if (print) + _print_next_block(par_num++, "PXPPCICLOCKCLIENT"); break; case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR: - _print_next_block(par_num++, "CFC"); + if (print) + _print_next_block(par_num++, "CFC"); break; case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR: - _print_next_block(par_num++, "CDU"); + if (print) + _print_next_block(par_num++, "CDU"); + break; + case AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "DMAE"); break; case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR: - _print_next_block(par_num++, "IGU"); + if (print) + _print_next_block(par_num++, "IGU"); break; case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR: - _print_next_block(par_num++, "MISC"); + if (print) + _print_next_block(par_num++, "MISC"); break; } @@ -3540,7 +3762,8 @@ static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num) return par_num; } -static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num) +static inline int bnx2x_check_blocks_with_parity3(u32 sig, int par_num, + bool *global, bool print) { int i = 0; u32 cur_bit = 0; @@ -3549,16 +3772,27 @@ static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num) if (sig & cur_bit) { switch (cur_bit) { case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY: - _print_next_block(par_num++, "MCP ROM"); + if (print) + _print_next_block(par_num++, "MCP ROM"); + *global = true; break; case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY: - _print_next_block(par_num++, "MCP UMP RX"); + if (print) + _print_next_block(par_num++, + "MCP UMP RX"); + *global = true; break; case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY: - _print_next_block(par_num++, "MCP UMP TX"); + if (print) + _print_next_block(par_num++, + "MCP UMP TX"); + *global = true; break; case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY: - _print_next_block(par_num++, "MCP SCPAD"); + if (print) + _print_next_block(par_num++, + "MCP SCPAD"); + *global = true; break; } @@ -3570,8 +3804,8 @@ static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num) return par_num; } -static inline bool bnx2x_parity_attn(struct bnx2x *bp, u32 sig0, u32 sig1, - u32 sig2, u32 sig3) +static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, + u32 sig0, u32 sig1, u32 sig2, u32 sig3) { if ((sig0 & HW_PRTY_ASSERT_SET_0) || (sig1 & HW_PRTY_ASSERT_SET_1) || (sig2 & HW_PRTY_ASSERT_SET_2) || (sig3 & HW_PRTY_ASSERT_SET_3)) { @@ -3583,23 +3817,32 @@ static inline bool bnx2x_parity_attn(struct bnx2x *bp, u32 sig0, u32 sig1, sig1 & HW_PRTY_ASSERT_SET_1, sig2 & HW_PRTY_ASSERT_SET_2, sig3 & HW_PRTY_ASSERT_SET_3); - printk(KERN_ERR"%s: Parity errors detected in blocks: ", - bp->dev->name); - par_num = bnx2x_print_blocks_with_parity0( - sig0 & HW_PRTY_ASSERT_SET_0, par_num); - par_num = bnx2x_print_blocks_with_parity1( - sig1 & HW_PRTY_ASSERT_SET_1, par_num); - par_num = bnx2x_print_blocks_with_parity2( - sig2 & HW_PRTY_ASSERT_SET_2, par_num); - par_num = bnx2x_print_blocks_with_parity3( - sig3 & HW_PRTY_ASSERT_SET_3, par_num); - printk("\n"); + if (print) + netdev_err(bp->dev, + "Parity errors detected in blocks: "); + par_num = bnx2x_check_blocks_with_parity0( + sig0 & HW_PRTY_ASSERT_SET_0, par_num, print); + par_num = bnx2x_check_blocks_with_parity1( + sig1 & HW_PRTY_ASSERT_SET_1, par_num, global, print); + par_num = bnx2x_check_blocks_with_parity2( + sig2 & HW_PRTY_ASSERT_SET_2, par_num, print); + par_num = bnx2x_check_blocks_with_parity3( + sig3 & HW_PRTY_ASSERT_SET_3, par_num, global, print); + if (print) + pr_cont("\n"); return true; } else return false; } -bool bnx2x_chk_parity_attn(struct bnx2x *bp) +/** + * bnx2x_chk_parity_attn - checks for parity attentions. + * + * @bp: driver handle + * @global: true if there was a global attention + * @print: show parity attention in syslog + */ +bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) { struct attn_route attn; int port = BP_PORT(bp); @@ -3617,8 +3860,8 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp) MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - return bnx2x_parity_attn(bp, attn.sig[0], attn.sig[1], attn.sig[2], - attn.sig[3]); + return bnx2x_parity_attn(bp, global, print, attn.sig[0], attn.sig[1], + attn.sig[2], attn.sig[3]); } @@ -3697,21 +3940,25 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) u32 reg_addr; u32 val; u32 aeu_mask; + bool global = false; /* need to take HW lock because MCP or other port might also try to handle this event */ bnx2x_acquire_alr(bp); - if (CHIP_PARITY_ENABLED(bp) && bnx2x_chk_parity_attn(bp)) { + if (bnx2x_chk_parity_attn(bp, &global, true)) { +#ifndef BNX2X_STOP_ON_ERROR bp->recovery_state = BNX2X_RECOVERY_INIT; - bnx2x_set_reset_in_progress(bp); schedule_delayed_work(&bp->reset_task, 0); /* Disable HW interrupts */ bnx2x_int_disable(bp); - bnx2x_release_alr(bp); /* In case of parity errors don't handle attentions so that * other function would "see" parity errors. */ +#else + bnx2x_panic(); +#endif + bnx2x_release_alr(bp); return; } @@ -5289,7 +5536,7 @@ static void bnx2x_pretend_func(struct bnx2x *bp, u8 pretend_func_num) DP(NETIF_MSG_HW, "Pretending to func %d\n", pretend_func_num); } -static void bnx2x_pf_disable(struct bnx2x *bp) +void bnx2x_pf_disable(struct bnx2x *bp) { u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); val &= ~IGU_PF_CONF_FUNC_EN; @@ -5733,8 +5980,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp) REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0); bnx2x_enable_blocks_attention(bp); - if (CHIP_PARITY_ENABLED(bp)) - bnx2x_enable_blocks_parity(bp); + bnx2x_enable_blocks_parity(bp); if (!BP_NOMCP(bp)) { if (CHIP_IS_E1x(bp)) @@ -7165,24 +7411,37 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp) /* Close gates #2, #3 and #4: */ static void bnx2x_set_234_gates(struct bnx2x *bp, bool close) { - u32 val, addr; + u32 val; /* Gates #2 and #4a are closed/opened for "not E1" only */ if (!CHIP_IS_E1(bp)) { /* #4 */ - val = REG_RD(bp, PXP_REG_HST_DISCARD_DOORBELLS); - REG_WR(bp, PXP_REG_HST_DISCARD_DOORBELLS, - close ? (val | 0x1) : (val & (~(u32)1))); + REG_WR(bp, PXP_REG_HST_DISCARD_DOORBELLS, !!close); /* #2 */ - val = REG_RD(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES); - REG_WR(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES, - close ? (val | 0x1) : (val & (~(u32)1))); + REG_WR(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES, !!close); } /* #3 */ - addr = BP_PORT(bp) ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; - val = REG_RD(bp, addr); - REG_WR(bp, addr, (!close) ? (val | 0x1) : (val & (~(u32)1))); + if (CHIP_IS_E1x(bp)) { + /* Prevent interrupts from HC on both ports */ + val = REG_RD(bp, HC_REG_CONFIG_1); + REG_WR(bp, HC_REG_CONFIG_1, + (!close) ? (val | HC_CONFIG_1_REG_BLOCK_DISABLE_1) : + (val & ~(u32)HC_CONFIG_1_REG_BLOCK_DISABLE_1)); + + val = REG_RD(bp, HC_REG_CONFIG_0); + REG_WR(bp, HC_REG_CONFIG_0, + (!close) ? (val | HC_CONFIG_0_REG_BLOCK_DISABLE_0) : + (val & ~(u32)HC_CONFIG_0_REG_BLOCK_DISABLE_0)); + } else { + /* Prevent incomming interrupts in IGU */ + val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); + + REG_WR(bp, IGU_REG_BLOCK_CONFIGURATION, + (!close) ? + (val | IGU_BLOCK_CONFIGURATION_REG_BLOCK_ENABLE) : + (val & ~(u32)IGU_BLOCK_CONFIGURATION_REG_BLOCK_ENABLE)); + } DP(NETIF_MSG_HW, "%s gates #2, #3 and #4\n", close ? "closing" : "opening"); @@ -7300,7 +7559,6 @@ static void bnx2x_pxp_prep(struct bnx2x *bp) if (!CHIP_IS_E1(bp)) { REG_WR(bp, PXP2_REG_RD_START_INIT, 0); REG_WR(bp, PXP2_REG_RQ_RBC_DONE, 0); - REG_WR(bp, PXP2_REG_RQ_CFG_DONE, 0); mmiowb(); } } @@ -7315,9 +7573,18 @@ static void bnx2x_pxp_prep(struct bnx2x *bp) * - GRC * - RBCN, RBCP */ -static void bnx2x_process_kill_chip_reset(struct bnx2x *bp) +static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) { u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2; + u32 global_bits2; + + /* + * Bits that have to be set in reset_mask2 if we want to reset 'global' + * (per chip) blocks. + */ + global_bits2 = + MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU | + MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE; not_reset_mask1 = MISC_REGISTERS_RESET_REG_1_RST_HC | @@ -7325,7 +7592,7 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp) MISC_REGISTERS_RESET_REG_1_RST_PXP; not_reset_mask2 = - MISC_REGISTERS_RESET_REG_2_RST_MDIO | + MISC_REGISTERS_RESET_REG_2_RST_PCI_MDIO | MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE | MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE | MISC_REGISTERS_RESET_REG_2_RST_MISC_CORE | @@ -7341,20 +7608,76 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp) else reset_mask2 = 0x1ffff; - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, - reset_mask1 & (~not_reset_mask1)); + if (CHIP_IS_E3(bp)) { + reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT0; + reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT1; + } + + /* Don't reset global blocks unless we need to */ + if (!global) + reset_mask2 &= ~global_bits2; + + /* + * In case of attention in the QM, we need to reset PXP + * (MISC_REGISTERS_RESET_REG_2_RST_PXP_RQ_RD_WR) before QM + * because otherwise QM reset would release 'close the gates' shortly + * before resetting the PXP, then the PSWRQ would send a write + * request to PGLUE. Then when PXP is reset, PGLUE would try to + * read the payload data from PSWWR, but PSWWR would not + * respond. The write queue in PGLUE would stuck, dmae commands + * would not return. Therefore it's important to reset the second + * reset register (containing the + * MISC_REGISTERS_RESET_REG_2_RST_PXP_RQ_RD_WR bit) before the + * first one (containing the MISC_REGISTERS_RESET_REG_1_RST_QM + * bit). + */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, reset_mask2 & (~not_reset_mask2)); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + reset_mask1 & (~not_reset_mask1)); + barrier(); mmiowb(); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, reset_mask2); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1); mmiowb(); } -static int bnx2x_process_kill(struct bnx2x *bp) +/** + * bnx2x_er_poll_igu_vq - poll for pending writes bit. + * It should get cleared in no more than 1s. + * + * @bp: driver handle + * + * It should get cleared in no more than 1s. Returns 0 if + * pending writes bit gets cleared. + */ +static int bnx2x_er_poll_igu_vq(struct bnx2x *bp) +{ + u32 cnt = 1000; + u32 pend_bits = 0; + + do { + pend_bits = REG_RD(bp, IGU_REG_PENDING_BITS_STATUS); + + if (pend_bits == 0) + break; + + usleep_range(1000, 1000); + } while (cnt-- > 0); + + if (cnt <= 0) { + BNX2X_ERR("Still pending IGU requests pend_bits=%x!\n", + pend_bits); + return -EBUSY; + } + + return 0; +} + +static int bnx2x_process_kill(struct bnx2x *bp, bool global) { int cnt = 1000; u32 val = 0; @@ -7373,7 +7696,7 @@ static int bnx2x_process_kill(struct bnx2x *bp) ((port_is_idle_1 & 0x1) == 0x1) && (pgl_exp_rom2 == 0xffffffff)) break; - msleep(1); + usleep_range(1000, 1000); } while (cnt-- > 0); if (cnt <= 0) { @@ -7393,6 +7716,11 @@ static int bnx2x_process_kill(struct bnx2x *bp) /* Close gates #2, #3 and #4 */ bnx2x_set_234_gates(bp, true); + /* Poll for IGU VQs for 57712 and newer chips */ + if (!CHIP_IS_E1x(bp) && bnx2x_er_poll_igu_vq(bp)) + return -EAGAIN; + + /* TBD: Indicate that "process kill" is in progress to MCP */ /* Clear "unprepared" bit */ @@ -7405,25 +7733,28 @@ static int bnx2x_process_kill(struct bnx2x *bp) /* Wait for 1ms to empty GLUE and PCI-E core queues, * PSWHST, GRC and PSWRD Tetris buffer. */ - msleep(1); + usleep_range(1000, 1000); /* Prepare to chip reset: */ /* MCP */ - bnx2x_reset_mcp_prep(bp, &val); + if (global) + bnx2x_reset_mcp_prep(bp, &val); /* PXP */ bnx2x_pxp_prep(bp); barrier(); /* reset the chip */ - bnx2x_process_kill_chip_reset(bp); + bnx2x_process_kill_chip_reset(bp, global); barrier(); /* Recover after reset: */ /* MCP */ - if (bnx2x_reset_mcp_comp(bp, val)) + if (global && bnx2x_reset_mcp_comp(bp, val)) return -EAGAIN; + /* TBD: Add resetting the NO_MCP mode DB here */ + /* PXP */ bnx2x_pxp_prep(bp); @@ -7436,43 +7767,85 @@ static int bnx2x_process_kill(struct bnx2x *bp) return 0; } -static int bnx2x_leader_reset(struct bnx2x *bp) +int bnx2x_leader_reset(struct bnx2x *bp) { int rc = 0; + bool global = bnx2x_reset_is_global(bp); + /* Try to recover after the failure */ - if (bnx2x_process_kill(bp)) { - printk(KERN_ERR "%s: Something bad had happen! Aii!\n", - bp->dev->name); + if (bnx2x_process_kill(bp, global)) { + netdev_err(bp->dev, "Something bad had happen on engine %d! " + "Aii!\n", BP_PATH(bp)); rc = -EAGAIN; goto exit_leader_reset; } - /* Clear "reset is in progress" bit and update the driver state */ + /* + * Clear RESET_IN_PROGRES and RESET_GLOBAL bits and update the driver + * state. + */ bnx2x_set_reset_done(bp); - bp->recovery_state = BNX2X_RECOVERY_DONE; + if (global) + bnx2x_clear_reset_global(bp); exit_leader_reset: bp->is_leader = 0; - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08); - smp_wmb(); + bnx2x_release_leader_lock(bp); + smp_mb(); return rc; } -/* Assumption: runs under rtnl lock. This together with the fact +static inline void bnx2x_recovery_failed(struct bnx2x *bp) +{ + netdev_err(bp->dev, "Recovery has failed. Power cycle is needed.\n"); + + /* Disconnect this device */ + netif_device_detach(bp->dev); + + /* + * Block ifup for all function on this engine until "process kill" + * or power cycle. + */ + bnx2x_set_reset_in_progress(bp); + + /* Shut down the power */ + bnx2x_set_power_state(bp, PCI_D3hot); + + bp->recovery_state = BNX2X_RECOVERY_FAILED; + + smp_mb(); +} + +/* + * Assumption: runs under rtnl lock. This together with the fact * that it's called only from bnx2x_reset_task() ensure that it * will never be called when netif_running(bp->dev) is false. */ static void bnx2x_parity_recover(struct bnx2x *bp) { + bool global = false; + DP(NETIF_MSG_HW, "Handling parity\n"); while (1) { switch (bp->recovery_state) { case BNX2X_RECOVERY_INIT: DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n"); + bnx2x_chk_parity_attn(bp, &global, false); + /* Try to get a LEADER_LOCK HW lock */ - if (bnx2x_trylock_hw_lock(bp, - HW_LOCK_RESOURCE_RESERVED_08)) + if (bnx2x_trylock_leader_lock(bp)) { + bnx2x_set_reset_in_progress(bp); + /* + * Check if there is a global attention and if + * there was a global attention, set the global + * reset bit. + */ + + if (global) + bnx2x_set_reset_global(bp); + bp->is_leader = 1; + } /* Stop the driver */ /* If interface has been removed - break */ @@ -7480,17 +7853,43 @@ static void bnx2x_parity_recover(struct bnx2x *bp) return; bp->recovery_state = BNX2X_RECOVERY_WAIT; - /* Ensure "is_leader" and "recovery_state" - * update values are seen on other CPUs + + /* + * Reset MCP command sequence number and MCP mail box + * sequence as we are going to reset the MCP. + */ + if (global) { + bp->fw_seq = 0; + bp->fw_drv_pulse_wr_seq = 0; + } + + /* Ensure "is_leader", MCP command sequence and + * "recovery_state" update values are seen on other + * CPUs. */ - smp_wmb(); + smp_mb(); break; case BNX2X_RECOVERY_WAIT: DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_WAIT\n"); if (bp->is_leader) { - u32 load_counter = bnx2x_get_load_cnt(bp); - if (load_counter) { + int other_engine = BP_PATH(bp) ? 0 : 1; + u32 other_load_counter = + bnx2x_get_load_cnt(bp, other_engine); + u32 load_counter = + bnx2x_get_load_cnt(bp, BP_PATH(bp)); + global = bnx2x_reset_is_global(bp); + + /* + * In case of a parity in a global block, let + * the first leader that performs a + * leader_reset() reset the global blocks in + * order to clear global attentions. Otherwise + * the the gates will remain closed for that + * engine. + */ + if (load_counter || + (global && other_load_counter)) { /* Wait until all other functions get * down. */ @@ -7503,37 +7902,27 @@ static void bnx2x_parity_recover(struct bnx2x *bp) * normal. In any case it's an exit * point for a leader. */ - if (bnx2x_leader_reset(bp) || - bnx2x_nic_load(bp, LOAD_NORMAL)) { - printk(KERN_ERR"%s: Recovery " - "has failed. Power cycle is " - "needed.\n", bp->dev->name); - /* Disconnect this device */ - netif_device_detach(bp->dev); - /* Block ifup for all function - * of this ASIC until - * "process kill" or power - * cycle. - */ - bnx2x_set_reset_in_progress(bp); - /* Shut down the power */ - bnx2x_set_power_state(bp, - PCI_D3hot); + if (bnx2x_leader_reset(bp)) { + bnx2x_recovery_failed(bp); return; } - return; + /* If we are here, means that the + * leader has succeeded and doesn't + * want to be a leader any more. Try + * to continue as a none-leader. + */ + break; } } else { /* non-leader */ - if (!bnx2x_reset_is_done(bp)) { + if (!bnx2x_reset_is_done(bp, BP_PATH(bp))) { /* Try to get a LEADER_LOCK HW lock as * long as a former leader may have * been unloaded by the user or * released a leadership by another * reason. */ - if (bnx2x_trylock_hw_lock(bp, - HW_LOCK_RESOURCE_RESERVED_08)) { + if (bnx2x_trylock_leader_lock(bp)) { /* I'm a leader now! Restart a * switch case. */ @@ -7545,14 +7934,25 @@ static void bnx2x_parity_recover(struct bnx2x *bp) HZ/10); return; - } else { /* A leader has completed - * the "process kill". It's an exit - * point for a non-leader. - */ - bnx2x_nic_load(bp, LOAD_NORMAL); - bp->recovery_state = - BNX2X_RECOVERY_DONE; - smp_wmb(); + } else { + /* + * If there was a global attention, wait + * for it to be cleared. + */ + if (bnx2x_reset_is_global(bp)) { + schedule_delayed_work( + &bp->reset_task, HZ/10); + return; + } + + if (bnx2x_nic_load(bp, LOAD_NORMAL)) + bnx2x_recovery_failed(bp); + else { + bp->recovery_state = + BNX2X_RECOVERY_DONE; + smp_mb(); + } + return; } } @@ -8871,45 +9271,62 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) static int bnx2x_open(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); + bool global = false; + int other_engine = BP_PATH(bp) ? 0 : 1; + u32 other_load_counter, load_counter; netif_carrier_off(dev); bnx2x_set_power_state(bp, PCI_D0); - if (!bnx2x_reset_is_done(bp)) { + other_load_counter = bnx2x_get_load_cnt(bp, other_engine); + load_counter = bnx2x_get_load_cnt(bp, BP_PATH(bp)); + + /* + * If parity had happen during the unload, then attentions + * and/or RECOVERY_IN_PROGRES may still be set. In this case we + * want the first function loaded on the current engine to + * complete the recovery. + */ + if (!bnx2x_reset_is_done(bp, BP_PATH(bp)) || + bnx2x_chk_parity_attn(bp, &global, true)) do { - /* Reset MCP mail box sequence if there is on going - * recovery + /* + * If there are attentions and they are in a global + * blocks, set the GLOBAL_RESET bit regardless whether + * it will be this function that will complete the + * recovery or not. */ - bp->fw_seq = 0; + if (global) + bnx2x_set_reset_global(bp); - /* If it's the first function to load and reset done - * is still not cleared it may mean that. We don't - * check the attention state here because it may have - * already been cleared by a "common" reset but we - * shell proceed with "process kill" anyway. + /* + * Only the first function on the current engine should + * try to recover in open. In case of attentions in + * global blocks only the first in the chip should try + * to recover. */ - if ((bnx2x_get_load_cnt(bp) == 0) && - bnx2x_trylock_hw_lock(bp, - HW_LOCK_RESOURCE_RESERVED_08) && - (!bnx2x_leader_reset(bp))) { - DP(NETIF_MSG_HW, "Recovered in open\n"); + if ((!load_counter && + (!global || !other_load_counter)) && + bnx2x_trylock_leader_lock(bp) && + !bnx2x_leader_reset(bp)) { + netdev_info(bp->dev, "Recovered in open\n"); break; } + /* recovery has failed... */ bnx2x_set_power_state(bp, PCI_D3hot); + bp->recovery_state = BNX2X_RECOVERY_FAILED; - printk(KERN_ERR"%s: Recovery flow hasn't been properly" + netdev_err(bp->dev, "Recovery flow hasn't been properly" " completed yet. Try again later. If u still see this" " message after a few retries then power cycle is" - " required.\n", bp->dev->name); + " required.\n"); return -EAGAIN; } while (0); - } bp->recovery_state = BNX2X_RECOVERY_DONE; - return bnx2x_nic_load(bp, LOAD_OPEN); } @@ -8920,6 +9337,8 @@ static int bnx2x_close(struct net_device *dev) /* Unload the driver, release IRQs */ bnx2x_nic_unload(bp, UNLOAD_CLOSE); + + /* Power off */ bnx2x_set_power_state(bp, PCI_D3hot); return 0; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 9868cb0270a..f8436e0c131 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -804,10 +804,12 @@ /* [RW 28] TCM Header when both ULP and TCP context is loaded. */ #define DORQ_REG_SHRT_CMHEAD 0x170054 #define HC_CONFIG_0_REG_ATTN_BIT_EN_0 (0x1<<4) +#define HC_CONFIG_0_REG_BLOCK_DISABLE_0 (0x1<<0) #define HC_CONFIG_0_REG_INT_LINE_EN_0 (0x1<<3) #define HC_CONFIG_0_REG_MSI_ATTN_EN_0 (0x1<<7) #define HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 (0x1<<2) -#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1) +#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1) +#define HC_CONFIG_1_REG_BLOCK_DISABLE_1 (0x1<<0) #define HC_REG_AGG_INT_0 0x108050 #define HC_REG_AGG_INT_1 0x108054 #define HC_REG_ATTN_BIT 0x108120 @@ -846,6 +848,7 @@ #define HC_REG_VQID_0 0x108008 #define HC_REG_VQID_1 0x10800c #define IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN (0x1<<1) +#define IGU_BLOCK_CONFIGURATION_REG_BLOCK_ENABLE (0x1<<0) #define IGU_REG_ATTENTION_ACK_BITS 0x130108 /* [R 4] Debug: attn_fsm */ #define IGU_REG_ATTN_FSM 0x130054 @@ -1876,11 +1879,21 @@ /* [R 32] Interrupt register #0 read */ #define NIG_REG_NIG_INT_STS_0 0x103b0 #define NIG_REG_NIG_INT_STS_1 0x103c0 +/* [R 32] Legacy E1 and E1H location for parity error mask register. */ +#define NIG_REG_NIG_PRTY_MASK 0x103dc +/* [RW 32] Parity mask register #0 read/write */ +#define NIG_REG_NIG_PRTY_MASK_0 0x183c8 +#define NIG_REG_NIG_PRTY_MASK_1 0x183d8 /* [R 32] Legacy E1 and E1H location for parity error status register. */ #define NIG_REG_NIG_PRTY_STS 0x103d0 /* [R 32] Parity register #0 read */ #define NIG_REG_NIG_PRTY_STS_0 0x183bc #define NIG_REG_NIG_PRTY_STS_1 0x183cc +/* [R 32] Legacy E1 and E1H location for parity error status clear register. */ +#define NIG_REG_NIG_PRTY_STS_CLR 0x103d4 +/* [RC 32] Parity register #0 read clear */ +#define NIG_REG_NIG_PRTY_STS_CLR_0 0x183c0 +#define NIG_REG_NIG_PRTY_STS_CLR_1 0x183d0 /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic * Ethernet header. */ #define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038 @@ -4322,6 +4335,8 @@ #define UCM_REG_UCM_INT_MASK 0xe01d4 /* [R 11] Interrupt register #0 read */ #define UCM_REG_UCM_INT_STS 0xe01c8 +/* [RW 27] Parity mask register #0 read/write */ +#define UCM_REG_UCM_PRTY_MASK 0xe01e4 /* [R 27] Parity register #0 read */ #define UCM_REG_UCM_PRTY_STS 0xe01d8 /* [RC 27] Parity register #0 read clear */ @@ -4843,8 +4858,13 @@ #define XCM_REG_XCM_INT_MASK 0x202b4 /* [R 14] Interrupt register #0 read */ #define XCM_REG_XCM_INT_STS 0x202a8 +/* [RW 30] Parity mask register #0 read/write */ +#define XCM_REG_XCM_PRTY_MASK 0x202c4 /* [R 30] Parity register #0 read */ #define XCM_REG_XCM_PRTY_STS 0x202b8 +/* [RC 30] Parity register #0 read clear */ +#define XCM_REG_XCM_PRTY_STS_CLR 0x202bc + /* [RW 4] The size of AG context region 0 in REG-pairs. Designates the MS REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). Is used to determine the number of the AG context REG-pairs written back; @@ -5284,9 +5304,12 @@ #define MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE (0x1<<15) #define MISC_REGISTERS_RESET_REG_2_RST_GRC (0x1<<4) #define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B (0x1<<6) +#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE (0x1<<8) +#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU (0x1<<7) #define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE (0x1<<5) #define MISC_REGISTERS_RESET_REG_2_RST_MDIO (0x1<<13) #define MISC_REGISTERS_RESET_REG_2_RST_MISC_CORE (0x1<<11) +#define MISC_REGISTERS_RESET_REG_2_RST_PCI_MDIO (0x1<<13) #define MISC_REGISTERS_RESET_REG_2_RST_RBCN (0x1<<9) #define MISC_REGISTERS_RESET_REG_2_SET 0x594 #define MISC_REGISTERS_RESET_REG_3_CLEAR 0x5a8 @@ -5315,71 +5338,82 @@ #define HW_LOCK_MAX_RESOURCE_VALUE 31 #define HW_LOCK_RESOURCE_GPIO 1 #define HW_LOCK_RESOURCE_MDIO 0 -#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3 -#define HW_LOCK_RESOURCE_RESERVED_08 8 +#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3 +#define HW_LOCK_RESOURCE_RECOVERY_LEADER_0 8 +#define HW_LOCK_RESOURCE_RECOVERY_LEADER_1 9 #define HW_LOCK_RESOURCE_SPIO 2 #define HW_LOCK_RESOURCE_UNDI 5 -#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) -#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) -#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) -#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31) -#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9) -#define AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR (1<<8) -#define AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT (1<<7) -#define AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR (1<<6) -#define AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT (1<<29) -#define AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR (1<<28) -#define AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT (1<<1) -#define AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR (1<<0) -#define AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR (1<<18) -#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11) -#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13) -#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12) -#define AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 (1<<2) -#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (1<<5) -#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (1<<9) -#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12) -#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY (1<<28) -#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY (1<<31) -#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY (1<<29) -#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY (1<<30) -#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (1<<15) -#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (1<<14) -#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (1<<20) -#define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (1<<0) -#define AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT (1<<31) -#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2) -#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3) -#define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (1<<3) -#define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (1<<2) -#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (1<<5) -#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR (1<<4) -#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (1<<3) -#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (1<<2) -#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (1<<22) -#define AEU_INPUTS_ATTN_BITS_SPIO5 (1<<15) -#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (1<<27) -#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (1<<5) -#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (1<<25) -#define AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR (1<<24) -#define AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT (1<<29) -#define AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR (1<<28) -#define AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT (1<<23) -#define AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT (1<<27) -#define AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR (1<<26) -#define AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT (1<<21) -#define AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR (1<<20) -#define AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT (1<<25) -#define AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR (1<<24) -#define AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR (1<<16) -#define AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT (1<<9) -#define AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT (1<<7) -#define AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR (1<<6) -#define AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT (1<<11) -#define AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR (1<<10) +#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) +#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) +#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (0x1<<18) +#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (0x1<<31) +#define AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR (0x1<<30) +#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (0x1<<9) +#define AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR (0x1<<8) +#define AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT (0x1<<7) +#define AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR (0x1<<6) +#define AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT (0x1<<29) +#define AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR (0x1<<28) +#define AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT (0x1<<1) +#define AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR (0x1<<0) +#define AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR (0x1<<18) +#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (0x1<<11) +#define AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR (0x1<<10) +#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (0x1<<13) +#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (0x1<<12) +#define AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 (0x1<<2) +#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (0x1<<12) +#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY (0x1<<28) +#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY (0x1<<31) +#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY (0x1<<29) +#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY (0x1<<30) +#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (0x1<<15) +#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (0x1<<14) +#define AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR (0x1<<14) +#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (0x1<<20) +#define AEU_INPUTS_ATTN_BITS_PBCLIENT_HW_INTERRUPT (0x1<<31) +#define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (0x1<<30) +#define AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR (0x1<<0) +#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2) +#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3) +#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (0x1<<5) +#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR (0x1<<4) +#define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (0x1<<3) +#define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (0x1<<2) +#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (0x1<<3) +#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (0x1<<2) +#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (0x1<<22) +#define AEU_INPUTS_ATTN_BITS_SPIO5 (0x1<<15) +#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (0x1<<27) +#define AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR (0x1<<26) +#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (0x1<<5) +#define AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR (0x1<<4) +#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (0x1<<25) +#define AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR (0x1<<24) +#define AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT (0x1<<29) +#define AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR (0x1<<28) +#define AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT (0x1<<23) +#define AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR (0x1<<22) +#define AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT (0x1<<27) +#define AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR (0x1<<26) +#define AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT (0x1<<21) +#define AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR (0x1<<20) +#define AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT (0x1<<25) +#define AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR (0x1<<24) +#define AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR (0x1<<16) +#define AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT (0x1<<9) +#define AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR (0x1<<8) +#define AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT (0x1<<7) +#define AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR (0x1<<6) +#define AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT (0x1<<11) +#define AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR (0x1<<10) + +#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (0x1<<5) +#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (0x1<<9) + #define RESERVED_GENERAL_ATTENTION_BIT_0 0 -#define EVEREST_GEN_ATTN_IN_USE_MASK 0x3ffe0 +#define EVEREST_GEN_ATTN_IN_USE_MASK 0x7ffe0 #define EVEREST_LATCHED_ATTN_IN_USE_MASK 0xffe00000 #define RESERVED_GENERAL_ATTENTION_BIT_6 6 -- cgit v1.2.3-70-g09d2 From ef01854e24035a0b17ebeb98b05cfee2c8b36e02 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:33:57 +0000 Subject: bnx2x: update DCB data during PMF migration Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_dcb.h | 2 +- drivers/net/bnx2x/bnx2x_main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h index 7887834cd65..b3a655ff2ba 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.h +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -184,7 +184,7 @@ enum { }; void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state); - +void bnx2x_dcbx_pmf_update(struct bnx2x *bp); /* DCB netlink */ #ifdef BCM_DCBNL extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 7ffb6e651e1..57fac3db9bd 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2477,6 +2477,8 @@ static void bnx2x_pmf_update(struct bnx2x *bp) bp->port.pmf = 1; DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); + bnx2x_dcbx_pmf_update(bp); + /* enable nig attention */ val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); if (bp->common.int_block == INT_BLOCK_HC) { -- cgit v1.2.3-70-g09d2 From 754a2f5220ac7d597454df3104cfce9c83d68df0 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:34:02 +0000 Subject: bnx2x: Cosmetic changes. Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 10 +++------- drivers/net/bnx2x/bnx2x_ethtool.c | 12 ++++++------ drivers/net/bnx2x/bnx2x_main.c | 37 ++++++++++++++++++------------------- 3 files changed, 27 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index c108e4cf633..838a4edbe94 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -26,10 +26,6 @@ #define DRV_MODULE_RELDATE "2011/03/20" #define BNX2X_BC_VER 0x040200 -#define BNX2X_MULTI_QUEUE - -#define BNX2X_NEW_NAPI - #if defined(CONFIG_DCB) #define BCM_DCBNL #endif @@ -745,9 +741,9 @@ struct bnx2x_common { (CHIP_REV(bp) == CHIP_REV_Ax)) int flash_size; -#define NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */ -#define NVRAM_TIMEOUT_COUNT 30000 -#define NVRAM_PAGE_SIZE 256 +#define BNX2X_NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */ +#define BNX2X_NVRAM_TIMEOUT_COUNT 30000 +#define BNX2X_NVRAM_PAGE_SIZE 256 u32 shmem_base; u32 shmem2_base; diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 965fb071fbe..1a3ed418946 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -762,7 +762,7 @@ static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) u32 val = 0; /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; + count = BNX2X_NVRAM_TIMEOUT_COUNT; if (CHIP_REV_IS_SLOW(bp)) count *= 100; @@ -793,7 +793,7 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp) u32 val = 0; /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; + count = BNX2X_NVRAM_TIMEOUT_COUNT; if (CHIP_REV_IS_SLOW(bp)) count *= 100; @@ -861,7 +861,7 @@ static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val, REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; + count = BNX2X_NVRAM_TIMEOUT_COUNT; if (CHIP_REV_IS_SLOW(bp)) count *= 100; @@ -984,7 +984,7 @@ static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; + count = BNX2X_NVRAM_TIMEOUT_COUNT; if (CHIP_REV_IS_SLOW(bp)) count *= 100; @@ -1088,9 +1088,9 @@ static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf, while ((written_so_far < buf_size) && (rc == 0)) { if (written_so_far == (buf_size - sizeof(u32))) cmd_flags |= MCPR_NVM_COMMAND_LAST; - else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0) + else if (((offset + 4) % BNX2X_NVRAM_PAGE_SIZE) == 0) cmd_flags |= MCPR_NVM_COMMAND_LAST; - else if ((offset % NVRAM_PAGE_SIZE) == 0) + else if ((offset % BNX2X_NVRAM_PAGE_SIZE) == 0) cmd_flags |= MCPR_NVM_COMMAND_FIRST; memcpy(&val, data_buf, 4); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 57fac3db9bd..6237e4aba82 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1557,7 +1557,7 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) offset++; #endif for_each_eth_queue(bp, i) - synchronize_irq(bp->msix_table[i + offset].vector); + synchronize_irq(bp->msix_table[offset++].vector); } else synchronize_irq(bp->pdev->irq); @@ -2514,7 +2514,8 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) SHMEM_WR(bp, func_mb[mb_idx].drv_mb_param, param); SHMEM_WR(bp, func_mb[mb_idx].drv_mb_header, (command | seq)); - DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB param 0x%08x\n", + (command | seq), param); do { /* let the FW do it's magic ... */ @@ -8193,7 +8194,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) } val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4); - bp->common.flash_size = (NVRAM_1MB_SIZE << + bp->common.flash_size = (BNX2X_NVRAM_1MB_SIZE << (val & MCPR_NVM_CFG4_FLASH_SIZE)); BNX2X_DEV_INFO("flash_size 0x%x (%d)\n", bp->common.flash_size, bp->common.flash_size); @@ -8466,7 +8467,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { - BNX2X_ERROR("NVRAM config error. " + BNX2X_ERR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, @@ -8485,7 +8486,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) (ADVERTISED_10baseT_Half | ADVERTISED_TP); } else { - BNX2X_ERROR("NVRAM config error. " + BNX2X_ERR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, @@ -8503,7 +8504,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { - BNX2X_ERROR("NVRAM config error. " + BNX2X_ERR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, @@ -8523,7 +8524,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) (ADVERTISED_100baseT_Half | ADVERTISED_TP); } else { - BNX2X_ERROR("NVRAM config error. " + BNX2X_ERR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, @@ -8541,7 +8542,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) (ADVERTISED_1000baseT_Full | ADVERTISED_TP); } else { - BNX2X_ERROR("NVRAM config error. " + BNX2X_ERR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, @@ -8559,7 +8560,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) (ADVERTISED_2500baseX_Full | ADVERTISED_TP); } else { - BNX2X_ERROR("NVRAM config error. " + BNX2X_ERR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, @@ -8577,7 +8578,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); } else { - BNX2X_ERROR("NVRAM config error. " + BNX2X_ERR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, @@ -8587,9 +8588,9 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) break; default: - BNX2X_ERROR("NVRAM config error. " - "BAD link speed link_config 0x%x\n", - link_config); + BNX2X_ERR("NVRAM config error. " + "BAD link speed link_config 0x%x\n", + link_config); bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG; bp->port.advertising[idx] = @@ -8962,14 +8963,12 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); } else - DP(NETIF_MSG_PROBE, "illegal OV for " - "SD\n"); + BNX2X_DEV_INFO("illegal OV for SD\n"); break; default: /* Unknown configuration: reset mf_config */ bp->mf_config[vn] = 0; - DP(NETIF_MSG_PROBE, "Unknown MF mode 0x%x\n", - val); + BNX2X_DEV_INFO("unkown MF mode 0x%x\n", val); } } @@ -10406,8 +10405,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev) struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. " - "Try again later\n"); + netdev_err(bp->dev, "Handling parity error recovery. " + "Try again later\n"); return; } -- cgit v1.2.3-70-g09d2 From 9380bb9e88831bd3d85636b3e4fec30e330d5266 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:34:07 +0000 Subject: bnx2x: Add new MAC support for 578xx Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 981 ++++++++++++++++++++++++++++++++++------- drivers/net/bnx2x/bnx2x_link.h | 16 +- drivers/net/bnx2x/bnx2x_reg.h | 181 +++++++- 3 files changed, 1003 insertions(+), 175 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 347f3239ad1..873463966a0 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -105,12 +105,6 @@ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG #define GP_STATUS_10G_CX4 \ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4 -#define GP_STATUS_12G_HIG \ - MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG -#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G -#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G -#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G -#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX #define GP_STATUS_10G_KX4 \ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 @@ -128,16 +122,6 @@ #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD -#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD -#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD -#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD -#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD -#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD -#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD -#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD -#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD -#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD -#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD #define PHY_XGXS_FLAG 0x1 #define PHY_SGMII_FLAG 0x2 @@ -167,8 +151,103 @@ #define EDC_MODE_PASSIVE_DAC 0x0055 +/* BRB thresholds for E2*/ +#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE 170 +#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 + +#define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE 250 +#define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 + +#define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE 10 +#define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 90 + +#define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE 50 +#define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE 250 + +/* BRB thresholds for E3A0 */ +#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE 290 +#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 + +#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE 410 +#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 + +#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE 10 +#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 170 + +#define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE 50 +#define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE 410 + + +/* BRB thresholds for E3B0 2 port mode*/ +#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 1025 +#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 + +#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE 1025 +#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 + +#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE 10 +#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 1025 + +#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE 50 +#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE 1025 + +/* only for E3B0*/ +#define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR 1025 +#define PFC_E3B0_2P_BRB_FULL_LB_XON_THR 1025 + +/* Lossy +Lossless GUARANTIED == GUART */ +#define PFC_E3B0_2P_MIX_PAUSE_LB_GUART 284 +/* Lossless +Lossless*/ +#define PFC_E3B0_2P_PAUSE_LB_GUART 236 +/* Lossy +Lossy*/ +#define PFC_E3B0_2P_NON_PAUSE_LB_GUART 342 + +/* Lossy +Lossless*/ +#define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART 284 +/* Lossless +Lossless*/ +#define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART 236 +/* Lossy +Lossy*/ +#define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART 336 +#define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST 80 + +#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART 0 +#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST 0 + +/* BRB thresholds for E3B0 4 port mode */ +#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 304 +#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0 + +#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE 384 +#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0 + +#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE 10 +#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 304 + +#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE 50 +#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE 384 + + +/* only for E3B0*/ +#define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR 304 +#define PFC_E3B0_4P_BRB_FULL_LB_XON_THR 384 +#define PFC_E3B0_4P_LB_GUART 120 + +#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART 120 +#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST 80 + +#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART 80 +#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST 120 + +#define DCBX_INVALID_COS (0xFF) + #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000) #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000) +#define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS (1360) +#define ETS_E3B0_NIG_MIN_W_VAL_20GBPS (2720) +#define ETS_E3B0_PBF_MIN_W_VAL (10000) + +#define MAX_PACKET_SIZE (9700) + /**********************************************************/ /* INTERFACE */ /**********************************************************/ @@ -390,6 +469,53 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) /* PFC section */ /******************************************************************/ +static void bnx2x_update_pfc_xmac(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + struct bnx2x *bp = params->bp; + u32 xmac_base; + u32 pause_val, pfc0_val, pfc1_val; + + /* XMAC base adrr */ + xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; + + /* Initialize pause and pfc registers */ + pause_val = 0x18000; + pfc0_val = 0xFFFF8000; + pfc1_val = 0x2; + + /* No PFC support */ + if (!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED)) { + + /* + * RX flow control - Process pause frame in receive direction + */ + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN; + + /* + * TX flow control - Send pause packet when buffer is full + */ + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN; + } else {/* PFC support */ + pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN | + XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN | + XMAC_PFC_CTRL_HI_REG_RX_PFC_EN | + XMAC_PFC_CTRL_HI_REG_TX_PFC_EN; + } + + /* Write pause and PFC registers */ + REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val); + REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val); + REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val); + + udelay(30); +} + + static void bnx2x_bmac2_get_pfc_stat(struct link_params *params, u32 pfc_frames_sent[2], u32 pfc_frames_received[2]) @@ -533,6 +659,233 @@ static void bnx2x_emac_init(struct link_params *params, EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val); } +static void bnx2x_set_xumac_nig(struct link_params *params, + u16 tx_pause_en, + u8 enable) +{ + struct bnx2x *bp = params->bp; + + REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN, + enable); + REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN, + enable); + REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN : + NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en); +} + +static void bnx2x_umac_enable(struct link_params *params, + struct link_vars *vars, u8 lb) +{ + u32 val; + u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; + struct bnx2x *bp = params->bp; + /* Reset UMAC */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)); + usleep_range(1000, 1000); + + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)); + + DP(NETIF_MSG_LINK, "enabling UMAC\n"); + + /** + * This register determines on which events the MAC will assert + * error on the i/f to the NIG along w/ EOP. + */ + + /** + * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK + + * params->port*0x14, 0xfffff. + */ + /* This register opens the gate for the UMAC despite its name */ + REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1); + + val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN | + UMAC_COMMAND_CONFIG_REG_PAD_EN | + UMAC_COMMAND_CONFIG_REG_SW_RESET | + UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK; + switch (vars->line_speed) { + case SPEED_10: + val |= (0<<2); + break; + case SPEED_100: + val |= (1<<2); + break; + case SPEED_1000: + val |= (2<<2); + break; + case SPEED_2500: + val |= (3<<2); + break; + default: + DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n", + vars->line_speed); + break; + } + REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); + udelay(50); + + /* Enable RX and TX */ + val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN; + val |= UMAC_COMMAND_CONFIG_REG_TX_ENA | + UMAC_COMMAND_CONFIG_REG_RX_ENA; + REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); + udelay(50); + + /* Remove SW Reset */ + val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET; + + /* Check loopback mode */ + if (lb) + val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA; + REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); + + /* + * Maximum Frame Length (RW). Defines a 14-Bit maximum frame + * length used by the MAC receive logic to check frames. + */ + REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710); + bnx2x_set_xumac_nig(params, + ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1); + vars->mac_type = MAC_TYPE_UMAC; + +} + +static u8 bnx2x_is_4_port_mode(struct bnx2x *bp) +{ + u32 port4mode_ovwr_val; + /* Check 4-port override enabled */ + port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR); + if (port4mode_ovwr_val & (1<<0)) { + /* Return 4-port mode override value */ + return ((port4mode_ovwr_val & (1<<1)) == (1<<1)); + } + /* Return 4-port mode from input pin */ + return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN); +} + +/* Define the XMAC mode */ +static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed) +{ + u32 is_port4mode = bnx2x_is_4_port_mode(bp); + + /** + * In 4-port mode, need to set the mode only once, so if XMAC is + * already out of reset, it means the mode has already been set, + * and it must not* reset the XMAC again, since it controls both + * ports of the path + **/ + + if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) & + MISC_REGISTERS_RESET_REG_2_XMAC)) { + DP(NETIF_MSG_LINK, "XMAC already out of reset" + " in 4-port mode\n"); + return; + } + + /* Hard reset */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + MISC_REGISTERS_RESET_REG_2_XMAC); + usleep_range(1000, 1000); + + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + MISC_REGISTERS_RESET_REG_2_XMAC); + if (is_port4mode) { + DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n"); + + /* Set the number of ports on the system side to up to 2 */ + REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1); + + /* Set the number of ports on the Warp Core to 10G */ + REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3); + } else { + /* Set the number of ports on the system side to 1 */ + REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0); + if (max_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, "Init XMAC to 10G x 1" + " port per path\n"); + /* Set the number of ports on the Warp Core to 10G */ + REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3); + } else { + DP(NETIF_MSG_LINK, "Init XMAC to 20G x 2 ports" + " per path\n"); + /* Set the number of ports on the Warp Core to 20G */ + REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1); + } + } + /* Soft reset */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + MISC_REGISTERS_RESET_REG_2_XMAC_SOFT); + usleep_range(1000, 1000); + + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + MISC_REGISTERS_RESET_REG_2_XMAC_SOFT); + +} + +static void bnx2x_xmac_disable(struct link_params *params) +{ + u8 port = params->port; + struct bnx2x *bp = params->bp; + u32 xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; + + if (REG_RD(bp, MISC_REG_RESET_REG_2) & + MISC_REGISTERS_RESET_REG_2_XMAC) { + DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port); + REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0); + usleep_range(1000, 1000); + bnx2x_set_xumac_nig(params, 0, 0); + REG_WR(bp, xmac_base + XMAC_REG_CTRL, + XMAC_CTRL_REG_SOFT_RESET); + } +} + +static int bnx2x_xmac_enable(struct link_params *params, + struct link_vars *vars, u8 lb) +{ + u32 val, xmac_base; + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "enabling XMAC\n"); + + xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; + + bnx2x_xmac_init(bp, vars->line_speed); + + /* + * This register determines on which events the MAC will assert + * error on the i/f to the NIG along w/ EOP. + */ + + /* + * This register tells the NIG whether to send traffic to UMAC + * or XMAC + */ + REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0); + + /* Set Max packet size */ + REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710); + + /* CRC append for Tx packets */ + REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800); + + /* update PFC */ + bnx2x_update_pfc_xmac(params, vars, 0); + + /* Enable TX and RX */ + val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN; + + /* Check loopback mode */ + if (lb) + val |= XMAC_CTRL_REG_CORE_LOCAL_LPBK; + REG_WR(bp, xmac_base + XMAC_REG_CTRL, val); + bnx2x_set_xumac_nig(params, + ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1); + + vars->mac_type = MAC_TYPE_XMAC; + + return 0; +} static int bnx2x_emac_enable(struct link_params *params, struct link_vars *vars, u8 lb) { @@ -785,95 +1138,341 @@ static void bnx2x_update_pfc_bmac2(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2); } -static void bnx2x_update_pfc_brb(struct link_params *params, - struct link_vars *vars, - struct bnx2x_nig_brb_pfc_port_params *pfc_params) + +/* PFC BRB internal port configuration params */ +struct bnx2x_pfc_brb_threshold_val { + u32 pause_xoff; + u32 pause_xon; + u32 full_xoff; + u32 full_xon; +}; + +struct bnx2x_pfc_brb_e3b0_val { + u32 full_lb_xoff_th; + u32 full_lb_xon_threshold; + u32 lb_guarantied; + u32 mac_0_class_t_guarantied; + u32 mac_0_class_t_guarantied_hyst; + u32 mac_1_class_t_guarantied; + u32 mac_1_class_t_guarantied_hyst; +}; + +struct bnx2x_pfc_brb_th_val { + struct bnx2x_pfc_brb_threshold_val pauseable_th; + struct bnx2x_pfc_brb_threshold_val non_pauseable_th; +}; +static int bnx2x_pfc_brb_get_config_params( + struct link_params *params, + struct bnx2x_pfc_brb_th_val *config_val) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n"); + if (CHIP_IS_E2(bp)) { + config_val->pauseable_th.pause_xoff = + PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE; + config_val->pauseable_th.pause_xon = + PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE; + config_val->pauseable_th.full_xoff = + PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE; + config_val->pauseable_th.full_xon = + PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE; + /* non pause able*/ + config_val->non_pauseable_th.pause_xoff = + PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.pause_xon = + PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xoff = + PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xon = + PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE; + } else if (CHIP_IS_E3A0(bp)) { + config_val->pauseable_th.pause_xoff = + PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE; + config_val->pauseable_th.pause_xon = + PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE; + config_val->pauseable_th.full_xoff = + PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE; + config_val->pauseable_th.full_xon = + PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE; + /* non pause able*/ + config_val->non_pauseable_th.pause_xoff = + PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.pause_xon = + PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xoff = + PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xon = + PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE; + } else if (CHIP_IS_E3B0(bp)) { + if (params->phy[INT_PHY].flags & + FLAGS_4_PORT_MODE) { + config_val->pauseable_th.pause_xoff = + PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE; + config_val->pauseable_th.pause_xon = + PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE; + config_val->pauseable_th.full_xoff = + PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE; + config_val->pauseable_th.full_xon = + PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE; + /* non pause able*/ + config_val->non_pauseable_th.pause_xoff = + PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.pause_xon = + PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xoff = + PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xon = + PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE; + } else { + config_val->pauseable_th.pause_xoff = + PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE; + config_val->pauseable_th.pause_xon = + PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE; + config_val->pauseable_th.full_xoff = + PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE; + config_val->pauseable_th.full_xon = + PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE; + /* non pause able*/ + config_val->non_pauseable_th.pause_xoff = + PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.pause_xon = + PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xoff = + PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE; + config_val->non_pauseable_th.full_xon = + PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE; + } + } else + return -EINVAL; + + return 0; +} + + +static void bnx2x_pfc_brb_get_e3b0_config_params(struct link_params *params, + struct bnx2x_pfc_brb_e3b0_val + *e3b0_val, + u32 cos0_pauseable, + u32 cos1_pauseable) +{ + if (params->phy[INT_PHY].flags & FLAGS_4_PORT_MODE) { + e3b0_val->full_lb_xoff_th = + PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR; + e3b0_val->full_lb_xon_threshold = + PFC_E3B0_4P_BRB_FULL_LB_XON_THR; + e3b0_val->lb_guarantied = + PFC_E3B0_4P_LB_GUART; + e3b0_val->mac_0_class_t_guarantied = + PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART; + e3b0_val->mac_0_class_t_guarantied_hyst = + PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST; + e3b0_val->mac_1_class_t_guarantied = + PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART; + e3b0_val->mac_1_class_t_guarantied_hyst = + PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST; + } else { + e3b0_val->full_lb_xoff_th = + PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR; + e3b0_val->full_lb_xon_threshold = + PFC_E3B0_2P_BRB_FULL_LB_XON_THR; + e3b0_val->mac_0_class_t_guarantied_hyst = + PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST; + e3b0_val->mac_1_class_t_guarantied = + PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART; + e3b0_val->mac_1_class_t_guarantied_hyst = + PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST; + + if (cos0_pauseable != cos1_pauseable) { + /* nonpauseable= Lossy + pauseable = Lossless*/ + e3b0_val->lb_guarantied = + PFC_E3B0_2P_MIX_PAUSE_LB_GUART; + e3b0_val->mac_0_class_t_guarantied = + PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART; + } else if (cos0_pauseable) { + /* Lossless +Lossless*/ + e3b0_val->lb_guarantied = + PFC_E3B0_2P_PAUSE_LB_GUART; + e3b0_val->mac_0_class_t_guarantied = + PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART; + } else { + /* Lossy +Lossy*/ + e3b0_val->lb_guarantied = + PFC_E3B0_2P_NON_PAUSE_LB_GUART; + e3b0_val->mac_0_class_t_guarantied = + PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART; + } + } +} +static int bnx2x_update_pfc_brb(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params + *pfc_params) { struct bnx2x *bp = params->bp; + struct bnx2x_pfc_brb_th_val config_val = { {0} }; + struct bnx2x_pfc_brb_threshold_val *reg_th_config = + &config_val.pauseable_th; + struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0}; int set_pfc = params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED; + int bnx2x_status = 0; + u8 port = params->port; /* default - pause configuration */ - u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE; - u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE; - u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE; - u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE; + reg_th_config = &config_val.pauseable_th; + bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val); + if (0 != bnx2x_status) + return bnx2x_status; if (set_pfc && pfc_params) /* First COS */ - if (!pfc_params->cos0_pauseable) { - pause_xoff_th = - PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE; - pause_xon_th = - PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE; - full_xoff_th = - PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE; - full_xon_th = - PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; - } + if (!pfc_params->cos0_pauseable) + reg_th_config = &config_val.non_pauseable_th; /* * The number of free blocks below which the pause signal to class 0 * of MAC #n is asserted. n=0,1 */ - REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th); + REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 : + BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , + reg_th_config->pause_xoff); /* * The number of free blocks above which the pause signal to class 0 * of MAC #n is de-asserted. n=0,1 */ - REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th); + REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 : + BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon); /* * The number of free blocks below which the full signal to class 0 * of MAC #n is asserted. n=0,1 */ - REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th); + REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 : + BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff); /* * The number of free blocks above which the full signal to class 0 * of MAC #n is de-asserted. n=0,1 */ - REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th); + REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 : + BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon); if (set_pfc && pfc_params) { /* Second COS */ - if (pfc_params->cos1_pauseable) { - pause_xoff_th = - PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE; - pause_xon_th = - PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE; - full_xoff_th = - PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE; - full_xon_th = - PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE; - } else { - pause_xoff_th = - PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE; - pause_xon_th = - PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE; - full_xoff_th = - PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE; - full_xon_th = - PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; - } + if (pfc_params->cos1_pauseable) + reg_th_config = &config_val.pauseable_th; + else + reg_th_config = &config_val.non_pauseable_th; /* * The number of free blocks below which the pause signal to * class 1 of MAC #n is asserted. n=0,1 - */ - REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th); + **/ + REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 : + BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, + reg_th_config->pause_xoff); /* * The number of free blocks above which the pause signal to * class 1 of MAC #n is de-asserted. n=0,1 */ - REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th); + REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 : + BRB1_REG_PAUSE_1_XON_THRESHOLD_0, + reg_th_config->pause_xon); /* * The number of free blocks below which the full signal to * class 1 of MAC #n is asserted. n=0,1 */ - REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th); + REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 : + BRB1_REG_FULL_1_XOFF_THRESHOLD_0, + reg_th_config->full_xoff); /* * The number of free blocks above which the full signal to * class 1 of MAC #n is de-asserted. n=0,1 */ - REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th); - } + REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 : + BRB1_REG_FULL_1_XON_THRESHOLD_0, + reg_th_config->full_xon); + + + if (CHIP_IS_E3B0(bp)) { + /*Should be done by init tool */ + /* + * BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD + * reset value + * 944 + */ + + /** + * The hysteresis on the guarantied buffer space for the Lb port + * before signaling XON. + **/ + REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST, 80); + + bnx2x_pfc_brb_get_e3b0_config_params( + params, + &e3b0_val, + pfc_params->cos0_pauseable, + pfc_params->cos1_pauseable); + /** + * The number of free blocks below which the full signal to the + * LB port is asserted. + */ + REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD, + e3b0_val.full_lb_xoff_th); + /** + * The number of free blocks above which the full signal to the + * LB port is de-asserted. + */ + REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD, + e3b0_val.full_lb_xon_threshold); + /** + * The number of blocks guarantied for the MAC #n port. n=0,1 + */ + + /*The number of blocks guarantied for the LB port.*/ + REG_WR(bp, BRB1_REG_LB_GUARANTIED, + e3b0_val.lb_guarantied); + + /** + * The number of blocks guarantied for the MAC #n port. + */ + REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0, + 2 * e3b0_val.mac_0_class_t_guarantied); + REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1, + 2 * e3b0_val.mac_1_class_t_guarantied); + /** + * The number of blocks guarantied for class #t in MAC0. t=0,1 + */ + REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED, + e3b0_val.mac_0_class_t_guarantied); + REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED, + e3b0_val.mac_0_class_t_guarantied); + /** + * The hysteresis on the guarantied buffer space for class in + * MAC0. t=0,1 + */ + REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST, + e3b0_val.mac_0_class_t_guarantied_hyst); + REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST, + e3b0_val.mac_0_class_t_guarantied_hyst); + + /** + * The number of blocks guarantied for class #t in MAC1.t=0,1 + */ + REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED, + e3b0_val.mac_1_class_t_guarantied); + REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED, + e3b0_val.mac_1_class_t_guarantied); + /** + * The hysteresis on the guarantied buffer space for class #t + * in MAC1. t=0,1 + */ + REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST, + e3b0_val.mac_1_class_t_guarantied_hyst); + REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST, + e3b0_val.mac_1_class_t_guarantied_hyst); + + } + + } + + return bnx2x_status; } /****************************************************************************** @@ -931,9 +1530,9 @@ static void bnx2x_update_pfc_nig(struct link_params *params, u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0; u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0; u32 pkt_priority_to_cos = 0; - u32 val; struct bnx2x *bp = params->bp; - int port = params->port; + u8 port = params->port; + int set_pfc = params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED; DP(NETIF_MSG_LINK, "updating pfc nig parameters\n"); @@ -954,6 +1553,9 @@ static void bnx2x_update_pfc_nig(struct link_params *params, pause_enable = 0; llfc_out_en = 0; llfc_enable = 0; + if (CHIP_IS_E3(bp)) + ppp_enable = 0; + else ppp_enable = 1; xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN : NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN); @@ -972,6 +1574,9 @@ static void bnx2x_update_pfc_nig(struct link_params *params, xcm0_out_en = 1; } + if (CHIP_IS_E3(bp)) + REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN : + NIG_REG_BRB0_PAUSE_IN_EN, pause_enable); REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 : NIG_REG_LLFC_OUT_EN_0, llfc_out_en); REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 : @@ -993,20 +1598,6 @@ static void bnx2x_update_pfc_nig(struct link_params *params, /* HW PFC TX enable */ REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable); - /* 0x2 = BMAC, 0x1= EMAC */ - switch (vars->mac_type) { - case MAC_TYPE_EMAC: - val = 1; - break; - case MAC_TYPE_BMAC: - val = 0; - break; - default: - val = 0; - break; - } - REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val); - if (nig_params) { u8 i = 0; pkt_priority_to_cos = nig_params->pkt_priority_to_cos; @@ -1028,8 +1619,7 @@ static void bnx2x_update_pfc_nig(struct link_params *params, pkt_priority_to_cos); } - -void bnx2x_update_pfc(struct link_params *params, +int bnx2x_update_pfc(struct link_params *params, struct link_vars *vars, struct bnx2x_nig_brb_pfc_port_params *pfc_params) { @@ -1040,38 +1630,48 @@ void bnx2x_update_pfc(struct link_params *params, */ u32 val; struct bnx2x *bp = params->bp; - + int bnx2x_status = 0; + u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC); /* update NIG params */ bnx2x_update_pfc_nig(params, vars, pfc_params); /* update BRB params */ - bnx2x_update_pfc_brb(params, vars, pfc_params); + bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params); + if (0 != bnx2x_status) + return bnx2x_status; if (!vars->link_up) - return; - - val = REG_RD(bp, MISC_REG_RESET_REG_2); - if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) - == 0) { - DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); - bnx2x_emac_enable(params, vars, 0); - return; - } + return bnx2x_status; DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); - if (CHIP_IS_E2(bp)) - bnx2x_update_pfc_bmac2(params, vars, 0); - else - bnx2x_update_pfc_bmac1(params, vars); + if (CHIP_IS_E3(bp)) + bnx2x_update_pfc_xmac(params, vars, 0); + else { + val = REG_RD(bp, MISC_REG_RESET_REG_2); + if ((val & + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) + == 0) { + DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); + bnx2x_emac_enable(params, vars, 0); + return bnx2x_status; + } - val = 0; - if ((params->feature_config_flags & - FEATURE_CONFIG_PFC_ENABLED) || - (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) - val = 1; - REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val); + if (CHIP_IS_E2(bp)) + bnx2x_update_pfc_bmac2(params, vars, bmac_loopback); + else + bnx2x_update_pfc_bmac1(params, vars); + + val = 0; + if ((params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) || + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) + val = 1; + REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val); + } + return bnx2x_status; } + static int bnx2x_bmac1_enable(struct link_params *params, struct link_vars *vars, u8 is_lb) @@ -1819,7 +2419,7 @@ void bnx2x_link_status_update(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 link_10g; + u8 link_10g_plus; u8 port = params->port; u32 sync_offset, media_types; /* Update PHY configuration */ @@ -1893,17 +2493,19 @@ void bnx2x_link_status_update(struct link_params *params, } /* anything 10 and over uses the bmac */ - link_10g = ((vars->line_speed == SPEED_10000) || - (vars->line_speed == SPEED_12000) || - (vars->line_speed == SPEED_12500) || - (vars->line_speed == SPEED_13000) || - (vars->line_speed == SPEED_15000) || - (vars->line_speed == SPEED_16000)); - if (link_10g) + link_10g_plus = (vars->line_speed >= SPEED_10000); + + if (link_10g_plus) { + if (USES_WARPCORE(bp)) + vars->mac_type = MAC_TYPE_XMAC; + else vars->mac_type = MAC_TYPE_BMAC; + } else { + if (USES_WARPCORE(bp)) + vars->mac_type = MAC_TYPE_UMAC; else vars->mac_type = MAC_TYPE_EMAC; - + } } else { /* link down */ DP(NETIF_MSG_LINK, "phy link down\n"); @@ -3507,14 +4109,21 @@ static int bnx2x_update_link_down(struct link_params *params, REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + if (!CHIP_IS_E3(bp)) + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); msleep(10); - - /* reset BigMac */ - bnx2x_bmac_rx_disable(bp, params->port); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + /* reset BigMac/Xmac */ + if (CHIP_IS_E1x(bp) || + CHIP_IS_E2(bp)) { + bnx2x_bmac_rx_disable(bp, params->port); + REG_WR(bp, GRCBASE_MISC + + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + } + if (CHIP_IS_E3(bp)) + bnx2x_xmac_disable(params); + return 0; } @@ -3535,25 +4144,36 @@ static int bnx2x_update_link_up(struct link_params *params, if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) vars->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED; - - if (link_10g) { - bnx2x_bmac_enable(params, vars, 0); + if (USES_WARPCORE(bp)) { + if (link_10g) + bnx2x_xmac_enable(params, vars, 0); + else + bnx2x_umac_enable(params, vars, 0); bnx2x_set_led(params, vars, - LED_MODE_OPER, SPEED_10000); - } else { - rc = bnx2x_emac_program(params, vars); - - bnx2x_emac_enable(params, vars, 0); + LED_MODE_OPER, vars->line_speed); + } + if ((CHIP_IS_E1x(bp) || + CHIP_IS_E2(bp))) { + if (link_10g) { + bnx2x_bmac_enable(params, vars, 0); - /* AN complete? */ - if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) - && (!(vars->phy_flags & PHY_SGMII_FLAG)) && - SINGLE_MEDIA_DIRECT(params)) - bnx2x_set_gmii_tx_driver(params); + bnx2x_set_led(params, vars, + LED_MODE_OPER, SPEED_10000); + } else { + rc = bnx2x_emac_program(params, vars); + bnx2x_emac_enable(params, vars, 0); + + /* AN complete? */ + if ((vars->link_status & + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) + && (!(vars->phy_flags & PHY_SGMII_FLAG)) && + SINGLE_MEDIA_DIRECT(params)) + bnx2x_set_gmii_tx_driver(params); + } } /* PBF - link up */ - if (!(CHIP_IS_E2(bp))) + if (CHIP_IS_E1x(bp)) rc |= bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); @@ -3617,7 +4237,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + if (!CHIP_IS_E3(bp)) + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); /* * Step 1: @@ -7871,6 +8492,43 @@ void bnx2x_init_emac_loopback(struct link_params *params, REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); } +void bnx2x_init_xmac_loopback(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + vars->link_up = 1; + if (!params->req_line_speed[0]) + vars->line_speed = SPEED_10000; + else + vars->line_speed = params->req_line_speed[0]; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->mac_type = MAC_TYPE_XMAC; + vars->phy_flags = PHY_XGXS_FLAG; + /* + * Set WC to loopback mode since link is required to provide clock + * to the XMAC in 20G mode + */ + + bnx2x_xmac_enable(params, vars, 1); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); +} + +void bnx2x_init_umac_loopback(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + vars->link_up = 1; + vars->line_speed = SPEED_1000; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->mac_type = MAC_TYPE_UMAC; + vars->phy_flags = PHY_XGXS_FLAG; + bnx2x_umac_enable(params, vars, 1); + + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); +} + void bnx2x_init_xgxs_loopback(struct link_params *params, struct link_vars *vars) { @@ -7883,17 +8541,23 @@ void bnx2x_init_xgxs_loopback(struct link_params *params, else vars->line_speed = SPEED_10000; - - bnx2x_xgxs_deassert(params); + if (!USES_WARPCORE(bp)) + bnx2x_xgxs_deassert(params); bnx2x_link_initialize(params, vars); if (params->req_line_speed[0] == SPEED_1000) { - bnx2x_emac_program(params, vars); - bnx2x_emac_enable(params, vars, 0); - - } else - bnx2x_bmac_enable(params, vars, 0); - + if (USES_WARPCORE(bp)) + bnx2x_umac_enable(params, vars, 0); + else { + bnx2x_emac_program(params, vars); + bnx2x_emac_enable(params, vars, 0); + } + } else { + if (USES_WARPCORE(bp)) + bnx2x_xmac_enable(params, vars, 0); + else + bnx2x_bmac_enable(params, vars, 0); + } if (params->loopback_mode == LOOPBACK_XGXS) { /* set 10G XGXS loopback */ @@ -7957,17 +8621,23 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) case LOOPBACK_EMAC: bnx2x_init_emac_loopback(params, vars); break; + case LOOPBACK_XMAC: + bnx2x_init_xmac_loopback(params, vars); + break; + case LOOPBACK_UMAC: + bnx2x_init_umac_loopback(params, vars); + break; case LOOPBACK_XGXS: case LOOPBACK_EXT_PHY: bnx2x_init_xgxs_loopback(params, vars); break; default: - /* No loopback */ - if (params->switch_cfg == SWITCH_CFG_10G) - bnx2x_xgxs_deassert(params); - else - bnx2x_serdes_deassert(bp, params->port); - + if (!CHIP_IS_E3(bp)) { + if (params->switch_cfg == SWITCH_CFG_10G) + bnx2x_xgxs_deassert(params); + else + bnx2x_serdes_deassert(bp, params->port); + } bnx2x_link_initialize(params, vars); msleep(30); bnx2x_link_int_enable(params); @@ -7995,14 +8665,19 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); /* disable nig egress interface */ - REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + if (!CHIP_IS_E3(bp)) { + REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + } /* Stop BigMac rx */ - bnx2x_bmac_rx_disable(bp, port); - + if (!CHIP_IS_E3(bp)) + bnx2x_bmac_rx_disable(bp, port); + else + bnx2x_xmac_disable(params); /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + if (!CHIP_IS_E3(bp)) + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); msleep(10); /* The PHY reset is controlled by GPIO 1 @@ -8038,10 +8713,10 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); /* disable nig ingress interface */ - REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); - REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); - REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + if (!CHIP_IS_E3(bp)) { + REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); + REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); + } vars->link_up = 0; return 0; } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 3fef7782490..12602f18fae 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -66,17 +66,6 @@ #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) -#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE 170 -#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE 0 - -#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE 250 -#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE 0 - -#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE 10 -#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE 90 - -#define PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE 50 -#define PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE 250 #define PFC_BRB_FULL_LB_XOFF_THRESHOLD 170 #define PFC_BRB_FULL_LB_XON_THRESHOLD 250 @@ -132,6 +121,7 @@ struct bnx2x_phy { #define FLAGS_FAN_FAILURE_DET_REQ (1<<2) /* Initialize first the XGXS and only then the phy itself */ #define FLAGS_INIT_XGXS_FIRST (1<<3) +#define FLAGS_4_PORT_MODE (1<<5) #define FLAGS_REARM_LATCH_SIGNAL (1<<6) #define FLAGS_SFP_NOT_APPROVED (1<<7) @@ -366,6 +356,8 @@ int bnx2x_phy_probe(struct link_params *params); u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 port); + + /* DCBX structs */ /* Number of maximum COS per chip */ @@ -400,7 +392,7 @@ struct bnx2x_nig_brb_pfc_port_params { * Used to update the PFC attributes in EMAC, BMAC, NIG and BRB * when link is already up */ -void bnx2x_update_pfc(struct link_params *params, +int bnx2x_update_pfc(struct link_params *params, struct link_vars *vars, struct bnx2x_nig_brb_pfc_port_params *pfc_params); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index f8436e0c131..65f3b126076 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -54,16 +54,20 @@ /* [RW 10] The number of free blocks below which the full signal to class 0 * is asserted */ #define BRB1_REG_FULL_0_XOFF_THRESHOLD_0 0x601d0 -/* [RW 10] The number of free blocks above which the full signal to class 0 +#define BRB1_REG_FULL_0_XOFF_THRESHOLD_1 0x60230 +/* [RW 11] The number of free blocks above which the full signal to class 0 * is de-asserted */ #define BRB1_REG_FULL_0_XON_THRESHOLD_0 0x601d4 -/* [RW 10] The number of free blocks below which the full signal to class 1 +#define BRB1_REG_FULL_0_XON_THRESHOLD_1 0x60234 +/* [RW 11] The number of free blocks below which the full signal to class 1 * is asserted */ #define BRB1_REG_FULL_1_XOFF_THRESHOLD_0 0x601d8 -/* [RW 10] The number of free blocks above which the full signal to class 1 +#define BRB1_REG_FULL_1_XOFF_THRESHOLD_1 0x60238 +/* [RW 11] The number of free blocks above which the full signal to class 1 * is de-asserted */ #define BRB1_REG_FULL_1_XON_THRESHOLD_0 0x601dc -/* [RW 10] The number of free blocks below which the full signal to the LB +#define BRB1_REG_FULL_1_XON_THRESHOLD_1 0x6023c +/* [RW 11] The number of free blocks below which the full signal to the LB * port is asserted */ #define BRB1_REG_FULL_LB_XOFF_THRESHOLD 0x601e0 /* [RW 10] The number of free blocks above which the full signal to the LB @@ -75,15 +79,49 @@ /* [RW 10] The number of free blocks below which the High_llfc signal to interface #n is asserted. */ #define BRB1_REG_HIGH_LLFC_LOW_THRESHOLD_0 0x6013c -/* [RW 23] LL RAM data. */ -#define BRB1_REG_LL_RAM 0x61000 +/* [RW 11] The number of blocks guarantied for the LB port */ +#define BRB1_REG_LB_GUARANTIED 0x601ec +/* [RW 11] The hysteresis on the guarantied buffer space for the Lb port + * before signaling XON. */ +#define BRB1_REG_LB_GUARANTIED_HYST 0x60264 +/* [RW 24] LL RAM data. */ +#define BRB1_REG_LL_RAM 0x61000 /* [RW 10] The number of free blocks above which the Low_llfc signal to interface #n is de-asserted. */ #define BRB1_REG_LOW_LLFC_HIGH_THRESHOLD_0 0x6016c /* [RW 10] The number of free blocks below which the Low_llfc signal to interface #n is asserted. */ #define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0 0x6015c -/* [RW 10] The number of blocks guarantied for the MAC port */ +/* [RW 11] The number of blocks guarantied for class 0 in MAC 0. The + * register is applicable only when per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_0_CLASS_0_GUARANTIED 0x60244 +/* [RW 11] The hysteresis on the guarantied buffer space for class 0 in MAC + * 1 before signaling XON. The register is applicable only when + * per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST 0x60254 +/* [RW 11] The number of blocks guarantied for class 1 in MAC 0. The + * register is applicable only when per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_0_CLASS_1_GUARANTIED 0x60248 +/* [RW 11] The hysteresis on the guarantied buffer space for class 1in MAC 0 + * before signaling XON. The register is applicable only when + * per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST 0x60258 +/* [RW 11] The number of blocks guarantied for class 0in MAC1.The register + * is applicable only when per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_1_CLASS_0_GUARANTIED 0x6024c +/* [RW 11] The hysteresis on the guarantied buffer space for class 0 in MAC + * 1 before signaling XON. The register is applicable only when + * per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST 0x6025c +/* [RW 11] The number of blocks guarantied for class 1 in MAC 1. The + * register is applicable only when per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_1_CLASS_1_GUARANTIED 0x60250 +/* [RW 11] The hysteresis on the guarantied buffer space for class 1 in MAC + * 1 before signaling XON. The register is applicable only when + * per_class_guaranty_mode is set. */ +#define BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST 0x60260 +/* [RW 11] The number of blocks guarantied for the MAC port. The register is + * applicable only when per_class_guaranty_mode is reset. */ #define BRB1_REG_MAC_GUARANTIED_0 0x601e8 #define BRB1_REG_MAC_GUARANTIED_1 0x60240 /* [R 24] The number of full blocks. */ @@ -100,15 +138,19 @@ /* [RW 10] The number of free blocks below which the pause signal to class 0 * is asserted */ #define BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 0x601c0 -/* [RW 10] The number of free blocks above which the pause signal to class 0 +#define BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 0x60220 +/* [RW 11] The number of free blocks above which the pause signal to class 0 * is de-asserted */ #define BRB1_REG_PAUSE_0_XON_THRESHOLD_0 0x601c4 -/* [RW 10] The number of free blocks below which the pause signal to class 1 +#define BRB1_REG_PAUSE_0_XON_THRESHOLD_1 0x60224 +/* [RW 11] The number of free blocks below which the pause signal to class 1 * is asserted */ #define BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0 0x601c8 -/* [RW 10] The number of free blocks above which the pause signal to class 1 +#define BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 0x60228 +/* [RW 11] The number of free blocks above which the pause signal to class 1 * is de-asserted */ #define BRB1_REG_PAUSE_1_XON_THRESHOLD_0 0x601cc +#define BRB1_REG_PAUSE_1_XON_THRESHOLD_1 0x6022c /* [RW 10] Write client 0: De-assert pause threshold. Not Functional */ #define BRB1_REG_PAUSE_HIGH_THRESHOLD_0 0x60078 #define BRB1_REG_PAUSE_HIGH_THRESHOLD_1 0x6007c @@ -1655,12 +1697,31 @@ * is compared to the value on ctrl_md_devad. Drives output * misc_xgxs0_phy_addr. Global register. */ #define MISC_REG_WC0_CTRL_PHY_ADDR 0xa9cc +/* [RW 2] XMAC Core port mode. Indicates the number of ports on the system + side. This should be less than or equal to phy_port_mode; if some of the + ports are not used. This enables reduction of frequency on the core side. + This is a strap input for the XMAC_MP core. 00 - Single Port Mode; 01 - + Dual Port Mode; 10 - Tri Port Mode; 11 - Quad Port Mode. This is a strap + input for the XMAC_MP core; and should be changed only while reset is + held low. Reset on Hard reset. */ +#define MISC_REG_XMAC_CORE_PORT_MODE 0xa964 +/* [RW 2] XMAC PHY port mode. Indicates the number of ports on the Warp + Core. This is a strap input for the XMAC_MP core. 00 - Single Port Mode; + 01 - Dual Port Mode; 1x - Quad Port Mode; This is a strap input for the + XMAC_MP core; and should be changed only while reset is held low. Reset + on Hard reset. */ +#define MISC_REG_XMAC_PHY_PORT_MODE 0xa960 /* [RW 32] 1 [47] Packet Size = 64 Write to this register write bits 31:0. * Reads from this register will clear bits 31:0. */ #define MSTAT_REG_RX_STAT_GR64_LO 0x200 /* [RW 32] 1 [00] Tx Good Packet Count Write to this register write bits * 31:0. Reads from this register will clear bits 31:0. */ #define MSTAT_REG_TX_STAT_GTXPOK_LO 0 +#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST (0x1<<0) +#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST (0x1<<1) +#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4) +#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2) +#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3) #define NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN (0x1<<0) #define NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) @@ -1903,6 +1964,12 @@ #define NIG_REG_P0_HWPFC_ENABLE 0x18078 #define NIG_REG_P0_LLH_FUNC_MEM2 0x18480 #define NIG_REG_P0_LLH_FUNC_MEM2_ENABLE 0x18440 +/* [RW 1] Input enable for RX MAC interface. */ +#define NIG_REG_P0_MAC_IN_EN 0x185ac +/* [RW 1] Output enable for TX MAC interface */ +#define NIG_REG_P0_MAC_OUT_EN 0x185b0 +/* [RW 1] Output enable for TX PAUSE signal to the MAC. */ +#define NIG_REG_P0_MAC_PAUSE_OUT_EN 0x185b4 /* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for * future expansion) each priorty is to be mapped to. Bits 3:0 specify the * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit @@ -1939,6 +2006,7 @@ * than one bit may be set; allowing multiple priorities to be mapped to one * COS. */ #define NIG_REG_P0_RX_COS5_PRIORITY_MASK 0x186bc +/* [R 1] RX FIFO for receiving data from MAC is empty. */ /* [RW 15] Specify which of the credit registers the client is to be mapped * to. Bits[2:0] are for client 0; bits [14:12] are for client 4. For * clients that are not subject to WFQ credit blocking - their @@ -1981,6 +2049,11 @@ #define NIG_REG_P1_HDRS_AFTER_BASIC 0x1818c #define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 #define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460 +#define NIG_REG_P1_MAC_IN_EN 0x185c0 +/* [RW 1] Output enable for TX MAC interface */ +#define NIG_REG_P1_MAC_OUT_EN 0x185c4 +/* [RW 1] Output enable for TX PAUSE signal to the MAC. */ +#define NIG_REG_P1_MAC_PAUSE_OUT_EN 0x185c8 /* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for * future expansion) each priorty is to be mapped to. Bits 3:0 specify the * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit @@ -2002,6 +2075,52 @@ * than one bit may be set; allowing multiple priorities to be mapped to one * COS. */ #define NIG_REG_P1_RX_COS2_PRIORITY_MASK 0x186f8 +/* [R 1] RX FIFO for receiving data from MAC is empty. */ +#define NIG_REG_P1_RX_MACFIFO_EMPTY 0x1858c +/* [R 1] TLLH FIFO is empty. */ +#define NIG_REG_P1_TLLH_FIFO_EMPTY 0x18338 +/* [RW 32] Specify which of the credit registers the client is to be mapped + * to. This register specifies bits 31:0 of the 36-bit value. Bits[3:0] are + * for client 0; bits [35:32] are for client 8. For clients that are not + * subject to WFQ credit blocking - their specifications here are not used. + * This is a new register (with 2_) added in E3 B0 to accommodate the 9 + * input clients to ETS arbiter. The reset default is set for management and + * debug to use credit registers 6, 7, and 8, respectively, and COSes 0-5 to + * use credit registers 0-5 respectively (0x543210876). Note that credit + * registers can not be shared between clients. Note also that there are + * only COS0-2 in port 1- there is a total of 6 clients in port 1. Only + * credit registers 0-5 are valid. This register should be configured + * appropriately before enabling WFQ. */ +#define NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB 0x186e8 +/* [RW 4] Specify which of the credit registers the client is to be mapped + * to. This register specifies bits 35:32 of the 36-bit value. Bits[3:0] are + * for client 0; bits [35:32] are for client 8. For clients that are not + * subject to WFQ credit blocking - their specifications here are not used. + * This is a new register (with 2_) added in E3 B0 to accommodate the 9 + * input clients to ETS arbiter. The reset default is set for management and + * debug to use credit registers 6, 7, and 8, respectively, and COSes 0-5 to + * use credit registers 0-5 respectively (0x543210876). Note that credit + * registers can not be shared between clients. Note also that there are + * only COS0-2 in port 1- there is a total of 6 clients in port 1. Only + * credit registers 0-5 are valid. This register should be configured + * appropriately before enabling WFQ. */ +#define NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB 0x186ec +/* [RW 9] Specify whether the client competes directly in the strict + * priority arbiter. The bits are mapped according to client ID (client IDs + * are defined in tx_arb_priority_client2): 0-management; 1-debug traffic + * from this port; 2-debug traffic from other port; 3-COS0 traffic; 4-COS1 + * traffic; 5-COS2 traffic; 6-COS3 traffic; 7-COS4 traffic; 8-COS5 traffic. + * Default value is set to enable strict priorities for all clients. */ +#define NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT 0x18234 +/* [RW 9] Specify whether the client is subject to WFQ credit blocking. The + * bits are mapped according to client ID (client IDs are defined in + * tx_arb_priority_client2): 0-management; 1-debug traffic from this port; + * 2-debug traffic from other port; 3-COS0 traffic; 4-COS1 traffic; 5-COS2 + * traffic; 6-COS3 traffic; 7-COS4 traffic; 8-COS5 traffic. Default value is + * 0 for not using WFQ credit blocking. */ +#define NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ 0x18238 +/* [RW 32] Specify the upper bound that credit register 0 is allowed to + * reach. */ /* [RW 1] Pause enable for port0. This register may get 1 only when ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same port */ @@ -4427,6 +4546,17 @@ The fields are: [4:0] - tail pointer; 10:5] - Link List size; 15:11] - header pointer. */ #define UCM_REG_XX_TABLE 0xe0300 +#define UMAC_COMMAND_CONFIG_REG_LOOP_ENA (0x1<<15) +#define UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK (0x1<<24) +#define UMAC_COMMAND_CONFIG_REG_PAD_EN (0x1<<5) +#define UMAC_COMMAND_CONFIG_REG_PROMIS_EN (0x1<<4) +#define UMAC_COMMAND_CONFIG_REG_RX_ENA (0x1<<1) +#define UMAC_COMMAND_CONFIG_REG_SW_RESET (0x1<<13) +#define UMAC_COMMAND_CONFIG_REG_TX_ENA (0x1<<0) +#define UMAC_REG_COMMAND_CONFIG 0x8 +/* [RW 14] Defines a 14-Bit maximum frame length used by the MAC receive + * logic to check frames. */ +#define UMAC_REG_MAXFR 0x14 /* [RW 8] The event id for aggregated interrupt 0 */ #define USDM_REG_AGG_INT_EVENT_0 0xc4038 #define USDM_REG_AGG_INT_EVENT_1 0xc403c @@ -4939,6 +5069,28 @@ #define XCM_REG_XX_MSG_NUM 0x20428 /* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */ #define XCM_REG_XX_OVFL_EVNT_ID 0x20058 +#define XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS (0x1<<0) +#define XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS (0x1<<1) +#define XMAC_CTRL_REG_CORE_LOCAL_LPBK (0x1<<3) +#define XMAC_CTRL_REG_RX_EN (0x1<<1) +#define XMAC_CTRL_REG_SOFT_RESET (0x1<<6) +#define XMAC_CTRL_REG_TX_EN (0x1<<0) +#define XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN (0x1<<18) +#define XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN (0x1<<17) +#define XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN (0x1<<0) +#define XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN (0x1<<3) +#define XMAC_PFC_CTRL_HI_REG_RX_PFC_EN (0x1<<4) +#define XMAC_PFC_CTRL_HI_REG_TX_PFC_EN (0x1<<5) +#define XMAC_REG_CLEAR_RX_LSS_STATUS 0x60 +#define XMAC_REG_CTRL 0 +#define XMAC_REG_PAUSE_CTRL 0x68 +#define XMAC_REG_PFC_CTRL 0x70 +#define XMAC_REG_PFC_CTRL_HI 0x74 +#define XMAC_REG_RX_LSS_STATUS 0x58 +/* [RW 14] Maximum packet size in receive direction; exclusive of preamble & + * CRC in strip mode */ +#define XMAC_REG_RX_MAX_SIZE 0x40 +#define XMAC_REG_TX_CTRL 0x20 /* [RW 16] Indirect access to the XX table of the XX protection mechanism. The fields are:[4:0] - tail pointer; 9:5] - Link List size; 14:10] - header pointer. */ @@ -5011,6 +5163,8 @@ #define XSDM_REG_NUM_OF_Q8_CMD 0x166264 /* [ST 32] The number of commands received in queue 9 */ #define XSDM_REG_NUM_OF_Q9_CMD 0x166268 +/* [RW 13] The start address in the internal RAM for queue counters */ +#define XSDM_REG_Q_COUNTER_START_ADDR 0x166010 /* [W 17] Generate an operation after completion; bit-16 is * AggVectIdx_valid; bits 15:8 are AggVectIdx; bits 7:5 are the TRIG and * bits 4:0 are the T124Param[4:0] */ @@ -5312,6 +5466,9 @@ #define MISC_REGISTERS_RESET_REG_2_RST_PCI_MDIO (0x1<<13) #define MISC_REGISTERS_RESET_REG_2_RST_RBCN (0x1<<9) #define MISC_REGISTERS_RESET_REG_2_SET 0x594 +#define MISC_REGISTERS_RESET_REG_2_UMAC0 (0x1<<20) +#define MISC_REGISTERS_RESET_REG_2_XMAC (0x1<<22) +#define MISC_REGISTERS_RESET_REG_2_XMAC_SOFT (0x1<<23) #define MISC_REGISTERS_RESET_REG_3_CLEAR 0x5a8 #define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ (0x1<<1) #define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN (0x1<<2) @@ -5503,9 +5660,13 @@ #define GRCBASE_HC 0x108000 #define GRCBASE_PXP2 0x120000 #define GRCBASE_PBF 0x140000 +#define GRCBASE_UMAC0 0x160000 +#define GRCBASE_UMAC1 0x160400 #define GRCBASE_XPB 0x161000 #define GRCBASE_MSTAT0 0x162000 #define GRCBASE_MSTAT1 0x162800 +#define GRCBASE_XMAC0 0x163000 +#define GRCBASE_XMAC1 0x163800 #define GRCBASE_TIMERS 0x164000 #define GRCBASE_XSDM 0x166000 #define GRCBASE_QM 0x168000 -- cgit v1.2.3-70-g09d2 From 3c9ada227c56c6f41e24b01d183b00b007c7ac93 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:34:12 +0000 Subject: bnx2x: Add Warpcore support for 578xx Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 1812 +++++++++++++++++++++++++++++++++++----- drivers/net/bnx2x/bnx2x_link.h | 40 +- drivers/net/bnx2x/bnx2x_main.c | 3 + drivers/net/bnx2x/bnx2x_reg.h | 163 ++++ 4 files changed, 1825 insertions(+), 193 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 873463966a0..b777d2c9633 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -37,6 +37,13 @@ #define ETH_MAX_JUMBO_PACKET_SIZE 9600 #define MDIO_ACCESS_TIMEOUT 1000 #define BMAC_CONTROL_RX_ENABLE 2 +#define WC_LANE_MAX 4 +#define I2C_SWITCH_WIDTH 2 +#define I2C_BSC0 0 +#define I2C_BSC1 1 +#define I2C_WA_RETRY_CNT 3 +#define MCPR_IMC_COMMAND_READ_OP 1 +#define MCPR_IMC_COMMAND_WRITE_OP 2 /***********************************************************/ /* Shortcut definitions */ @@ -108,7 +115,10 @@ #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX #define GP_STATUS_10G_KX4 \ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 - +#define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR +#define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI +#define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS +#define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD @@ -122,11 +132,8 @@ #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD - -#define PHY_XGXS_FLAG 0x1 -#define PHY_SGMII_FLAG 0x2 -#define PHY_SERDES_FLAG 0x4 - +#define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD +#define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD /* */ #define SFP_EEPROM_CON_TYPE_ADDR 0x2 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 @@ -247,6 +254,7 @@ #define ETS_E3B0_PBF_MIN_W_VAL (10000) #define MAX_PACKET_SIZE (9700) +#define WC_UC_TIMEOUT 100 /**********************************************************/ /* INTERFACE */ @@ -282,6 +290,47 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) return val; } +/******************************************************************/ +/* EPIO/GPIO section */ +/******************************************************************/ +static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en) +{ + u32 epio_mask, gp_output, gp_oenable; + + /* Sanity check */ + if (epio_pin > 31) { + DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin); + return; + } + DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en); + epio_mask = 1 << epio_pin; + /* Set this EPIO to output */ + gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS); + if (en) + gp_output |= epio_mask; + else + gp_output &= ~epio_mask; + + REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output); + + /* Set the value for this EPIO */ + gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE); + REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask); +} + +static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val) +{ + if (pin_cfg == PIN_CFG_NA) + return; + if (pin_cfg >= PIN_CFG_EPIO0) { + bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val); + } else { + u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3; + u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2; + bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port); + } +} + /******************************************************************/ /* ETS section */ /******************************************************************/ @@ -607,7 +656,10 @@ static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port) mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); mode &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT); - mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); + if (USES_WARPCORE(bp)) + mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); + else + mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); mode |= (EMAC_MDIO_MODE_CLAUSE_45); REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode); @@ -729,7 +781,7 @@ static void bnx2x_umac_enable(struct link_params *params, /* Enable RX and TX */ val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN; val |= UMAC_COMMAND_CONFIG_REG_TX_ENA | - UMAC_COMMAND_CONFIG_REG_RX_ENA; + UMAC_COMMAND_CONFIG_REG_RX_ENA; REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); udelay(50); @@ -1649,7 +1701,7 @@ int bnx2x_update_pfc(struct link_params *params, else { val = REG_RD(bp, MISC_REG_RESET_REG_2); if ((val & - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) == 0) { DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); bnx2x_emac_enable(params, vars, 0); @@ -1940,18 +1992,6 @@ static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, case SPEED_10000: init_crd = thresh + 553 - 22; break; - - case SPEED_12000: - init_crd = thresh + 664 - 22; - break; - - case SPEED_13000: - init_crd = thresh + 742 - 22; - break; - - case SPEED_16000: - init_crd = thresh + 778 - 22; - break; default: DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed); @@ -2073,6 +2113,14 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, rc = -EFAULT; } } + /* Work around for E3 A0 */ + if (phy->flags & FLAGS_MDC_MDIO_WA) { + phy->flags ^= FLAGS_DUMMY_READ; + if (phy->flags & FLAGS_DUMMY_READ) { + u16 temp_val; + bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); + } + } return rc; } @@ -2128,11 +2176,149 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, rc = -EFAULT; } } + /* Work around for E3 A0 */ + if (phy->flags & FLAGS_MDC_MDIO_WA) { + phy->flags ^= FLAGS_DUMMY_READ; + if (phy->flags & FLAGS_DUMMY_READ) { + u16 temp_val; + bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); + } + } + + return rc; +} +/******************************************************************/ +/* BSC access functions from E3 */ +/******************************************************************/ +static void bnx2x_bsc_module_sel(struct link_params *params) +{ + int idx; + u32 board_cfg, sfp_ctrl; + u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH]; + struct bnx2x *bp = params->bp; + u8 port = params->port; + /* Read I2C output PINs */ + board_cfg = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.shared_hw_config.board)); + i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK; + i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >> + SHARED_HW_CFG_E3_I2C_MUX1_SHIFT; + + /* Read I2C output value */ + sfp_ctrl = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_cmn_pin_cfg)); + i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0; + i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0; + DP(NETIF_MSG_LINK, "Setting BSC switch\n"); + for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++) + bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]); +} + +static int bnx2x_bsc_read(struct link_params *params, + struct bnx2x_phy *phy, + u8 sl_devid, + u16 sl_addr, + u8 lc_addr, + u8 xfer_cnt, + u32 *data_array) +{ + u32 val, i; + int rc = 0; + struct bnx2x *bp = params->bp; + + if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) { + DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid); + return -EINVAL; + } + + if (xfer_cnt > 16) { + DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n", + xfer_cnt); + return -EINVAL; + } + bnx2x_bsc_module_sel(params); + + xfer_cnt = 16 - lc_addr; + + /* enable the engine */ + val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); + val |= MCPR_IMC_COMMAND_ENABLE; + REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); + + /* program slave device ID */ + val = (sl_devid << 16) | sl_addr; + REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val); + + /* start xfer with 0 byte to update the address pointer ???*/ + val = (MCPR_IMC_COMMAND_ENABLE) | + (MCPR_IMC_COMMAND_WRITE_OP << + MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | + (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0); + REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); + + /* poll for completion */ + i = 0; + val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); + while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { + udelay(10); + val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); + if (i++ > 1000) { + DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n", + i); + rc = -EFAULT; + break; + } + } + if (rc == -EFAULT) + return rc; + + /* start xfer with read op */ + val = (MCPR_IMC_COMMAND_ENABLE) | + (MCPR_IMC_COMMAND_READ_OP << + MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | + (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | + (xfer_cnt); + REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); + + /* poll for completion */ + i = 0; + val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); + while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { + udelay(10); + val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); + if (i++ > 1000) { + DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i); + rc = -EFAULT; + break; + } + } + if (rc == -EFAULT) + return rc; + + for (i = (lc_addr >> 2); i < 4; i++) { + data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4)); +#ifdef __BIG_ENDIAN + data_array[i] = ((data_array[i] & 0x000000ff) << 24) | + ((data_array[i] & 0x0000ff00) << 8) | + ((data_array[i] & 0x00ff0000) >> 8) | + ((data_array[i] & 0xff000000) >> 24); +#endif + } return rc; } +static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 or_val) +{ + u16 val; + bnx2x_cl45_read(bp, phy, devad, reg, &val); + bnx2x_cl45_write(bp, phy, devad, reg, val | or_val); +} + int bnx2x_phy_read(struct link_params *params, u8 phy_addr, u8 devad, u16 reg, u16 *ret_val) { @@ -2168,6 +2354,59 @@ int bnx2x_phy_write(struct link_params *params, u8 phy_addr, } return -EINVAL; } +static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy, + struct link_params *params) +{ + u8 lane = 0; + struct bnx2x *bp = params->bp; + u32 path_swap, path_swap_ovr; + u8 path, port; + + path = BP_PATH(bp); + port = params->port; + + if (bnx2x_is_4_port_mode(bp)) { + u32 port_swap, port_swap_ovr; + + /*figure out path swap value */ + path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR); + if (path_swap_ovr & 0x1) + path_swap = (path_swap_ovr & 0x2); + else + path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP); + + if (path_swap) + path = path ^ 1; + + /*figure out port swap value */ + port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR); + if (port_swap_ovr & 0x1) + port_swap = (port_swap_ovr & 0x2); + else + port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP); + + if (port_swap) + port = port ^ 1; + + lane = (port<<1) + path; + } else { /* two port mode - no port swap */ + + /*figure out path swap value */ + path_swap_ovr = + REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR); + if (path_swap_ovr & 0x1) { + path_swap = (path_swap_ovr & 0x2); + } else { + path_swap = + REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP); + } + if (path_swap) + path = path ^ 1; + + lane = path << 1 ; + } + return lane; +} static void bnx2x_set_aer_mmd(struct link_params *params, struct bnx2x_phy *phy) @@ -2182,7 +2421,18 @@ static void bnx2x_set_aer_mmd(struct link_params *params, offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? (phy->addr + ser_lane) : 0; - if (CHIP_IS_E2(bp)) + if (USES_WARPCORE(bp)) { + aer_val = bnx2x_get_warpcore_lane(phy, params); + /* + * In Dual-lane mode, two lanes are joined together, + * so in order to configure them, the AER broadcast method is + * used here. + * 0x200 is the broadcast address for lanes 0,1 + * 0x201 is the broadcast address for lanes 2,3 + */ + if (phy->flags & FLAGS_WC_DUAL_MODE) + aer_val = (aer_val >> 1) | 0x200; + } else if (CHIP_IS_E2(bp)) aer_val = 0x3800 + offset - 1; else aer_val = 0x3800 + offset; @@ -2415,6 +2665,778 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, } return ret; } +/******************************************************************/ +/* Warpcore section */ +/******************************************************************/ +/* The init_internal_warpcore should mirror the xgxs, + * i.e. reset the lane (if needed), set aer for the + * init configuration, and set/clear SGMII flag. Internal + * phy init is done purely in phy_init stage. + */ +static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { + u16 val16 = 0, lane; + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); + /* Check adding advertisement for 1G KX */ + if (((vars->line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || + (vars->line_speed == SPEED_1000)) { + u16 sd_digital; + val16 |= (1<<5); + + /* Enable CL37 1G Parallel Detect */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, + (sd_digital | 0x1)); + + DP(NETIF_MSG_LINK, "Advertize 1G\n"); + } + if (((vars->line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || + (vars->line_speed == SPEED_10000)) { + /* Check adding advertisement for 10G KR */ + val16 |= (1<<7); + /* Enable 10G Parallel Detect */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_PAR_DET_10G_CTRL, 1); + + DP(NETIF_MSG_LINK, "Advertize 10G\n"); + } + + /* Set Transmit PMD settings */ + lane = bnx2x_get_warpcore_lane(phy, params); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, + ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | + (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | + (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, + 0x03f0); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL, + 0x03f0); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + 0x383f); + + /* Advertised speeds */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); + + /* Advertise pause */ + bnx2x_ext_phy_set_pause(params, phy, vars); + + /* Enable Autoneg */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000); + + /* Over 1G - AN local device user page 1 */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL3_UP1, 0x1f); + + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC7, &val16); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100); +} + +static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val; + + /* Disable Autoneg */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7); + + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_PAR_DET_10G_CTRL, 0); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00); + + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0); + + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL3_UP1, 0x1); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC7, 0xa); + + /* Disable CL36 PCS Tx */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0); + + /* Double Wide Single Data Rate @ pll rate */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF); + + /* Leave cl72 training enable, needed for KR */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, + MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, + 0x2); + + /* Leave CL72 enabled */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + val | 0x3800); + + /* Set speed via PMA/PMD register */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); + + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, + MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB); + + /*Enable encoded forced speed */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30); + + /* Turn TX scramble payload only the 64/66 scrambler */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX66_CONTROL, 0x9); + + /* Turn RX scramble payload only the 64/66 scrambler */ + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_CONTROL, 0xF9); + + /* set and clear loopback to cause a reset to 64/66 decoder */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0); + +} + +static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, + struct link_params *params, + u8 is_xfi) +{ + struct bnx2x *bp = params->bp; + u16 misc1_val, tap_val, tx_driver_val, lane, val; + /* Hold rxSeqStart */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000)); + + /* Hold tx_fifo_reset */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1)); + + /* Disable CL73 AN */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); + + /* Disable 100FX Enable and Auto-Detect */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_FX100_CTRL1, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA)); + + /* Disable 100FX Idle detect */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_FX100_CTRL3, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_FX100_CTRL3, (val | 0x0080)); + + /* Set Block address to Remote PHY & Clear forced_speed[5] */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC3, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F)); + + /* Turn off auto-detect & fiber mode */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, + (val & 0xFFEE)); + + /* Set filter_force_link, disable_false_link and parallel_detect */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, + ((val | 0x0006) & 0xFFFE)); + + /* Set XFI / SFI */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val); + + misc1_val &= ~(0x1f); + + if (is_xfi) { + misc1_val |= 0x5; + tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | + (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | + (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); + tx_driver_val = + ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | + (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | + (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); + + } else { + misc1_val |= 0x9; + tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | + (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | + (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); + tx_driver_val = + ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | + (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | + (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); + } + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); + + /* Set Transmit PMD settings */ + lane = bnx2x_get_warpcore_lane(phy, params); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX_FIR_TAP, + tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, + tx_driver_val); + + /* Enable fiber mode, enable and invert sig_det */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd); + + /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC3, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); + + /* 10G XFI Full Duplex */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100); + + /* Release tx_fifo_reset */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE); + + /* Release rxSeqStart */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF)); +} + +static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n"); +} + +static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 lane) +{ + /* Rx0 anaRxControl1G */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90); + + /* Rx2 anaRxControl1G */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW0, 0xE070); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW1, 0xC0D0); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW2, 0xA0B0); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW3, 0x8090); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0); + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0); + + /* Serdes Digital Misc1 */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008); + + /* Serdes Digital4 Misc3 */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC3, 0x8088); + + /* Set Transmit PMD settings */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX_FIR_TAP, + ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | + (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | + (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) | + MDIO_WC_REG_TX_FIR_TAP_ENABLE)); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, + ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | + (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | + (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); +} + +static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, + struct link_params *params, + u8 fiber_mode) +{ + struct bnx2x *bp = params->bp; + u16 val16, digctrl_kx1, digctrl_kx2; + u8 lane; + + lane = bnx2x_get_warpcore_lane(phy, params); + + /* Clear XFI clock comp in non-10G single lane mode. */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_CONTROL, &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13)); + + if (phy->req_line_speed == SPEED_AUTO_NEG) { + /* SGMII Autoneg */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, + val16 | 0x1000); + DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n"); + } else { + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); + val16 &= 0xcfbf; + switch (phy->req_line_speed) { + case SPEED_10: + break; + case SPEED_100: + val16 |= 0x2000; + break; + case SPEED_1000: + val16 |= 0x0040; + break; + default: + DP(NETIF_MSG_LINK, "Speed not supported: 0x%x" + "\n", phy->req_line_speed); + return; + } + + if (phy->req_duplex == DUPLEX_FULL) + val16 |= 0x0100; + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16); + + DP(NETIF_MSG_LINK, "set SGMII force speed %d\n", + phy->req_line_speed); + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); + DP(NETIF_MSG_LINK, " (readback) %x\n", val16); + } + + /* SGMII Slave mode and disable signal detect */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1); + if (fiber_mode) + digctrl_kx1 = 1; + else + digctrl_kx1 &= 0xff4a; + + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, + digctrl_kx1); + + /* Turn off parallel detect */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, + (digctrl_kx2 & ~(1<<2))); + + /* Re-enable parallel detect */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, + (digctrl_kx2 | (1<<2))); + + /* Enable autodet */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, + (digctrl_kx1 | 0x10)); +} + +static void bnx2x_warpcore_reset_lane(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 reset) +{ + u16 val; + /* Take lane out of reset after configuration is finished */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC6, &val); + if (reset) + val |= 0xC000; + else + val &= 0x3FFF; + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC6, val); + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL5_MISC6, &val); +} + + + /* Clear SFI/XFI link settings registers */ +static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy, + struct link_params *params, + u16 lane) +{ + struct bnx2x *bp = params->bp; + u16 val16; + + /* Set XFI clock comp as default. */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_CONTROL, &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13)); + + bnx2x_warpcore_reset_lane(bp, phy, 1); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_FX100_CTRL1, 0x014a); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_FX100_CTRL3, 0x0800); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL4_MISC3, 0x8008); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000); + lane = bnx2x_get_warpcore_lane(phy, params); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX_FIR_TAP, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140); + bnx2x_warpcore_reset_lane(bp, phy, 0); +} + +static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp, + u32 chip_id, + u32 shmem_base, u8 port, + u8 *gpio_num, u8 *gpio_port) +{ + u32 cfg_pin; + *gpio_num = 0; + *gpio_port = 0; + if (CHIP_IS_E3(bp)) { + cfg_pin = (REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_sfp_ctrl)) & + PORT_HW_CFG_E3_MOD_ABS_MASK) >> + PORT_HW_CFG_E3_MOD_ABS_SHIFT; + + /* + * Should not happen. This function called upon interrupt + * triggered by GPIO ( since EPIO can only generate interrupts + * to MCP). + * So if this function was called and none of the GPIOs was set, + * it means the shit hit the fan. + */ + if ((cfg_pin < PIN_CFG_GPIO0_P0) || + (cfg_pin > PIN_CFG_GPIO3_P1)) { + DP(NETIF_MSG_LINK, "ERROR: Invalid cfg pin %x for " + "module detect indication\n", + cfg_pin); + return -EINVAL; + } + + *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3; + *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2; + } else { + *gpio_num = MISC_REGISTERS_GPIO_3; + *gpio_port = port; + } + DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port); + return 0; +} + +static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 gpio_num, gpio_port; + u32 gpio_val; + if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, + params->shmem_base, params->port, + &gpio_num, &gpio_port) != 0) + return 0; + gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port); + + /* Call the handling function in case module is detected */ + if (gpio_val == 0) + return 1; + else + return 0; +} + +static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u32 serdes_net_if; + u8 fiber_mode; + u16 lane = bnx2x_get_warpcore_lane(phy, params); + serdes_net_if = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].default_cfg)) & + PORT_HW_CFG_NET_SERDES_IF_MASK); + DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, " + "serdes_net_if = 0x%x\n", + vars->line_speed, serdes_net_if); + bnx2x_set_aer_mmd(params, phy); + + vars->phy_flags |= PHY_XGXS_FLAG; + if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) || + (phy->req_line_speed && + ((phy->req_line_speed == SPEED_100) || + (phy->req_line_speed == SPEED_10)))) { + vars->phy_flags |= PHY_SGMII_FLAG; + DP(NETIF_MSG_LINK, "Setting SGMII mode\n"); + bnx2x_warpcore_clear_regs(phy, params, lane); + bnx2x_warpcore_set_sgmii_speed(phy, params, 0); + } else { + switch (serdes_net_if) { + case PORT_HW_CFG_NET_SERDES_IF_KR: + /* Enable KR Auto Neg */ + if (params->loopback_mode == LOOPBACK_NONE) + bnx2x_warpcore_enable_AN_KR(phy, params, vars); + else { + DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n"); + bnx2x_warpcore_set_10G_KR(phy, params, vars); + } + break; + + case PORT_HW_CFG_NET_SERDES_IF_XFI: + bnx2x_warpcore_clear_regs(phy, params, lane); + if (vars->line_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, "Setting 10G XFI\n"); + bnx2x_warpcore_set_10G_XFI(phy, params, 1); + } else { + if (SINGLE_MEDIA_DIRECT(params)) { + DP(NETIF_MSG_LINK, "1G Fiber\n"); + fiber_mode = 1; + } else { + DP(NETIF_MSG_LINK, "10/100/1G SGMII\n"); + fiber_mode = 0; + } + bnx2x_warpcore_set_sgmii_speed(phy, + params, + fiber_mode); + } + + break; + + case PORT_HW_CFG_NET_SERDES_IF_SFI: + + bnx2x_warpcore_clear_regs(phy, params, lane); + if (vars->line_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, "Setting 10G SFI\n"); + bnx2x_warpcore_set_10G_XFI(phy, params, 0); + } else if (vars->line_speed == SPEED_1000) { + DP(NETIF_MSG_LINK, "Setting 1G Fiber\n"); + bnx2x_warpcore_set_sgmii_speed(phy, params, 1); + } + /* Issue Module detection */ + if (bnx2x_is_sfp_module_plugged(phy, params)) + bnx2x_sfp_module_detection(phy, params); + break; + + case PORT_HW_CFG_NET_SERDES_IF_DXGXS: + if (vars->line_speed != SPEED_20000) { + DP(NETIF_MSG_LINK, "Speed not supported yet\n"); + return; + } + DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n"); + bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane); + /* Issue Module detection */ + + bnx2x_sfp_module_detection(phy, params); + break; + + case PORT_HW_CFG_NET_SERDES_IF_KR2: + if (vars->line_speed != SPEED_20000) { + DP(NETIF_MSG_LINK, "Speed not supported yet\n"); + return; + } + DP(NETIF_MSG_LINK, "Setting 20G KR2\n"); + bnx2x_warpcore_set_20G_KR2(bp, phy); + break; + + default: + DP(NETIF_MSG_LINK, "Unsupported Serdes Net Interface " + "0x%x\n", serdes_net_if); + return; + } + } + + /* Take lane out of reset after configuration is finished */ + bnx2x_warpcore_reset_lane(bp, phy, 0); + DP(NETIF_MSG_LINK, "Exit config init\n"); +} + +static void bnx2x_sfp_e3_set_transmitter(struct link_params *params, + struct bnx2x_phy *phy, + u8 tx_en) +{ + struct bnx2x *bp = params->bp; + u32 cfg_pin; + u8 port = params->port; + + cfg_pin = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_sfp_ctrl)) & + PORT_HW_CFG_TX_LASER_MASK; + /* Set the !tx_en since this pin is DISABLE_TX_LASER */ + DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en); + /* For 20G, the expected pin to be used is 3 pins after the current */ + + bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1); + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G) + bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1); +} + +static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u16 val16; + bnx2x_sfp_e3_set_transmitter(params, phy, 0); + bnx2x_set_mdio_clk(bp, params->chip_id, params->port); + bnx2x_set_aer_mmd(params, phy); + /* Global register */ + bnx2x_warpcore_reset_lane(bp, phy, 1); + + /* Clear loopback settings (if any) */ + /* 10G & 20G */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 & + 0xBFFF); + + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe); + + /* Update those 1-copy registers */ + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, 0); + /* Enable 1G MDIO (1-copy) */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, + &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, + val16 & ~0x10); + + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK1_LANECTRL2, + val16 & 0xff00); + +} + +static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u16 val16; + u32 lane; + DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n", + params->loopback_mode, phy->req_line_speed); + + if (phy->req_line_speed < SPEED_10000) { + /* 10/100/1000 */ + + /* Update those 1-copy registers */ + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, 0); + /* Enable 1G MDIO (1-copy) */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, + &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, + val16 | 0x10); + /* Set 1G loopback based on lane (1-copy) */ + lane = bnx2x_get_warpcore_lane(phy, params); + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_XGXSBLK1_LANECTRL2, + val16 | (1<line_speed = SPEED_10000; break; - + case LINK_20GTFD: + vars->line_speed = SPEED_20000; + break; default: break; } @@ -2491,7 +3515,10 @@ void bnx2x_link_status_update(struct link_params *params, } else { vars->phy_flags &= ~PHY_SGMII_FLAG; } - + if (vars->line_speed && + USES_WARPCORE(bp) && + (vars->line_speed == SPEED_1000)) + vars->phy_flags |= PHY_SGMII_FLAG; /* anything 10 and over uses the bmac */ link_10g_plus = (vars->line_speed >= SPEED_10000); @@ -2499,12 +3526,12 @@ void bnx2x_link_status_update(struct link_params *params, if (USES_WARPCORE(bp)) vars->mac_type = MAC_TYPE_XMAC; else - vars->mac_type = MAC_TYPE_BMAC; + vars->mac_type = MAC_TYPE_BMAC; } else { if (USES_WARPCORE(bp)) vars->mac_type = MAC_TYPE_UMAC; - else - vars->mac_type = MAC_TYPE_EMAC; + else + vars->mac_type = MAC_TYPE_EMAC; } } else { /* link down */ DP(NETIF_MSG_LINK, "phy link down\n"); @@ -2860,9 +3887,6 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, if (vars->line_speed == SPEED_10000) reg_val |= MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; - if (vars->line_speed == SPEED_13000) - reg_val |= - MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; } CL22_WR_OVER_CL45(bp, phy, @@ -3212,45 +4236,25 @@ static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy, vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED; } - -static int bnx2x_link_settings_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars, + u16 is_link_up, + u16 speed_mask, + u16 is_duplex) { struct bnx2x *bp = params->bp; - u16 new_line_speed, gp_status; - int rc = 0; - - /* Read gp_status */ - CL22_RD_OVER_CL45(bp, phy, - MDIO_REG_BANK_GP_STATUS, - MDIO_GP_STATUS_TOP_AN_STATUS1, - &gp_status); - if (phy->req_line_speed == SPEED_AUTO_NEG) vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; - if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { - DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n", - gp_status); + if (is_link_up) { + DP(NETIF_MSG_LINK, "phy link up\n"); vars->phy_link_up = 1; vars->link_status |= LINK_STATUS_LINK_UP; - if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) - vars->duplex = DUPLEX_FULL; - else - vars->duplex = DUPLEX_HALF; - - if (SINGLE_MEDIA_DIRECT(params)) { - bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); - if (phy->req_line_speed == SPEED_AUTO_NEG) - bnx2x_xgxs_an_resolve(phy, params, vars, - gp_status); - } - - switch (gp_status & GP_STATUS_SPEED_MASK) { + switch (speed_mask) { case GP_STATUS_10M: - new_line_speed = SPEED_10; + vars->line_speed = SPEED_10; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_10TFD; else @@ -3258,7 +4262,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, break; case GP_STATUS_100M: - new_line_speed = SPEED_100; + vars->line_speed = SPEED_100; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_100TXFD; else @@ -3267,7 +4271,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, case GP_STATUS_1G: case GP_STATUS_1G_KX: - new_line_speed = SPEED_1000; + vars->line_speed = SPEED_1000; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_1000TFD; else @@ -3275,7 +4279,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, break; case GP_STATUS_2_5G: - new_line_speed = SPEED_2500; + vars->line_speed = SPEED_2500; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_2500TFD; else @@ -3286,25 +4290,28 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, case GP_STATUS_6G: DP(NETIF_MSG_LINK, "link speed unsupported gp_status 0x%x\n", - gp_status); + speed_mask); return -EINVAL; case GP_STATUS_10G_KX4: case GP_STATUS_10G_HIG: case GP_STATUS_10G_CX4: - new_line_speed = SPEED_10000; + case GP_STATUS_10G_KR: + case GP_STATUS_10G_SFI: + case GP_STATUS_10G_XFI: + vars->line_speed = SPEED_10000; vars->link_status |= LINK_10GTFD; break; - + case GP_STATUS_20G_DXGXS: + vars->line_speed = SPEED_20000; + vars->link_status |= LINK_20GTFD; + break; default: DP(NETIF_MSG_LINK, "link speed unsupported gp_status 0x%x\n", - gp_status); + speed_mask); return -EINVAL; } - - vars->line_speed = new_line_speed; - } else { /* link_down */ DP(NETIF_MSG_LINK, "phy link down\n"); @@ -3313,7 +4320,47 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->mac_type = MAC_TYPE_NONE; + } + DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n", + vars->phy_link_up, vars->line_speed); + return 0; +} + +static int bnx2x_link_settings_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + + struct bnx2x *bp = params->bp; + + u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask; + int rc = 0; + + /* Read gp_status */ + CL22_RD_OVER_CL45(bp, phy, + MDIO_REG_BANK_GP_STATUS, + MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) + duplex = DUPLEX_FULL; + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) + link_up = 1; + speed_mask = gp_status & GP_STATUS_SPEED_MASK; + DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n", + gp_status, link_up, speed_mask); + rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask, + duplex); + if (rc == -EINVAL) + return rc; + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { + if (SINGLE_MEDIA_DIRECT(params)) { + bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); + if (phy->req_line_speed == SPEED_AUTO_NEG) + bnx2x_xgxs_an_resolve(phy, params, vars, + gp_status); + } + } else { /* link_down */ if ((phy->req_line_speed == SPEED_AUTO_NEG) && SINGLE_MEDIA_DIRECT(params)) { /* Check signal is detected */ @@ -3321,13 +4368,86 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, } } - DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n", - gp_status, vars->phy_link_up, vars->line_speed); DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", vars->duplex, vars->flow_ctrl, vars->link_status); return rc; } +static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + + struct bnx2x *bp = params->bp; + + u8 lane; + u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL; + int rc = 0; + lane = bnx2x_get_warpcore_lane(phy, params); + /* Read gp_status */ + if (phy->req_line_speed > SPEED_10000) { + u16 temp_link_up; + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + 1, &temp_link_up); + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + 1, &link_up); + DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n", + temp_link_up, link_up); + link_up &= (1<<2); + if (link_up) + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } else { + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1); + DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1); + /* Check for either KR or generic link up. */ + gp_status1 = ((gp_status1 >> 8) & 0xf) | + ((gp_status1 >> 12) & 0xf); + link_up = gp_status1 & (1 << lane); + if (link_up && SINGLE_MEDIA_DIRECT(params)) { + u16 pd, gp_status4; + if (phy->req_line_speed == SPEED_AUTO_NEG) { + /* Check Autoneg complete */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_GP2_STATUS_GP_2_4, + &gp_status4); + if (gp_status4 & ((1<<12)<link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + + /* Check parallel detect used */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_PAR_DET_10G_STATUS, + &pd); + if (pd & (1<<15)) + vars->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; + } + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + } + + if (lane < 2) { + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed); + } else { + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed); + } + DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed); + + if ((lane & 1) == 0) + gp_speed <<= 8; + gp_speed &= 0x3f00; + + + rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed, + duplex); + + DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", + vars->duplex, vars->flow_ctrl, vars->link_status); + return rc; +} static void bnx2x_set_gmii_tx_driver(struct link_params *params) { struct bnx2x *bp = params->bp; @@ -3555,7 +4675,11 @@ static void bnx2x_link_int_enable(struct link_params *params) struct bnx2x *bp = params->bp; /* Setting the status to report on link up for either XGXS or SerDes */ - if (params->switch_cfg == SWITCH_CFG_10G) { + if (CHIP_IS_E3(bp)) { + mask = NIG_MASK_XGXS0_LINK_STATUS; + if (!(SINGLE_MEDIA_DIRECT(params))) + mask |= NIG_MASK_MI_INT; + } else if (params->switch_cfg == SWITCH_CFG_10G) { mask = (NIG_MASK_XGXS0_LINK10G | NIG_MASK_XGXS0_LINK_STATUS); DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); @@ -3628,11 +4752,11 @@ static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, } static void bnx2x_link_int_ack(struct link_params *params, - struct link_vars *vars, u8 is_10g) + struct link_vars *vars, u8 is_10g_plus) { struct bnx2x *bp = params->bp; u8 port = params->port; - + u32 mask; /* * First reset all status we assume only one line will be * change at a time @@ -3642,43 +4766,30 @@ static void bnx2x_link_int_ack(struct link_params *params, NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS)); if (vars->phy_link_up) { - if (is_10g) { - /* - * Disable the 10G link interrupt by writing 1 to the - * status register - */ - DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_XGXS0_LINK10G); - - } else if (params->switch_cfg == SWITCH_CFG_10G) { - /* - * Disable the link interrupt by writing 1 to the - * relevant lane in the status register - */ - u32 ser_lane = ((params->lane_config & + if (USES_WARPCORE(bp)) + mask = NIG_STATUS_XGXS0_LINK_STATUS; + else { + if (is_10g_plus) + mask = NIG_STATUS_XGXS0_LINK10G; + else if (params->switch_cfg == SWITCH_CFG_10G) { + /* + * Disable the link interrupt by writing 1 to + * the relevant lane in the status register + */ + u32 ser_lane = + ((params->lane_config & PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - - DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", - vars->line_speed); - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - ((1 << ser_lane) << - NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); - - } else { /* SerDes */ - DP(NETIF_MSG_LINK, "SerDes phy link up\n"); - /* - * Disable the link interrupt by writing 1 to the status - * register - */ - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_SERDES0_LINK_STATUS); + mask = ((1 << ser_lane) << + NIG_STATUS_XGXS0_LINK_STATUS_SIZE); + } else + mask = NIG_STATUS_SERDES0_LINK_STATUS; } - + DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n", + mask); + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + mask); } } @@ -3775,15 +4886,18 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; if (phy->req_line_speed != SPEED_1000) { - u32 md_devad; + u32 md_devad = 0; DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); - /* change the uni_phy_addr in the nig */ - md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + - port*0x18)); + if (!CHIP_IS_E3(bp)) { + /* change the uni_phy_addr in the nig */ + md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + + port*0x18)); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + 0x5); + } bnx2x_cl45_write(bp, phy, 5, @@ -3800,8 +4914,11 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, /* set aer mmd back */ bnx2x_set_aer_mmd(params, phy); - /* and md_devad */ - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad); + if (!CHIP_IS_E3(bp)) { + /* and md_devad */ + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + md_devad); + } } else { u16 mii_ctrl; DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); @@ -3875,7 +4992,9 @@ int bnx2x_set_led(struct link_params *params, (tmp | EMAC_LED_OVERRIDE)); return rc; } - } else if (SINGLE_MEDIA_DIRECT(params)) { + } else if (SINGLE_MEDIA_DIRECT(params) && + (CHIP_IS_E1x(bp) || + CHIP_IS_E2(bp))) { /* * This is a work-around for HW issue found when link * is up in CL73 @@ -3934,14 +5053,42 @@ int bnx2x_test_link(struct link_params *params, struct link_vars *vars, u16 gp_status = 0, phy_index = 0; u8 ext_phy_link_up = 0, serdes_phy_type; struct link_vars temp_vars; - - CL22_RD_OVER_CL45(bp, ¶ms->phy[INT_PHY], + struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; + + if (CHIP_IS_E3(bp)) { + u16 link_up; + if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)] + > SPEED_10000) { + /* Check 20G link */ + bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, + 1, &link_up); + bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, + 1, &link_up); + link_up &= (1<<2); + } else { + /* Check 10G link and below*/ + u8 lane = bnx2x_get_warpcore_lane(int_phy, params); + bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, + MDIO_WC_REG_GP2_STATUS_GP_2_1, + &gp_status); + gp_status = ((gp_status >> 8) & 0xf) | + ((gp_status >> 12) & 0xf); + link_up = gp_status & (1 << lane); + } + if (!link_up) + return -ESRCH; + } else { + CL22_RD_OVER_CL45(bp, int_phy, MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); /* link is up only if both local phy and external phy are up */ if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) return -ESRCH; + } + /* In XGXS loopback mode, do not check external PHY */ + if (params->loopback_mode == LOOPBACK_XGXS) + return 0; switch (params->num_phys) { case 1: @@ -3997,8 +5144,8 @@ static int bnx2x_link_initialize(struct link_params *params, * (no external phys), or this board has external phy which requires * to first. */ - - bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars); + if (!USES_WARPCORE(bp)) + bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars); /* init ext phy and enable link state int */ non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || (params->loopback_mode == LOOPBACK_XGXS)); @@ -4007,7 +5154,9 @@ static int bnx2x_link_initialize(struct link_params *params, (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || (params->loopback_mode == LOOPBACK_EXT_PHY)) { struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; - if (vars->line_speed == SPEED_AUTO_NEG) + if (vars->line_speed == SPEED_AUTO_NEG && + (CHIP_IS_E1x(bp) || + CHIP_IS_E2(bp))) bnx2x_set_parallel_detection(phy, params); if (params->phy[INT_PHY].config_init) params->phy[INT_PHY].config_init(phy, @@ -4203,7 +5352,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) struct bnx2x *bp = params->bp; struct link_vars phy_vars[MAX_PHYS]; u8 port = params->port; - u8 link_10g, phy_index; + u8 link_10g_plus, phy_index; u8 ext_phy_link_up = 0, cur_link_up; int rc = 0; u8 is_mi_int = 0; @@ -4221,6 +5370,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) phy_vars[phy_index].fault_detected = 0; } + if (USES_WARPCORE(bp)) + bnx2x_set_aer_mmd(params, ¶ms->phy[INT_PHY]); + DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", port, (vars->phy_flags & PHY_XGXS_FLAG), REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); @@ -4392,14 +5544,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) } /* anything 10 and over uses the bmac */ - link_10g = ((vars->line_speed == SPEED_10000) || - (vars->line_speed == SPEED_12000) || - (vars->line_speed == SPEED_12500) || - (vars->line_speed == SPEED_13000) || - (vars->line_speed == SPEED_15000) || - (vars->line_speed == SPEED_16000)); + link_10g_plus = (vars->line_speed >= SPEED_10000); - bnx2x_link_int_ack(params, vars, link_10g); + bnx2x_link_int_ack(params, vars, link_10g_plus); /* * In case external phy link is up, and internal link is down @@ -4440,7 +5587,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) (phy_vars[active_external_phy].fault_detected == 0)); if (vars->link_up) - rc = bnx2x_update_link_up(params, vars, link_10g); + rc = bnx2x_update_link_up(params, vars, link_10g_plus); else rc = bnx2x_update_link_down(params, vars); @@ -5135,9 +6282,10 @@ static u8 bnx2x_get_gpio_port(struct link_params *params) swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); return gpio_port ^ (swap_val && swap_override); } -static void bnx2x_sfp_set_transmitter(struct link_params *params, - struct bnx2x_phy *phy, - u8 tx_en) + +static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params, + struct bnx2x_phy *phy, + u8 tx_en) { u16 val; u8 port = params->port; @@ -5192,6 +6340,18 @@ static void bnx2x_sfp_set_transmitter(struct link_params *params, } } +static void bnx2x_sfp_set_transmitter(struct link_params *params, + struct bnx2x_phy *phy, + u8 tx_en) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en); + if (CHIP_IS_E3(bp)) + bnx2x_sfp_e3_set_transmitter(params, phy, tx_en); + else + bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en); +} + static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) @@ -5258,6 +6418,42 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } +static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, + u16 addr, u8 byte_cnt, + u8 *o_buf) +{ + int rc = 0; + u8 i, j = 0, cnt = 0; + u32 data_array[4]; + u16 addr32; + struct bnx2x *bp = params->bp; + /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:" + " addr %d, cnt %d\n", + addr, byte_cnt);*/ + if (byte_cnt > 16) { + DP(NETIF_MSG_LINK, "Reading from eeprom is" + " is limited to 16 bytes\n"); + return -EINVAL; + } + + /* 4 byte aligned address */ + addr32 = addr & (~0x3); + do { + rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, + data_array); + } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); + + if (rc == 0) { + for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) { + o_buf[j] = *((u8 *)data_array + i); + j++; + } + } + + return rc; +} + static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) @@ -5360,6 +6556,10 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, byte_cnt, o_buf); break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, + byte_cnt, o_buf); + break; } return rc; } @@ -5573,8 +6773,8 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, * In the GPIO register, bit 4 is use to determine if the GPIOs are * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for * output - * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 - * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 + * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0 + * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1 * where the 1st bit is the over-current(only input), and 2nd bit is * for power( only output ) * @@ -5703,7 +6903,7 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, } } -static void bnx2x_set_sfp_module_fault_led(struct link_params *params, +static void bnx2x_set_e1e2_module_fault_led(struct link_params *params, u8 gpio_mode) { struct bnx2x *bp = params->bp; @@ -5735,6 +6935,58 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params, } } +static void bnx2x_set_e3_module_fault_led(struct link_params *params, + u8 gpio_mode) +{ + u32 pin_cfg; + u8 port = params->port; + struct bnx2x *bp = params->bp; + pin_cfg = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_sfp_ctrl)) & + PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >> + PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT; + DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n", + gpio_mode, pin_cfg); + bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode); +} + +static void bnx2x_set_sfp_module_fault_led(struct link_params *params, + u8 gpio_mode) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode); + if (CHIP_IS_E3(bp)) { + /* + * Low ==> if SFP+ module is supported otherwise + * High ==> if SFP+ module is not on the approved vendor list + */ + bnx2x_set_e3_module_fault_led(params, gpio_mode); + } else + bnx2x_set_e1e2_module_fault_led(params, gpio_mode); +} + +static void bnx2x_warpcore_power_module(struct link_params *params, + struct bnx2x_phy *phy, + u8 power) +{ + u32 pin_cfg; + struct bnx2x *bp = params->bp; + + pin_cfg = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & + PORT_HW_CFG_E3_PWR_DIS_MASK) >> + PORT_HW_CFG_E3_PWR_DIS_SHIFT; + DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", + power, pin_cfg); + /* + * Low ==> corresponding SFP+ module is powered + * high ==> the SFP+ module is powered down + */ + bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); +} + static void bnx2x_power_sfp_module(struct link_params *params, struct bnx2x_phy *phy, u8 power) @@ -5747,9 +6999,47 @@ static void bnx2x_power_sfp_module(struct link_params *params, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: bnx2x_8727_power_module(params->bp, phy, power); break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + bnx2x_warpcore_power_module(params, phy, power); + break; + default: + break; + } +} +static void bnx2x_warpcore_set_limiting_mode(struct link_params *params, + struct bnx2x_phy *phy, + u16 edc_mode) +{ + u16 val = 0; + u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT; + struct bnx2x *bp = params->bp; + + u8 lane = bnx2x_get_warpcore_lane(phy, params); + /* This is a global register which controls all lanes */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); + val &= ~(0xf << (lane << 2)); + + switch (edc_mode) { + case EDC_MODE_LINEAR: + case EDC_MODE_LIMITING: + mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT; + break; + case EDC_MODE_PASSIVE_DAC: + mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC; + break; default: break; } + + val |= (mode << (lane << 2)); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val); + /* A must read */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); + + } static void bnx2x_set_limiting_mode(struct link_params *params, @@ -5764,6 +7054,9 @@ static void bnx2x_set_limiting_mode(struct link_params *params, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode); break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode); + break; } } @@ -5828,23 +7121,33 @@ int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, void bnx2x_handle_module_detect_int(struct link_params *params) { struct bnx2x *bp = params->bp; - struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; + struct bnx2x_phy *phy; u32 gpio_val; - u8 port = params->port; + u8 gpio_num, gpio_port; + if (CHIP_IS_E3(bp)) + phy = ¶ms->phy[INT_PHY]; + else + phy = ¶ms->phy[EXT_PHY1]; + + if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base, + params->port, &gpio_num, &gpio_port) == + -EINVAL) { + DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n"); + return; + } /* Set valid module led off */ bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH); /* Get current gpio val reflecting module plugged in / out*/ - gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); + gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port); /* Call the handling function in case module is detected */ if (gpio_val == 0) { bnx2x_power_sfp_module(params, phy, 1); - bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, + bnx2x_set_gpio_int(bp, gpio_num, MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, - port); - + gpio_port); if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) bnx2x_sfp_module_detection(phy, params); else @@ -5855,9 +7158,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params) port_feature_config[params->port]. config)); - bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, + bnx2x_set_gpio_int(bp, gpio_num, MISC_REGISTERS_GPIO_INT_OUTPUT_SET, - port); + gpio_port); /* * Module was plugged out. * Disable transmit for this module @@ -7762,6 +9065,43 @@ static struct bnx2x_phy phy_xgxs = { .set_link_led = (set_link_led_t)NULL, .phy_specific_func = (phy_specific_func_t)NULL }; +static struct bnx2x_phy phy_warpcore = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, + .addr = 0xff, + .def_md_devad = 0, + .flags = FLAGS_HW_LOCK_REQUIRED, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_20000baseKR2_Full | + SUPPORTED_20000baseMLD2_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + /* req_duplex = */0, + /* rsrv = */0, + .config_init = (config_init_t)bnx2x_warpcore_config_init, + .read_status = (read_status_t)bnx2x_warpcore_read_status, + .link_reset = (link_reset_t)bnx2x_warpcore_link_reset, + .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; + static struct bnx2x_phy phy_7101 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, @@ -8126,22 +9466,105 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, dev_info.port_feature_config[port].link_config)) & PORT_FEATURE_CONNECTED_SWITCH_MASK); chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16; - switch (switch_cfg) { - case SWITCH_CFG_1G: - phy_addr = REG_RD(bp, - NIG_REG_SERDES0_CTRL_PHY_ADDR + - port * 0x10); - *phy = phy_serdes; - break; - case SWITCH_CFG_10G: + DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id); + if (USES_WARPCORE(bp)) { + u32 serdes_net_if; phy_addr = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR + - port * 0x18); - *phy = phy_xgxs; - break; - default: - DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); - return -EINVAL; + MISC_REG_WC0_CTRL_PHY_ADDR); + *phy = phy_warpcore; + if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3) + phy->flags |= FLAGS_4_PORT_MODE; + else + phy->flags &= ~FLAGS_4_PORT_MODE; + /* Check Dual mode */ + serdes_net_if = (REG_RD(bp, shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[port].default_cfg)) & + PORT_HW_CFG_NET_SERDES_IF_MASK); + /* + * Set the appropriate supported and flags indications per + * interface type of the chip + */ + switch (serdes_net_if) { + case PORT_HW_CFG_NET_SERDES_IF_SGMII: + phy->supported &= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + phy->media_type = ETH_PHY_BASE_T; + break; + case PORT_HW_CFG_NET_SERDES_IF_XFI: + phy->media_type = ETH_PHY_XFP_FIBER; + break; + case PORT_HW_CFG_NET_SERDES_IF_SFI: + phy->supported &= (SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + phy->media_type = ETH_PHY_SFP_FIBER; + break; + case PORT_HW_CFG_NET_SERDES_IF_KR: + phy->media_type = ETH_PHY_KR; + phy->supported &= (SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + case PORT_HW_CFG_NET_SERDES_IF_DXGXS: + phy->media_type = ETH_PHY_KR; + phy->flags |= FLAGS_WC_DUAL_MODE; + phy->supported &= (SUPPORTED_20000baseMLD2_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + case PORT_HW_CFG_NET_SERDES_IF_KR2: + phy->media_type = ETH_PHY_KR; + phy->flags |= FLAGS_WC_DUAL_MODE; + phy->supported &= (SUPPORTED_20000baseKR2_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + default: + DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n", + serdes_net_if); + break; + } + + /* + * Enable MDC/MDIO work-around for E3 A0 since free running MDC + * was not set as expected. For B0, ECO will be enabled so there + * won't be an issue there + */ + if (CHIP_REV(bp) == CHIP_REV_Ax) + phy->flags |= FLAGS_MDC_MDIO_WA; + } else { + switch (switch_cfg) { + case SWITCH_CFG_1G: + phy_addr = REG_RD(bp, + NIG_REG_SERDES0_CTRL_PHY_ADDR + + port * 0x10); + *phy = phy_serdes; + break; + case SWITCH_CFG_10G: + phy_addr = REG_RD(bp, + NIG_REG_XGXS0_CTRL_PHY_ADDR + + port * 0x18); + *phy = phy_xgxs; + break; + default: + DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); + return -EINVAL; + } } phy->addr = (u8)phy_addr; phy->mdio_ctrl = bnx2x_get_emac_base(bp, @@ -8509,7 +9932,13 @@ void bnx2x_init_xmac_loopback(struct link_params *params, * Set WC to loopback mode since link is required to provide clock * to the XMAC in 20G mode */ - + if (vars->line_speed == SPEED_20000) { + bnx2x_set_aer_mmd(params, ¶ms->phy[0]); + bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0); + params->phy[INT_PHY].config_loopback( + ¶ms->phy[INT_PHY], + params); + } bnx2x_xmac_enable(params, vars, 1); REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); } @@ -8718,6 +10147,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); } vars->link_up = 0; + vars->phy_flags = 0; return 0; } @@ -8743,14 +10173,14 @@ static int bnx2x_8073_common_init_phy(struct bnx2x *bp, for (port = PORT_MAX - 1; port >= PORT_0; port--) { u32 shmem_base, shmem2_base; /* In E2, same phy is using for port0 of the two paths */ - if (CHIP_IS_E2(bp)) { - shmem_base = shmem_base_path[port]; - shmem2_base = shmem2_base_path[port]; - port_of_path = 0; - } else { + if (CHIP_IS_E1x(bp)) { shmem_base = shmem_base_path[0]; shmem2_base = shmem2_base_path[0]; port_of_path = port; + } else { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; } /* Extract the ext phy address for the port */ @@ -8794,10 +10224,10 @@ static int bnx2x_8073_common_init_phy(struct bnx2x *bp, /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { - if (CHIP_IS_E2(bp)) - port_of_path = 0; - else + if (CHIP_IS_E1x(bp)) port_of_path = port; + else + port_of_path = 0; DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", phy_blk[port]->addr); @@ -8871,12 +10301,12 @@ static int bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, shmem2_base; /* In E2, same phy is using for port0 of the two paths */ - if (CHIP_IS_E2(bp)) { - shmem_base = shmem_base_path[port]; - shmem2_base = shmem2_base_path[port]; - } else { + if (CHIP_IS_E1x(bp)) { shmem_base = shmem_base_path[0]; shmem2_base = shmem2_base_path[0]; + } else { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; } /* Extract the ext phy address for the port */ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, @@ -8985,14 +10415,14 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, shmem2_base; /* In E2, same phy is using for port0 of the two paths */ - if (CHIP_IS_E2(bp)) { - shmem_base = shmem_base_path[port]; - shmem2_base = shmem2_base_path[port]; - port_of_path = 0; - } else { + if (CHIP_IS_E1x(bp)) { shmem_base = shmem_base_path[0]; shmem2_base = shmem2_base_path[0]; port_of_path = port; + } else { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; } /* Extract the ext phy address for the port */ @@ -9027,10 +10457,10 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp, } /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { - if (CHIP_IS_E2(bp)) - port_of_path = 0; - else + if (CHIP_IS_E1x(bp)) port_of_path = port; + else + port_of_path = 0; DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", phy_blk[port]->addr); if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], @@ -9091,13 +10521,17 @@ int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], u32 shmem2_base_path[], u32 chip_id) { int rc = 0; - u32 phy_ver; - u8 phy_index; + u32 phy_ver, val; + u8 phy_index = 0; u32 ext_phy_type, ext_phy_config; bnx2x_set_mdio_clk(bp, chip_id, PORT_0); bnx2x_set_mdio_clk(bp, chip_id, PORT_1); DP(NETIF_MSG_LINK, "Begin common phy init\n"); - + if (CHIP_IS_E3(bp)) { + /* Enable EPIO */ + val = REG_RD(bp, MISC_REG_GEN_PURP_HWG); + REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1); + } /* Check if common init was already done */ phy_ver = REG_RD(bp, shmem_base_path[0] + offsetof(struct shmem_region, @@ -9183,8 +10617,14 @@ void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, u8 gpio_num = 0xff, gpio_port = 0xff, phy_index; u32 val; u32 offset, aeu_mask, swap_val, swap_override, sync_offset; - - { + if (CHIP_IS_E3(bp)) { + if (bnx2x_get_mod_abs_int_cfg(bp, chip_id, + shmem_base, + port, + &gpio_num, + &gpio_port) != 0) + return; + } else { struct bnx2x_phy phy; for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; phy_index++) { diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 12602f18fae..82bc021bdf0 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -33,12 +33,13 @@ #define BNX2X_FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH #define BNX2X_FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE +#define NET_SERDES_IF_XFI 1 +#define NET_SERDES_IF_SFI 2 +#define NET_SERDES_IF_KR 3 +#define NET_SERDES_IF_DXGXS 4 + #define SPEED_AUTO_NEG 0 -#define SPEED_12000 12000 -#define SPEED_12500 12500 -#define SPEED_13000 13000 -#define SPEED_15000 15000 -#define SPEED_16000 16000 +#define SPEED_20000 20000 #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14 #define SFP_EEPROM_VENDOR_NAME_SIZE 16 @@ -46,6 +47,12 @@ #define SFP_EEPROM_VENDOR_OUI_SIZE 3 #define SFP_EEPROM_PART_NO_ADDR 0x28 #define SFP_EEPROM_PART_NO_SIZE 16 +#define SFP_EEPROM_REVISION_ADDR 0x38 +#define SFP_EEPROM_REVISION_SIZE 4 +#define SFP_EEPROM_SERIAL_ADDR 0x44 +#define SFP_EEPROM_SERIAL_SIZE 16 +#define SFP_EEPROM_DATE_ADDR 0x54 /* ASCII YYMMDD */ +#define SFP_EEPROM_DATE_SIZE 6 #define PWR_FLT_ERR_MSG_LEN 250 #define XGXS_EXT_PHY_TYPE(ext_phy_config) \ @@ -62,7 +69,18 @@ #define SINGLE_MEDIA(params) (params->num_phys == 2) /* Dual Media board contains two external phy with different media */ #define DUAL_MEDIA(params) (params->num_phys == 3) + +#define FW_PARAM_PHY_ADDR_MASK 0x000000FF +#define FW_PARAM_PHY_TYPE_MASK 0x0000FF00 +#define FW_PARAM_MDIO_CTRL_MASK 0xFFFF0000 #define FW_PARAM_MDIO_CTRL_OFFSET 16 +#define FW_PARAM_PHY_ADDR(fw_param) (fw_param & \ + FW_PARAM_PHY_ADDR_MASK) +#define FW_PARAM_PHY_TYPE(fw_param) (fw_param & \ + FW_PARAM_PHY_TYPE_MASK) +#define FW_PARAM_MDIO_CTRL(fw_param) ((fw_param & \ + FW_PARAM_MDIO_CTRL_MASK) >> \ + FW_PARAM_MDIO_CTRL_OFFSET) #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) @@ -121,9 +139,12 @@ struct bnx2x_phy { #define FLAGS_FAN_FAILURE_DET_REQ (1<<2) /* Initialize first the XGXS and only then the phy itself */ #define FLAGS_INIT_XGXS_FIRST (1<<3) +#define FLAGS_WC_DUAL_MODE (1<<4) #define FLAGS_4_PORT_MODE (1<<5) #define FLAGS_REARM_LATCH_SIGNAL (1<<6) #define FLAGS_SFP_NOT_APPROVED (1<<7) +#define FLAGS_MDC_MDIO_WA (1<<8) +#define FLAGS_DUMMY_READ (1<<9) /* preemphasis values for the rx side */ u16 rx_preemphasis[4]; @@ -142,8 +163,8 @@ struct bnx2x_phy { #define ETH_PHY_XFP_FIBER 0x2 #define ETH_PHY_DA_TWINAX 0x3 #define ETH_PHY_BASE_T 0x4 -#define ETH_PHY_KR 0xf0 -#define ETH_PHY_CX4 0xf1 +#define ETH_PHY_KR 0xf0 +#define ETH_PHY_CX4 0xf1 #define ETH_PHY_NOT_PRESENT 0xff /* The address in which version is located*/ @@ -248,6 +269,8 @@ struct link_params { /* Output parameters */ struct link_vars { u8 phy_flags; +#define PHY_XGXS_FLAG (1<<0) +#define PHY_SGMII_FLAG (1<<1) u8 mac_type; #define MAC_TYPE_NONE 0 @@ -414,4 +437,7 @@ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, u32 chip_id, u32 shmem_base, u32 shmem2_base, u8 port); + +int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, + struct link_params *params); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 6237e4aba82..0dddba9532c 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -8586,7 +8586,10 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) return; } break; + case PORT_FEATURE_LINK_SPEED_20G: + bp->link_params.req_line_speed[idx] = SPEED_20000; + break; default: BNX2X_ERR("NVRAM config error. " "BAD link speed link_config 0x%x\n", diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 65f3b126076..23c89a863a5 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -981,6 +981,13 @@ #define IGU_REG_WRITE_DONE_PENDING 0x130480 #define MCP_A_REG_MCPR_SCRATCH 0x3a0000 #define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c +#define MCP_REG_MCPR_GP_INPUTS 0x800c0 +#define MCP_REG_MCPR_GP_OENABLE 0x800c8 +#define MCP_REG_MCPR_GP_OUTPUTS 0x800c4 +#define MCP_REG_MCPR_IMC_COMMAND 0x85900 +#define MCP_REG_MCPR_IMC_DATAREG0 0x85920 +#define MCP_REG_MCPR_IMC_SLAVE_CONTROL 0x85904 +#define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c #define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 #define MCP_REG_MCPR_NVM_ADDR 0x8640c #define MCP_REG_MCPR_NVM_CFG4 0x8642c @@ -1477,11 +1484,37 @@ /* [RW 1] e1hmf for WOL. If clr WOL signal o the PXP will be send on bit 0 only. */ #define MISC_REG_E1HMF_MODE 0xa5f8 +/* [R 1] Status of four port mode path swap input pin. */ +#define MISC_REG_FOUR_PORT_PATH_SWAP 0xa75c +/* [RW 2] 4 port path swap overwrite.[0] - Overwrite control; if it is 0 - + the path_swap output is equal to 4 port mode path swap input pin; if it + is 1 - the path_swap output is equal to bit[1] of this register; [1] - + Overwrite value. If bit[0] of this register is 1 this is the value that + receives the path_swap output. Reset on Hard reset. */ +#define MISC_REG_FOUR_PORT_PATH_SWAP_OVWR 0xa738 +/* [R 1] Status of 4 port mode port swap input pin. */ +#define MISC_REG_FOUR_PORT_PORT_SWAP 0xa754 +/* [RW 2] 4 port port swap overwrite.[0] - Overwrite control; if it is 0 - + the port_swap output is equal to 4 port mode port swap input pin; if it + is 1 - the port_swap output is equal to bit[1] of this register; [1] - + Overwrite value. If bit[0] of this register is 1 this is the value that + receives the port_swap output. Reset on Hard reset. */ +#define MISC_REG_FOUR_PORT_PORT_SWAP_OVWR 0xa734 /* [RW 32] Debug only: spare RW register reset by core reset */ #define MISC_REG_GENERIC_CR_0 0xa460 #define MISC_REG_GENERIC_CR_1 0xa464 /* [RW 32] Debug only: spare RW register reset by por reset */ #define MISC_REG_GENERIC_POR_1 0xa474 +/* [RW 32] Bit[0]: EPIO MODE SEL: Setting this bit to 1 will allow SW/FW to + use all of the 32 Extended GPIO pins. Without setting this bit; an EPIO + can not be configured as an output. Each output has its output enable in + the MCP register space; but this bit needs to be set to make use of that. + Bit[3:1] spare. Bit[4]: WCVTMON_PWRDN: Powerdown for Warpcore VTMON. When + set to 1 - Powerdown. Bit[5]: WCVTMON_RESETB: Reset for Warpcore VTMON. + When set to 0 - vTMON is in reset. Bit[6]: setting this bit will change + the i/o to an output and will drive the TimeSync output. Bit[31:7]: + spare. Global register. Reset by hard reset. */ +#define MISC_REG_GEN_PURP_HWG 0xa9a0 /* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of these bits is written as a '1'; the corresponding SPIO bit will turn off it's drivers and become an input. This is the reset state of all GPIO @@ -1684,6 +1717,14 @@ in this register. address 0 - timer 1; address 1 - timer 2, ... address 7 - timer 8 */ #define MISC_REG_SW_TIMER_VAL 0xa5c0 +/* [R 1] Status of two port mode path swap input pin. */ +#define MISC_REG_TWO_PORT_PATH_SWAP 0xa758 +/* [RW 2] 2 port swap overwrite.[0] - Overwrite control; if it is 0 - the + path_swap output is equal to 2 port mode path swap input pin; if it is 1 + - the path_swap output is equal to bit[1] of this register; [1] - + Overwrite value. If bit[0] of this register is 1 this is the value that + receives the path_swap output. Reset on Hard reset. */ +#define MISC_REG_TWO_PORT_PATH_SWAP_OVWR 0xa72c /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are loaded; 0-prepare; -unprepare */ #define MISC_REG_UNPREPARED 0xa424 @@ -1955,6 +1996,10 @@ /* [RC 32] Parity register #0 read clear */ #define NIG_REG_NIG_PRTY_STS_CLR_0 0x183c0 #define NIG_REG_NIG_PRTY_STS_CLR_1 0x183d0 +#define MCPR_IMC_COMMAND_ENABLE (1L<<31) +#define MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT 16 +#define MCPR_IMC_COMMAND_OPERATION_BITSHIFT 28 +#define MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT 8 /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic * Ethernet header. */ #define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038 @@ -6232,6 +6277,10 @@ #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G 0x0C00 #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX 0x0D00 #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 0x0E00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR 0x0F00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI 0x1B00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS 0x1E00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI 0x1F00 #define MDIO_REG_BANK_10G_PARALLEL_DETECT 0x8130 @@ -6574,6 +6623,120 @@ Theotherbitsarereservedandshouldbezero*/ #define PHY84833_CMD_CLEAR_COMPLETE 0x0080 #define PHY84833_CMD_OPEN_OVERRIDE 0xa5a5 +/* Warpcore clause 45 addressing */ +#define MDIO_WC_DEVAD 0x3 +#define MDIO_WC_REG_IEEE0BLK_MIICNTL 0x0 +#define MDIO_WC_REG_IEEE0BLK_AUTONEGNP 0x7 +#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT0 0x10 +#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1 0x11 +#define MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150 0x96 +#define MDIO_WC_REG_XGXSBLK0_XGXSCONTROL 0x8000 +#define MDIO_WC_REG_XGXSBLK0_MISCCONTROL1 0x800e +#define MDIO_WC_REG_XGXSBLK1_DESKEW 0x8010 +#define MDIO_WC_REG_XGXSBLK1_LANECTRL0 0x8015 +#define MDIO_WC_REG_XGXSBLK1_LANECTRL1 0x8016 +#define MDIO_WC_REG_XGXSBLK1_LANECTRL2 0x8017 +#define MDIO_WC_REG_TX0_ANA_CTRL0 0x8061 +#define MDIO_WC_REG_TX1_ANA_CTRL0 0x8071 +#define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081 +#define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091 +#define MDIO_WC_REG_TX0_TX_DRIVER 0x8067 +#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04 +#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0 +#define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08 +#define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00 +#define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET 0x0c +#define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_MASK 0x7000 +#define MDIO_WC_REG_TX1_TX_DRIVER 0x8077 +#define MDIO_WC_REG_TX2_TX_DRIVER 0x8087 +#define MDIO_WC_REG_TX3_TX_DRIVER 0x8097 +#define MDIO_WC_REG_RX0_ANARXCONTROL1G 0x80b9 +#define MDIO_WC_REG_RX2_ANARXCONTROL1G 0x80d9 +#define MDIO_WC_REG_RX0_PCI_CTRL 0x80ba +#define MDIO_WC_REG_RX1_PCI_CTRL 0x80ca +#define MDIO_WC_REG_RX2_PCI_CTRL 0x80da +#define MDIO_WC_REG_RX3_PCI_CTRL 0x80ea +#define MDIO_WC_REG_XGXSBLK2_UNICORE_MODE_10G 0x8104 +#define MDIO_WC_REG_XGXS_STATUS3 0x8129 +#define MDIO_WC_REG_PAR_DET_10G_STATUS 0x8130 +#define MDIO_WC_REG_PAR_DET_10G_CTRL 0x8131 +#define MDIO_WC_REG_XGXS_X2_CONTROL2 0x8141 +#define MDIO_WC_REG_XGXS_RX_LN_SWAP1 0x816B +#define MDIO_WC_REG_XGXS_TX_LN_SWAP1 0x8169 +#define MDIO_WC_REG_GP2_STATUS_GP_2_0 0x81d0 +#define MDIO_WC_REG_GP2_STATUS_GP_2_1 0x81d1 +#define MDIO_WC_REG_GP2_STATUS_GP_2_2 0x81d2 +#define MDIO_WC_REG_GP2_STATUS_GP_2_3 0x81d3 +#define MDIO_WC_REG_GP2_STATUS_GP_2_4 0x81d4 +#define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP 0x81EE +#define MDIO_WC_REG_UC_INFO_B1_VERSION 0x81F0 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE 0x81F2 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE0_OFFSET 0x0 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT 0x0 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_OPT_LR 0x1 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC 0x2 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_XLAUI 0x3 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_LONG_CH_6G 0x4 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE1_OFFSET 0x4 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE2_OFFSET 0x8 +#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE3_OFFSET 0xc +#define MDIO_WC_REG_UC_INFO_B1_CRC 0x81FE +#define MDIO_WC_REG_DSC_SMC 0x8213 +#define MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0 0x821e +#define MDIO_WC_REG_TX_FIR_TAP 0x82e2 +#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET 0x00 +#define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_MASK 0x000f +#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET 0x04 +#define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_MASK 0x03f0 +#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET 0x0a +#define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_MASK 0x7c00 +#define MDIO_WC_REG_TX_FIR_TAP_ENABLE 0x8000 +#define MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL 0x82e3 +#define MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL 0x82e6 +#define MDIO_WC_REG_CL72_USERB0_CL72_BR_DEF_CTRL 0x82e7 +#define MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL 0x82e8 +#define MDIO_WC_REG_CL72_USERB0_CL72_MISC4_CONTROL 0x82ec +#define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1 0x8300 +#define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2 0x8301 +#define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3 0x8302 +#define MDIO_WC_REG_SERDESDIGITAL_STATUS1000X1 0x8304 +#define MDIO_WC_REG_SERDESDIGITAL_MISC1 0x8308 +#define MDIO_WC_REG_SERDESDIGITAL_MISC2 0x8309 +#define MDIO_WC_REG_DIGITAL3_UP1 0x8329 +#define MDIO_WC_REG_DIGITAL4_MISC3 0x833c +#define MDIO_WC_REG_DIGITAL5_MISC6 0x8345 +#define MDIO_WC_REG_DIGITAL5_MISC7 0x8349 +#define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED 0x834e +#define MDIO_WC_REG_CL49_USERB0_CTRL 0x8368 +#define MDIO_WC_REG_TX66_CONTROL 0x83b0 +#define MDIO_WC_REG_RX66_CONTROL 0x83c0 +#define MDIO_WC_REG_RX66_SCW0 0x83c2 +#define MDIO_WC_REG_RX66_SCW1 0x83c3 +#define MDIO_WC_REG_RX66_SCW2 0x83c4 +#define MDIO_WC_REG_RX66_SCW3 0x83c5 +#define MDIO_WC_REG_RX66_SCW0_MASK 0x83c6 +#define MDIO_WC_REG_RX66_SCW1_MASK 0x83c7 +#define MDIO_WC_REG_RX66_SCW2_MASK 0x83c8 +#define MDIO_WC_REG_RX66_SCW3_MASK 0x83c9 +#define MDIO_WC_REG_FX100_CTRL1 0x8400 +#define MDIO_WC_REG_FX100_CTRL3 0x8402 + +#define MDIO_WC_REG_MICROBLK_CMD 0xffc2 +#define MDIO_WC_REG_MICROBLK_DL_STATUS 0xffc5 +#define MDIO_WC_REG_MICROBLK_CMD3 0xffcc + +#define MDIO_WC_REG_AERBLK_AER 0xffde +#define MDIO_WC_REG_COMBO_IEEE0_MIICTRL 0xffe0 +#define MDIO_WC_REG_COMBO_IEEE0_MIIISTAT 0xffe1 + +#define MDIO_WC0_XGXS_BLK2_LANE_RESET 0x810A +#define MDIO_WC0_XGXS_BLK2_LANE_RESET_RX_BITSHIFT 0 +#define MDIO_WC0_XGXS_BLK2_LANE_RESET_TX_BITSHIFT 4 + +#define MDIO_WC0_XGXS_BLK6_XGXS_X2_CONTROL2 0x8141 + +#define DIGITAL5_ACTUAL_SPEED_TX_MASK 0x003f + #define IGU_FUNC_BASE 0x0400 #define IGU_ADDR_MSIX 0x0000 -- cgit v1.2.3-70-g09d2 From 6583e33baefbe4dea04999ec91be1a1371cd1528 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:34:17 +0000 Subject: bnx2x: Add new PHY 54616s Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 467 ++++++++++++++++++++++++++++++++++++++++- drivers/net/bnx2x/bnx2x_reg.h | 12 ++ 2 files changed, 471 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index b777d2c9633..73938f9201a 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -134,6 +134,9 @@ #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD + + + /* */ #define SFP_EEPROM_CON_TYPE_ADDR 0x2 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 @@ -2059,6 +2062,83 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, } +/******************************************************************/ +/* CL22 access functions */ +/******************************************************************/ +static int bnx2x_cl22_write(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 reg, u16 val) +{ + u32 tmp, mode; + u8 i; + int rc = 0; + /* Switch to CL22 */ + mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, + mode & ~EMAC_MDIO_MODE_CLAUSE_45); + + /* address */ + tmp = ((phy->addr << 21) | (reg << 16) | val | + EMAC_MDIO_COMM_COMMAND_WRITE_22 | + EMAC_MDIO_COMM_START_BUSY); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); + + for (i = 0; i < 50; i++) { + udelay(10); + + tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); + break; + } + } + if (tmp & EMAC_MDIO_COMM_START_BUSY) { + DP(NETIF_MSG_LINK, "write phy register failed\n"); + rc = -EFAULT; + } + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode); + return rc; +} + +static int bnx2x_cl22_read(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 reg, u16 *ret_val) +{ + u32 val, mode; + u16 i; + int rc = 0; + + /* Switch to CL22 */ + mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, + mode & ~EMAC_MDIO_MODE_CLAUSE_45); + + /* address */ + val = ((phy->addr << 21) | (reg << 16) | + EMAC_MDIO_COMM_COMMAND_READ_22 | + EMAC_MDIO_COMM_START_BUSY); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); + + for (i = 0; i < 50; i++) { + udelay(10); + + val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + if (!(val & EMAC_MDIO_COMM_START_BUSY)) { + *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); + udelay(5); + break; + } + } + if (val & EMAC_MDIO_COMM_START_BUSY) { + DP(NETIF_MSG_LINK, "read phy register failed\n"); + + *ret_val = 0; + rc = -EFAULT; + } + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode); + return rc; +} + /******************************************************************/ /* CL45 access functions */ /******************************************************************/ @@ -2649,12 +2729,19 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, vars->flow_ctrl = params->req_fc_auto_adv; else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { ret = 1; - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &ld_pause); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) { + bnx2x_cl22_read(bp, phy, + 0x4, &ld_pause); + bnx2x_cl22_read(bp, phy, + 0x5, &lp_pause); + } else { + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_ADV_PAUSE, &ld_pause); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); + } pause_result = (ld_pause & MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; pause_result |= (lp_pause & @@ -4653,8 +4740,13 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, u16 cnt, ctrl; /* Wait for soft reset to get cleared up to 1 sec */ for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) + bnx2x_cl22_read(bp, phy, + MDIO_PMA_REG_CTRL, &ctrl); + else + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, &ctrl); if (!(ctrl & (1<<15))) break; msleep(1); @@ -8807,6 +8899,329 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, break; } } +/******************************************************************/ +/* 54616S PHY SECTION */ +/******************************************************************/ +static int bnx2x_54616s_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 port; + u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp; + u32 cfg_pin; + + DP(NETIF_MSG_LINK, "54616S cfg init\n"); + usleep_range(1000, 1000); + + /* This works with E3 only, no need to check the chip + before determining the port. */ + port = params->port; + + cfg_pin = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_cmn_pin_cfg)) & + PORT_HW_CFG_E3_PHY_RESET_MASK) >> + PORT_HW_CFG_E3_PHY_RESET_SHIFT; + + /* Drive pin high to bring the GPHY out of reset. */ + bnx2x_set_cfg_pin(bp, cfg_pin, 1); + + /* wait for GPHY to reset */ + msleep(50); + + /* reset phy */ + bnx2x_cl22_write(bp, phy, + MDIO_PMA_REG_CTRL, 0x8000); + bnx2x_wait_reset_complete(bp, phy, params); + + /*wait for GPHY to reset */ + msleep(50); + + /* Configure LED4: set to INTR (0x6). */ + /* Accessing shadow register 0xe. */ + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_SHADOW, + MDIO_REG_GPHY_SHADOW_LED_SEL2); + bnx2x_cl22_read(bp, phy, + MDIO_REG_GPHY_SHADOW, + &temp); + temp &= ~(0xf << 4); + temp |= (0x6 << 4); + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_SHADOW, + MDIO_REG_GPHY_SHADOW_WR_ENA | temp); + /* Configure INTR based on link status change. */ + bnx2x_cl22_write(bp, phy, + MDIO_REG_INTR_MASK, + ~MDIO_REG_INTR_MASK_LINK_STATUS); + + /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */ + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_SHADOW, + MDIO_REG_GPHY_SHADOW_AUTO_DET_MED); + bnx2x_cl22_read(bp, phy, + MDIO_REG_GPHY_SHADOW, + &temp); + temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD; + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_SHADOW, + MDIO_REG_GPHY_SHADOW_WR_ENA | temp); + + /* Set up fc */ + /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + fc_val = 0; + if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) + fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; + + if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) + fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; + + /* read all advertisement */ + bnx2x_cl22_read(bp, phy, + 0x09, + &an_1000_val); + + bnx2x_cl22_read(bp, phy, + 0x04, + &an_10_100_val); + + bnx2x_cl22_read(bp, phy, + MDIO_PMA_REG_CTRL, + &autoneg_val); + + /* Disable forced speed */ + autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); + an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) | + (1<<11)); + + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || + (phy->req_line_speed == SPEED_1000)) { + an_1000_val |= (1<<8); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_1000_val |= (1<<9); + DP(NETIF_MSG_LINK, "Advertising 1G\n"); + } else + an_1000_val &= ~((1<<8) | (1<<9)); + + bnx2x_cl22_write(bp, phy, + 0x09, + an_1000_val); + bnx2x_cl22_read(bp, phy, + 0x09, + &an_1000_val); + + /* set 100 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { + an_10_100_val |= (1<<7); + /* Enable autoneg and restart autoneg for legacy speeds */ + autoneg_val |= (1<<9 | 1<<12); + + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<8); + DP(NETIF_MSG_LINK, "Advertising 100M\n"); + } + + /* set 10 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { + an_10_100_val |= (1<<5); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<6); + DP(NETIF_MSG_LINK, "Advertising 10M\n"); + } + + /* Only 10/100 are allowed to work in FORCE mode */ + if (phy->req_line_speed == SPEED_100) { + autoneg_val |= (1<<13); + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl22_write(bp, phy, + 0x18, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 100M force\n"); + } + if (phy->req_line_speed == SPEED_10) { + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl22_write(bp, phy, + 0x18, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 10M force\n"); + } + + bnx2x_cl22_write(bp, phy, + 0x04, + an_10_100_val | fc_val); + + if (phy->req_duplex == DUPLEX_FULL) + autoneg_val |= (1<<8); + + bnx2x_cl22_write(bp, phy, + MDIO_PMA_REG_CTRL, autoneg_val); + + return 0; +} + +static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "54616S set link led (mode=%x)\n", mode); + switch (mode) { + case LED_MODE_FRONT_PANEL_OFF: + case LED_MODE_OFF: + case LED_MODE_OPER: + case LED_MODE_ON: + default: + break; + } + return; +} + +static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u32 cfg_pin; + u8 port; + + /* This works with E3 only, no need to check the chip + before determining the port. */ + port = params->port; + cfg_pin = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_cmn_pin_cfg)) & + PORT_HW_CFG_E3_PHY_RESET_MASK) >> + PORT_HW_CFG_E3_PHY_RESET_SHIFT; + + /* Drive pin low to put GPHY in reset. */ + bnx2x_set_cfg_pin(bp, cfg_pin, 0); +} + +static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val; + u8 link_up = 0; + u16 legacy_status, legacy_speed; + + /* Get speed operation status */ + bnx2x_cl22_read(bp, phy, + 0x19, + &legacy_status); + DP(NETIF_MSG_LINK, "54616S read_status: 0x%x\n", legacy_status); + + /* Read status to clear the PHY interrupt. */ + bnx2x_cl22_read(bp, phy, + MDIO_REG_INTR_STATUS, + &val); + + link_up = ((legacy_status & (1<<2)) == (1<<2)); + + if (link_up) { + legacy_speed = (legacy_status & (7<<8)); + if (legacy_speed == (7<<8)) { + vars->line_speed = SPEED_1000; + vars->duplex = DUPLEX_FULL; + } else if (legacy_speed == (6<<8)) { + vars->line_speed = SPEED_1000; + vars->duplex = DUPLEX_HALF; + } else if (legacy_speed == (5<<8)) { + vars->line_speed = SPEED_100; + vars->duplex = DUPLEX_FULL; + } + /* Omitting 100Base-T4 for now */ + else if (legacy_speed == (3<<8)) { + vars->line_speed = SPEED_100; + vars->duplex = DUPLEX_HALF; + } else if (legacy_speed == (2<<8)) { + vars->line_speed = SPEED_10; + vars->duplex = DUPLEX_FULL; + } else if (legacy_speed == (1<<8)) { + vars->line_speed = SPEED_10; + vars->duplex = DUPLEX_HALF; + } else /* Should not happen */ + vars->line_speed = 0; + + DP(NETIF_MSG_LINK, "Link is up in %dMbps," + " is_duplex_full= %d\n", vars->line_speed, + (vars->duplex == DUPLEX_FULL)); + + /* Check legacy speed AN resolution */ + bnx2x_cl22_read(bp, phy, + 0x01, + &val); + if (val & (1<<5)) + vars->link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + bnx2x_cl22_read(bp, phy, + 0x06, + &val); + if ((val & (1<<0)) == 0) + vars->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; + + DP(NETIF_MSG_LINK, "BCM54616S: link speed is %d\n", + vars->line_speed); + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + return link_up; +} + +static void bnx2x_54616s_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u16 val; + u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; + + DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54616s\n"); + + /* Enable master/slave manual mmode and set to master */ + /* mii write 9 [bits set 11 12] */ + bnx2x_cl22_write(bp, phy, 0x09, 3<<11); + + /* forced 1G and disable autoneg */ + /* set val [mii read 0] */ + /* set val [expr $val & [bits clear 6 12 13]] */ + /* set val [expr $val | [bits set 6 8]] */ + /* mii write 0 $val */ + bnx2x_cl22_read(bp, phy, 0x00, &val); + val &= ~((1<<6) | (1<<12) | (1<<13)); + val |= (1<<6) | (1<<8); + bnx2x_cl22_write(bp, phy, 0x00, val); + + /* Set external loopback and Tx using 6dB coding */ + /* mii write 0x18 7 */ + /* set val [mii read 0x18] */ + /* mii write 0x18 [expr $val | [bits set 10 15]] */ + bnx2x_cl22_write(bp, phy, 0x18, 7); + bnx2x_cl22_read(bp, phy, 0x18, &val); + bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15)); + + /* This register opens the gate for the UMAC despite its name */ + REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1); + + /* + * Maximum Frame Length (RW). Defines a 14-Bit maximum frame + * length used by the MAC receive logic to check frames. + */ + REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710); +} + /******************************************************************/ /* SFX7101 PHY SECTION */ /******************************************************************/ @@ -9390,6 +9805,39 @@ static struct bnx2x_phy phy_84833 = { .phy_specific_func = (phy_specific_func_t)NULL }; +static struct bnx2x_phy phy_54616s = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616, + .addr = 0xff, + .def_md_devad = 0, + .flags = FLAGS_INIT_XGXS_FIRST, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + /* req_duplex = */0, + /* rsrv = */0, + .config_init = (config_init_t)bnx2x_54616s_config_init, + .read_status = (read_status_t)bnx2x_54616s_read_status, + .link_reset = (link_reset_t)bnx2x_54616s_link_reset, + .config_loopback = (config_loopback_t)bnx2x_54616s_config_loopback, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)bnx2x_54616s_set_link_led, + .phy_specific_func = (phy_specific_func_t)NULL +}; /*****************************************************************/ /* */ /* Populate the phy according. Main function: bnx2x_populate_phy */ @@ -9630,6 +10078,9 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: *phy = phy_84833; break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616: + *phy = phy_54616s; + break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: *phy = phy_7101; break; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 23c89a863a5..bf43b9b16d8 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5420,7 +5420,9 @@ #define EMAC_LED_OVERRIDE (1L<<0) #define EMAC_LED_TRAFFIC (1L<<6) #define EMAC_MDIO_COMM_COMMAND_ADDRESS (0L<<26) +#define EMAC_MDIO_COMM_COMMAND_READ_22 (2L<<26) #define EMAC_MDIO_COMM_COMMAND_READ_45 (3L<<26) +#define EMAC_MDIO_COMM_COMMAND_WRITE_22 (1L<<26) #define EMAC_MDIO_COMM_COMMAND_WRITE_45 (1L<<26) #define EMAC_MDIO_COMM_DATA (0xffffL<<0) #define EMAC_MDIO_COMM_START_BUSY (1L<<29) @@ -6737,6 +6739,16 @@ Theotherbitsarereservedandshouldbezero*/ #define DIGITAL5_ACTUAL_SPEED_TX_MASK 0x003f +/* 54616s */ +#define MDIO_REG_INTR_STATUS 0x1a +#define MDIO_REG_INTR_MASK 0x1b +#define MDIO_REG_INTR_MASK_LINK_STATUS (0x1 << 1) +#define MDIO_REG_GPHY_SHADOW 0x1c +#define MDIO_REG_GPHY_SHADOW_LED_SEL2 (0x0e << 10) +#define MDIO_REG_GPHY_SHADOW_WR_ENA (0x1 << 15) +#define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED (0x1e << 10) +#define MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD (0x1 << 8) + #define IGU_FUNC_BASE 0x0400 #define IGU_ADDR_MSIX 0x0000 -- cgit v1.2.3-70-g09d2 From 6c3218c6f7e5be6d785486797d48203d54cfd893 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:34:23 +0000 Subject: bnx2x: Adjust ETS to 578xx Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_dcb.c | 2 +- drivers/net/bnx2x/bnx2x_link.c | 753 ++++++++++++++++++++++++++++++++++++++++- drivers/net/bnx2x/bnx2x_link.h | 40 ++- drivers/net/bnx2x/bnx2x_reg.h | 172 ++++++++++ 4 files changed, 963 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index aaed9f09c32..50a5c4f3d58 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -424,7 +424,7 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets); u8 status = 0; - bnx2x_ets_disabled(&bp->link_params/*, &bp->link_vars*/); + bnx2x_ets_disabled(&bp->link_params, &bp->link_vars); if (!ets->enabled) return; diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 73938f9201a..a5c34880b39 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -337,12 +337,12 @@ static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val) /******************************************************************/ /* ETS section */ /******************************************************************/ -void bnx2x_ets_disabled(struct link_params *params) +static void bnx2x_ets_e2e3a0_disabled(struct link_params *params) { /* ETS disabled configuration*/ struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "ETS disabled configuration\n"); + DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n"); /* * mapping between entry priority to client number (0,1,2 -debug and @@ -395,7 +395,756 @@ void bnx2x_ets_disabled(struct link_params *params) /* Defines the number of consecutive slots for the strict priority */ REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); } +/****************************************************************************** +* Description: +* Getting min_w_val will be set according to line speed . +*. +******************************************************************************/ +static u32 bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars) +{ + u32 min_w_val = 0; + /* Calculate min_w_val.*/ + if (vars->link_up) { + if (SPEED_20000 == vars->line_speed) + min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS; + else + min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS; + } else + min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS; + /** + * If the link isn't up (static configuration for example ) The + * link will be according to 20GBPS. + */ + return min_w_val; +} +/****************************************************************************** +* Description: +* Getting credit upper bound form min_w_val. +*. +******************************************************************************/ +static u32 bnx2x_ets_get_credit_upper_bound(const u32 min_w_val) +{ + const u32 credit_upper_bound = (u32)MAXVAL((150 * min_w_val), + MAX_PACKET_SIZE); + return credit_upper_bound; +} +/****************************************************************************** +* Description: +* Set credit upper bound for NIG. +*. +******************************************************************************/ +static void bnx2x_ets_e3b0_set_credit_upper_bound_nig( + const struct link_params *params, + const u32 min_w_val) +{ + struct bnx2x *bp = params->bp; + const u8 port = params->port; + const u32 credit_upper_bound = + bnx2x_ets_get_credit_upper_bound(min_w_val); + + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 : + NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 : + NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 : + NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 : + NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 : + NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 : + NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound); + + if (0 == port) { + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6, + credit_upper_bound); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7, + credit_upper_bound); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8, + credit_upper_bound); + } +} +/****************************************************************************** +* Description: +* Will return the NIG ETS registers to init values.Except +* credit_upper_bound. +* That isn't used in this configuration (No WFQ is enabled) and will be +* configured acording to spec +*. +******************************************************************************/ +static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params, + const struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + const u8 port = params->port; + const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars); + /** + * mapping between entry priority to client number (0,1,2 -debug and + * management clients, 3 - COS0 client, 4 - COS1, ... 8 - + * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by + * reset value or init tool + */ + if (port) { + REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210); + REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0); + } else { + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210); + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8); + } + /** + * For strict priority entries defines the number of consecutive + * slots for the highest priority. + */ + /* TODO_ETS - Should be done by reset value or init tool */ + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS : + NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); + /** + * mapping between the CREDIT_WEIGHT registers and actual client + * numbers + */ + /* TODO_ETS - Should be done by reset value or init tool */ + if (port) { + /*Port 1 has 6 COS*/ + REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543); + REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0); + } else { + /*Port 0 has 9 COS*/ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB, + 0x43210876); + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5); + } + + /** + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, 3 - + * COS0 entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ + if (port) + REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f); + else + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff); + /* defines which entries (clients) are subjected to WFQ arbitration */ + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ : + NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0); + + /** + * Please notice the register address are note continuous and a + * for here is note appropriate.In 2 port mode port0 only COS0-5 + * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4 + * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT + * are never used for WFQ + */ + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0); + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0); + if (0 == port) { + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0); + } + + bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val); +} +/****************************************************************************** +* Description: +* Set credit upper bound for PBF. +*. +******************************************************************************/ +static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf( + const struct link_params *params, + const u32 min_w_val) +{ + struct bnx2x *bp = params->bp; + const u32 credit_upper_bound = + bnx2x_ets_get_credit_upper_bound(min_w_val); + const u8 port = params->port; + u32 base_upper_bound = 0; + u8 max_cos = 0; + u8 i = 0; + /** + * In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4 + * port mode port1 has COS0-2 that can be used for WFQ. + */ + if (0 == port) { + base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0; + max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0; + } else { + base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1; + max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1; + } + + for (i = 0; i < max_cos; i++) + REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound); +} +/****************************************************************************** +* Description: +* Will return the PBF ETS registers to init values.Except +* credit_upper_bound. +* That isn't used in this configuration (No WFQ is enabled) and will be +* configured acording to spec +*. +******************************************************************************/ +static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params) +{ + struct bnx2x *bp = params->bp; + const u8 port = params->port; + const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL; + u8 i = 0; + u32 base_weight = 0; + u8 max_cos = 0; + + /** + * mapping between entry priority to client number 0 - COS0 + * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num. + * TODO_ETS - Should be done by reset value or init tool + */ + if (port) + /* 0x688 (|011|0 10|00 1|000) */ + REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688); + else + /* (10 1|100 |011|0 10|00 1|000) */ + REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688); + + /* TODO_ETS - Should be done by reset value or init tool */ + if (port) + /* 0x688 (|011|0 10|00 1|000)*/ + REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688); + else + /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */ + REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688); + + REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 : + PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100); + + + REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 : + PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0); + + REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 : + PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0); + /** + * In 2 port mode port0 has COS0-5 that can be used for WFQ. + * In 4 port mode port1 has COS0-2 that can be used for WFQ. + */ + if (0 == port) { + base_weight = PBF_REG_COS0_WEIGHT_P0; + max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0; + } else { + base_weight = PBF_REG_COS0_WEIGHT_P1; + max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1; + } + + for (i = 0; i < max_cos; i++) + REG_WR(bp, base_weight + (0x4 * i), 0); + + bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf); +} +/****************************************************************************** +* Description: +* E3B0 disable will return basicly the values to init values. +*. +******************************************************************************/ +static int bnx2x_ets_e3b0_disabled(const struct link_params *params, + const struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + + if (!CHIP_IS_E3B0(bp)) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_disabled the chip isn't E3B0" + "\n"); + return -EINVAL; + } + + bnx2x_ets_e3b0_nig_disabled(params, vars); + + bnx2x_ets_e3b0_pbf_disabled(params); + + return 0; +} + +/****************************************************************************** +* Description: +* Disable will return basicly the values to init values. +*. +******************************************************************************/ +int bnx2x_ets_disabled(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + int bnx2x_status = 0; + + if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp))) + bnx2x_ets_e2e3a0_disabled(params); + else if (CHIP_IS_E3B0(bp)) + bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars); + else { + DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n"); + return -EINVAL; + } + + return bnx2x_status; +} + +/****************************************************************************** +* Description +* Set the COS mappimg to SP and BW until this point all the COS are not +* set as SP or BW. +******************************************************************************/ +static int bnx2x_ets_e3b0_cli_map(const struct link_params *params, + const struct bnx2x_ets_params *ets_params, + const u8 cos_sp_bitmap, + const u8 cos_bw_bitmap) +{ + struct bnx2x *bp = params->bp; + const u8 port = params->port; + const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3); + const u8 pbf_cli_sp_bitmap = cos_sp_bitmap; + const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3; + const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap; + + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT : + NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap); + + REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 : + PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap); + + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ : + NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, + nig_cli_subject2wfq_bitmap); + + REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 : + PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0, + pbf_cli_subject2wfq_bitmap); + + return 0; +} + +/****************************************************************************** +* Description: +* This function is needed because NIG ARB_CREDIT_WEIGHT_X are +* not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable. +******************************************************************************/ +static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp, + const u8 cos_entry, + const u32 min_w_val_nig, + const u32 min_w_val_pbf, + const u16 total_bw, + const u8 bw, + const u8 port) +{ + u32 nig_reg_adress_crd_weight = 0; + u32 pbf_reg_adress_crd_weight = 0; + /* Calculate and set BW for this COS*/ + const u32 cos_bw_nig = (bw * min_w_val_nig) / total_bw; + const u32 cos_bw_pbf = (bw * min_w_val_pbf) / total_bw; + + switch (cos_entry) { + case 0: + nig_reg_adress_crd_weight = + (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0; + pbf_reg_adress_crd_weight = (port) ? + PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0; + break; + case 1: + nig_reg_adress_crd_weight = (port) ? + NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1; + pbf_reg_adress_crd_weight = (port) ? + PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0; + break; + case 2: + nig_reg_adress_crd_weight = (port) ? + NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 : + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2; + + pbf_reg_adress_crd_weight = (port) ? + PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0; + break; + case 3: + if (port) + return -EINVAL; + nig_reg_adress_crd_weight = + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3; + pbf_reg_adress_crd_weight = + PBF_REG_COS3_WEIGHT_P0; + break; + case 4: + if (port) + return -EINVAL; + nig_reg_adress_crd_weight = + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4; + pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0; + break; + case 5: + if (port) + return -EINVAL; + nig_reg_adress_crd_weight = + NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5; + pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0; + break; + } + + REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig); + + REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf); + + return 0; +} +/****************************************************************************** +* Description: +* Calculate the total BW.A value of 0 isn't legal. +*. +******************************************************************************/ +static int bnx2x_ets_e3b0_get_total_bw( + const struct link_params *params, + const struct bnx2x_ets_params *ets_params, + u16 *total_bw) +{ + struct bnx2x *bp = params->bp; + u8 cos_idx = 0; + + *total_bw = 0 ; + /* Calculate total BW requested */ + for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) { + if (bnx2x_cos_state_bw == ets_params->cos[cos_idx].state) { + + if (0 == ets_params->cos[cos_idx].params.bw_params.bw) { + DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW" + "was set to 0\n"); + return -EINVAL; + } + *total_bw += + ets_params->cos[cos_idx].params.bw_params.bw; + } + } + + /*Check taotl BW is valid */ + if ((100 != *total_bw) || (0 == *total_bw)) { + if (0 == *total_bw) { + DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config toatl BW" + "shouldn't be 0\n"); + return -EINVAL; + } + DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config toatl BW should be" + "100\n"); + /** + * We can handle a case whre the BW isn't 100 this can happen + * if the TC are joined. + */ + } + return 0; +} + +/****************************************************************************** +* Description: +* Invalidate all the sp_pri_to_cos. +*. +******************************************************************************/ +static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos) +{ + u8 pri = 0; + for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++) + sp_pri_to_cos[pri] = DCBX_INVALID_COS; +} +/****************************************************************************** +* Description: +* Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers +* according to sp_pri_to_cos. +*. +******************************************************************************/ +static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, + u8 *sp_pri_to_cos, const u8 pri, + const u8 cos_entry) +{ + struct bnx2x *bp = params->bp; + const u8 port = params->port; + const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : + DCBX_E3B0_MAX_NUM_COS_PORT0; + + if (DCBX_INVALID_COS != sp_pri_to_cos[pri]) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " + "parameter There can't be two COS's with" + "the same strict pri\n"); + return -EINVAL; + } + + if (pri > max_num_of_cos) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid" + "parameter Illegal strict priority\n"); + return -EINVAL; + } + + sp_pri_to_cos[pri] = cos_entry; + return 0; + +} + +/****************************************************************************** +* Description: +* Returns the correct value according to COS and priority in +* the sp_pri_cli register. +*. +******************************************************************************/ +static u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset, + const u8 pri_set, + const u8 pri_offset, + const u8 entry_size) +{ + u64 pri_cli_nig = 0; + pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size * + (pri_set + pri_offset)); + + return pri_cli_nig; +} +/****************************************************************************** +* Description: +* Returns the correct value according to COS and priority in the +* sp_pri_cli register for NIG. +*. +******************************************************************************/ +static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set) +{ + /* MCP Dbg0 and dbg1 are always with higher strict pri*/ + const u8 nig_cos_offset = 3; + const u8 nig_pri_offset = 3; + + return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set, + nig_pri_offset, 4); + +} +/****************************************************************************** +* Description: +* Returns the correct value according to COS and priority in the +* sp_pri_cli register for PBF. +*. +******************************************************************************/ +static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set) +{ + const u8 pbf_cos_offset = 0; + const u8 pbf_pri_offset = 0; + + return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set, + pbf_pri_offset, 3); + +} + +/****************************************************************************** +* Description: +* Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers +* according to sp_pri_to_cos.(which COS has higher priority) +*. +******************************************************************************/ +static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params, + u8 *sp_pri_to_cos) +{ + struct bnx2x *bp = params->bp; + u8 i = 0; + const u8 port = params->port; + /* MCP Dbg0 and dbg1 are always with higher strict pri*/ + u64 pri_cli_nig = 0x210; + u32 pri_cli_pbf = 0x0; + u8 pri_set = 0; + u8 pri_bitmask = 0; + const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : + DCBX_E3B0_MAX_NUM_COS_PORT0; + + u8 cos_bit_to_set = (1 << max_num_of_cos) - 1; + + /* Set all the strict priority first */ + for (i = 0; i < max_num_of_cos; i++) { + if (DCBX_INVALID_COS != sp_pri_to_cos[i]) { + if (DCBX_MAX_NUM_COS <= sp_pri_to_cos[i]) { + DP(NETIF_MSG_LINK, + "bnx2x_ets_e3b0_sp_set_pri_cli_reg " + "invalid cos entry\n"); + return -EINVAL; + } + + pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig( + sp_pri_to_cos[i], pri_set); + + pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf( + sp_pri_to_cos[i], pri_set); + pri_bitmask = 1 << sp_pri_to_cos[i]; + /* COS is used remove it from bitmap.*/ + if (0 == (pri_bitmask & cos_bit_to_set)) { + DP(NETIF_MSG_LINK, + "bnx2x_ets_e3b0_sp_set_pri_cli_reg " + "invalid There can't be two COS's with" + " the same strict pri\n"); + return -EINVAL; + } + cos_bit_to_set &= ~pri_bitmask; + pri_set++; + } + } + + /* Set all the Non strict priority i= COS*/ + for (i = 0; i < max_num_of_cos; i++) { + pri_bitmask = 1 << i; + /* Check if COS was already used for SP */ + if (pri_bitmask & cos_bit_to_set) { + /* COS wasn't used for SP */ + pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig( + i, pri_set); + + pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf( + i, pri_set); + /* COS is used remove it from bitmap.*/ + cos_bit_to_set &= ~pri_bitmask; + pri_set++; + } + } + + if (pri_set != max_num_of_cos) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all " + "entries were set\n"); + return -EINVAL; + } + + if (port) { + /* Only 6 usable clients*/ + REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, + (u32)pri_cli_nig); + + REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf); + } else { + /* Only 9 usable clients*/ + const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig); + const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF); + + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, + pri_cli_nig_lsb); + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, + pri_cli_nig_msb); + + REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf); + } + return 0; +} + +/****************************************************************************** +* Description: +* Configure the COS to ETS according to BW and SP settings. +******************************************************************************/ +int bnx2x_ets_e3b0_config(const struct link_params *params, + const struct link_vars *vars, + const struct bnx2x_ets_params *ets_params) +{ + struct bnx2x *bp = params->bp; + int bnx2x_status = 0; + const u8 port = params->port; + u16 total_bw = 0; + const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars); + const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL; + u8 cos_bw_bitmap = 0; + u8 cos_sp_bitmap = 0; + u8 sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0}; + const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : + DCBX_E3B0_MAX_NUM_COS_PORT0; + u8 cos_entry = 0; + + if (!CHIP_IS_E3B0(bp)) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_disabled the chip isn't E3B0" + "\n"); + return -EINVAL; + } + + if ((ets_params->num_of_cos > max_num_of_cos)) { + DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS " + "isn't supported\n"); + return -EINVAL; + } + + /* Prepare sp strict priority parameters*/ + bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos); + + /* Prepare BW parameters*/ + bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params, + &total_bw); + if (0 != bnx2x_status) { + DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config get_total_bw failed " + "\n"); + return -EINVAL; + } + + /** + * Upper bound is set according to current link speed (min_w_val + * should be the same for upper bound and COS credit val). + */ + bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig); + bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf); + + + for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) { + if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) { + cos_bw_bitmap |= (1 << cos_entry); + /** + * The function also sets the BW in HW(not the mappin + * yet) + */ + bnx2x_status = bnx2x_ets_e3b0_set_cos_bw( + bp, cos_entry, min_w_val_nig, min_w_val_pbf, + total_bw, + ets_params->cos[cos_entry].params.bw_params.bw, + port); + } else if (bnx2x_cos_state_strict == + ets_params->cos[cos_entry].state){ + cos_sp_bitmap |= (1 << cos_entry); + + bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set( + params, + sp_pri_to_cos, + ets_params->cos[cos_entry].params.sp_params.pri, + cos_entry); + + } else { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_config cos state not" + " valid\n"); + return -EINVAL; + } + if (0 != bnx2x_status) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_config set cos bw " + "failed\n"); + return bnx2x_status; + } + } + + /* Set SP register (which COS has higher priority) */ + bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params, + sp_pri_to_cos); + + if (0 != bnx2x_status) { + DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config set_pri_cli_reg " + "failed\n"); + return bnx2x_status; + } + + /* Set client mapping of BW and strict */ + bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params, + cos_sp_bitmap, + cos_bw_bitmap); + + if (0 != bnx2x_status) { + DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n"); + return bnx2x_status; + } + return 0; +} static void bnx2x_ets_bw_limit_common(const struct link_params *params) { /* ETS disabled configuration */ diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 82bc021bdf0..3d9c46bb108 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -411,6 +411,38 @@ struct bnx2x_nig_brb_pfc_port_params { u32 cos1_pauseable; }; + +/* ETS port configuration params */ +struct bnx2x_ets_bw_params { + u8 bw; +}; + +struct bnx2x_ets_sp_params { + /** + * valid values are 0 - 5. 0 is highest strict priority. + * There can't be two COS's with the same pri. + */ + u8 pri; +}; + +enum bnx2x_cos_state { + bnx2x_cos_state_strict = 0, + bnx2x_cos_state_bw = 1, +}; + +struct bnx2x_ets_cos_params { + enum bnx2x_cos_state state ; + union { + struct bnx2x_ets_bw_params bw_params; + struct bnx2x_ets_sp_params sp_params; + } params; +}; + +struct bnx2x_ets_params { + u8 num_of_cos; /* Number of valid COS entries*/ + struct bnx2x_ets_cos_params cos[DCBX_MAX_NUM_COS]; +}; + /** * Used to update the PFC attributes in EMAC, BMAC, NIG and BRB * when link is already up @@ -421,7 +453,8 @@ int bnx2x_update_pfc(struct link_params *params, /* Used to configure the ETS to disable */ -void bnx2x_ets_disabled(struct link_params *params); +int bnx2x_ets_disabled(struct link_params *params, + struct link_vars *vars); /* Used to configure the ETS to BW limited */ void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, @@ -430,6 +463,11 @@ void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, /* Used to configure the ETS to strict */ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); + +/* Configure the COS to ETS according to BW and SP settings.*/ +int bnx2x_ets_e3b0_config(const struct link_params *params, + const struct link_vars *vars, + const struct bnx2x_ets_params *ets_params); /* Read pfc statistic*/ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, u32 pfc_frames_sent[2], diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index bf43b9b16d8..d0cf072d21e 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -2057,6 +2057,26 @@ * clients that are not subject to WFQ credit blocking - their * specifications here are not used. */ #define NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP 0x180f0 +/* [RW 32] Specify which of the credit registers the client is to be mapped + * to. This register specifies bits 31:0 of the 36-bit value. Bits[3:0] are + * for client 0; bits [35:32] are for client 8. For clients that are not + * subject to WFQ credit blocking - their specifications here are not used. + * This is a new register (with 2_) added in E3 B0 to accommodate the 9 + * input clients to ETS arbiter. The reset default is set for management and + * debug to use credit registers 6, 7, and 8, respectively, and COSes 0-5 to + * use credit registers 0-5 respectively (0x543210876). Note that credit + * registers can not be shared between clients. */ +#define NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB 0x18688 +/* [RW 4] Specify which of the credit registers the client is to be mapped + * to. This register specifies bits 35:32 of the 36-bit value. Bits[3:0] are + * for client 0; bits [35:32] are for client 8. For clients that are not + * subject to WFQ credit blocking - their specifications here are not used. + * This is a new register (with 2_) added in E3 B0 to accommodate the 9 + * input clients to ETS arbiter. The reset default is set for management and + * debug to use credit registers 6, 7, and 8, respectively, and COSes 0-5 to + * use credit registers 0-5 respectively (0x543210876). Note that credit + * registers can not be shared between clients. */ +#define NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB 0x1868c /* [RW 5] Specify whether the client competes directly in the strict * priority arbiter. The bits are mapped according to client ID (client IDs * are defined in tx_arb_priority_client). Default value is set to enable @@ -2071,10 +2091,24 @@ * reach. */ #define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0 0x1810c #define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1 0x18110 +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2 0x18114 +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3 0x18118 +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4 0x1811c +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5 0x186a0 +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6 0x186a4 +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7 0x186a8 +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8 0x186ac /* [RW 32] Specify the weight (in bytes) to be added to credit register 0 * when it is time to increment. */ #define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0 0x180f8 #define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1 0x180fc +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2 0x18100 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3 0x18104 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4 0x18108 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5 0x18690 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6 0x18694 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7 0x18698 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8 0x1869c /* [RW 12] Specify the number of strict priority arbitration slots between * two round-robin arbitration slots to avoid starvation. A value of 0 means * no strict priority cycles - the strict priority with anti-starvation @@ -2094,6 +2128,26 @@ #define NIG_REG_P1_HDRS_AFTER_BASIC 0x1818c #define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 #define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460 +/* [RW 32] Specify the client number to be assigned to each priority of the + * strict priority arbiter. This register specifies bits 31:0 of the 36-bit + * value. Priority 0 is the highest priority. Bits [3:0] are for priority 0 + * client; bits [35-32] are for priority 8 client. The clients are assigned + * the following IDs: 0-management; 1-debug traffic from this port; 2-debug + * traffic from other port; 3-COS0 traffic; 4-COS1 traffic; 5-COS2 traffic; + * 6-COS3 traffic; 7-COS4 traffic; 8-COS5 traffic. The reset value[35:0] is + * set to 0x345678021. This is a new register (with 2_) added in E3 B0 to + * accommodate the 9 input clients to ETS arbiter. */ +#define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB 0x18680 +/* [RW 4] Specify the client number to be assigned to each priority of the + * strict priority arbiter. This register specifies bits 35:32 of the 36-bit + * value. Priority 0 is the highest priority. Bits [3:0] are for priority 0 + * client; bits [35-32] are for priority 8 client. The clients are assigned + * the following IDs: 0-management; 1-debug traffic from this port; 2-debug + * traffic from other port; 3-COS0 traffic; 4-COS1 traffic; 5-COS2 traffic; + * 6-COS3 traffic; 7-COS4 traffic; 8-COS5 traffic. The reset value[35:0] is + * set to 0x345678021. This is a new register (with 2_) added in E3 B0 to + * accommodate the 9 input clients to ETS arbiter. */ +#define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB 0x18684 #define NIG_REG_P1_MAC_IN_EN 0x185c0 /* [RW 1] Output enable for TX MAC interface */ #define NIG_REG_P1_MAC_OUT_EN 0x185c4 @@ -2164,6 +2218,54 @@ * traffic; 6-COS3 traffic; 7-COS4 traffic; 8-COS5 traffic. Default value is * 0 for not using WFQ credit blocking. */ #define NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ 0x18238 +#define NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 0x18258 +#define NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 0x1825c +#define NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 0x18260 +#define NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 0x18264 +#define NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 0x18268 +#define NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 0x186f4 +/* [RW 32] Specify the weight (in bytes) to be added to credit register 0 + * when it is time to increment. */ +#define NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 0x18244 +#define NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 0x18248 +#define NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 0x1824c +#define NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 0x18250 +#define NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 0x18254 +#define NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 0x186f0 +/* [RW 12] Specify the number of strict priority arbitration slots between + two round-robin arbitration slots to avoid starvation. A value of 0 means + no strict priority cycles - the strict priority with anti-starvation + arbiter becomes a round-robin arbiter. */ +#define NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS 0x18240 +/* [RW 32] Specify the client number to be assigned to each priority of the + strict priority arbiter. This register specifies bits 31:0 of the 36-bit + value. Priority 0 is the highest priority. Bits [3:0] are for priority 0 + client; bits [35-32] are for priority 8 client. The clients are assigned + the following IDs: 0-management; 1-debug traffic from this port; 2-debug + traffic from other port; 3-COS0 traffic; 4-COS1 traffic; 5-COS2 traffic; + 6-COS3 traffic; 7-COS4 traffic; 8-COS5 traffic. The reset value[35:0] is + set to 0x345678021. This is a new register (with 2_) added in E3 B0 to + accommodate the 9 input clients to ETS arbiter. Note that this register + is the same as the one for port 0, except that port 1 only has COS 0-2 + traffic. There is no traffic for COS 3-5 of port 1. */ +#define NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB 0x186e0 +/* [RW 4] Specify the client number to be assigned to each priority of the + strict priority arbiter. This register specifies bits 35:32 of the 36-bit + value. Priority 0 is the highest priority. Bits [3:0] are for priority 0 + client; bits [35-32] are for priority 8 client. The clients are assigned + the following IDs: 0-management; 1-debug traffic from this port; 2-debug + traffic from other port; 3-COS0 traffic; 4-COS1 traffic; 5-COS2 traffic; + 6-COS3 traffic; 7-COS4 traffic; 8-COS5 traffic. The reset value[35:0] is + set to 0x345678021. This is a new register (with 2_) added in E3 B0 to + accommodate the 9 input clients to ETS arbiter. Note that this register + is the same as the one for port 0, except that port 1 only has COS 0-2 + traffic. There is no traffic for COS 3-5 of port 1. */ +#define NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB 0x186e4 +/* [R 1] TX FIFO for transmitting data to MAC is empty. */ +#define NIG_REG_P1_TX_MACFIFO_EMPTY 0x18594 +/* [R 1] FIFO empty status of the MCP TX FIFO used for storing MCP packets + forwarded to the host. */ +#define NIG_REG_P1_TX_MNG_HOST_FIFO_EMPTY 0x182b8 /* [RW 32] Specify the upper bound that credit register 0 is allowed to * reach. */ /* [RW 1] Pause enable for port0. This register may get 1 only when @@ -2249,12 +2351,36 @@ #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18 /* [RW 31] The upper bound of the weight of COS0 in the ETS command arbiter. */ #define PBF_REG_COS0_UPPER_BOUND 0x15c05c +/* [RW 31] The upper bound of the weight of COS0 in the ETS command arbiter + * of port 0. */ +#define PBF_REG_COS0_UPPER_BOUND_P0 0x15c2cc +/* [RW 31] The upper bound of the weight of COS0 in the ETS command arbiter + * of port 1. */ +#define PBF_REG_COS0_UPPER_BOUND_P1 0x15c2e4 /* [RW 31] The weight of COS0 in the ETS command arbiter. */ #define PBF_REG_COS0_WEIGHT 0x15c054 +/* [RW 31] The weight of COS0 in port 0 ETS command arbiter. */ +#define PBF_REG_COS0_WEIGHT_P0 0x15c2a8 +/* [RW 31] The weight of COS0 in port 1 ETS command arbiter. */ +#define PBF_REG_COS0_WEIGHT_P1 0x15c2c0 /* [RW 31] The upper bound of the weight of COS1 in the ETS command arbiter. */ #define PBF_REG_COS1_UPPER_BOUND 0x15c060 /* [RW 31] The weight of COS1 in the ETS command arbiter. */ #define PBF_REG_COS1_WEIGHT 0x15c058 +/* [RW 31] The weight of COS1 in port 0 ETS command arbiter. */ +#define PBF_REG_COS1_WEIGHT_P0 0x15c2ac +/* [RW 31] The weight of COS1 in port 1 ETS command arbiter. */ +#define PBF_REG_COS1_WEIGHT_P1 0x15c2c4 +/* [RW 31] The weight of COS2 in port 0 ETS command arbiter. */ +#define PBF_REG_COS2_WEIGHT_P0 0x15c2b0 +/* [RW 31] The weight of COS2 in port 1 ETS command arbiter. */ +#define PBF_REG_COS2_WEIGHT_P1 0x15c2c8 +/* [RW 31] The weight of COS3 in port 0 ETS command arbiter. */ +#define PBF_REG_COS3_WEIGHT_P0 0x15c2b4 +/* [RW 31] The weight of COS4 in port 0 ETS command arbiter. */ +#define PBF_REG_COS4_WEIGHT_P0 0x15c2b8 +/* [RW 31] The weight of COS5 in port 0 ETS command arbiter. */ +#define PBF_REG_COS5_WEIGHT_P0 0x15c2bc /* [R 11] Current credit for the LB queue in the tx port buffers in 16 byte * lines. */ #define PBF_REG_CREDIT_LB_Q 0x140338 @@ -2274,6 +2400,52 @@ current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c #define PBF_REG_DISABLE_PF 0x1402e8 +/* [RW 18] For port 0: For each client that is subject to WFQ (the + * corresponding bit is 1); indicates to which of the credit registers this + * client is mapped. For clients which are not credit blocked; their mapping + * is dont care. */ +#define PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0 0x15c288 +/* [RW 9] For port 1: For each client that is subject to WFQ (the + * corresponding bit is 1); indicates to which of the credit registers this + * client is mapped. For clients which are not credit blocked; their mapping + * is dont care. */ +#define PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1 0x15c28c +/* [RW 6] For port 0: Bit per client to indicate if the client competes in + * the strict priority arbiter directly (corresponding bit = 1); or first + * goes to the RR arbiter (corresponding bit = 0); and then competes in the + * lowest priority in the strict-priority arbiter. */ +#define PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 0x15c278 +/* [RW 3] For port 1: Bit per client to indicate if the client competes in + * the strict priority arbiter directly (corresponding bit = 1); or first + * goes to the RR arbiter (corresponding bit = 0); and then competes in the + * lowest priority in the strict-priority arbiter. */ +#define PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 0x15c27c +/* [RW 6] For port 0: Bit per client to indicate if the client is subject to + * WFQ credit blocking (corresponding bit = 1). */ +#define PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 0x15c280 +/* [RW 3] For port 0: Bit per client to indicate if the client is subject to + * WFQ credit blocking (corresponding bit = 1). */ +#define PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 0x15c284 +/* [RW 16] For port 0: The number of strict priority arbitration slots + * between 2 RR arbitration slots. A value of 0 means no strict priority + * cycles; i.e. the strict-priority w/ anti-starvation arbiter is a RR + * arbiter. */ +#define PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 0x15c2a0 +/* [RW 16] For port 1: The number of strict priority arbitration slots + * between 2 RR arbitration slots. A value of 0 means no strict priority + * cycles; i.e. the strict-priority w/ anti-starvation arbiter is a RR + * arbiter. */ +#define PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 0x15c2a4 +/* [RW 18] For port 0: Indicates which client is connected to each priority + * in the strict-priority arbiter. Priority 0 is the highest priority, and + * priority 5 is the lowest; to which the RR output is connected to (this is + * not configurable). */ +#define PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 0x15c270 +/* [RW 9] For port 1: Indicates which client is connected to each priority + * in the strict-priority arbiter. Priority 0 is the highest priority, and + * priority 5 is the lowest; to which the RR output is connected to (this is + * not configurable). */ +#define PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 0x15c274 /* [RW 1] Indicates that ETS is performed between the COSes in the command * arbiter. If reset strict priority w/ anti-starvation will be performed * w/o WFQ. */ -- cgit v1.2.3-70-g09d2 From 0d40f0d425ec632956547bd8efd8965e5945e1dc Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:34:27 +0000 Subject: bnx2x: Adjust BCM84833 to BCM578xx Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 85 +++++++++++++++++++++++++++++++++++++++--- drivers/net/bnx2x/bnx2x_main.c | 47 +++++++++++++++++++++++ 2 files changed, 127 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index a5c34880b39..241b1e42c37 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -9198,6 +9198,52 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, return 0; } + +static int bnx2x_84833_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 chip_id) +{ + u32 reset_pin[2]; + u32 idx; + u8 reset_gpios; + if (CHIP_IS_E3(bp)) { + /* Assume that these will be GPIOs, not EPIOs. */ + for (idx = 0; idx < 2; idx++) { + /* Map config param to register bit. */ + reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] + + offsetof(struct shmem_region, + dev_info.port_hw_config[0].e3_cmn_pin_cfg)); + reset_pin[idx] = (reset_pin[idx] & + PORT_HW_CFG_E3_PHY_RESET_MASK) >> + PORT_HW_CFG_E3_PHY_RESET_SHIFT; + reset_pin[idx] -= PIN_CFG_GPIO0_P0; + reset_pin[idx] = (1 << reset_pin[idx]); + } + reset_gpios = (u8)(reset_pin[0] | reset_pin[1]); + } else { + /* E2, look from diff place of shmem. */ + for (idx = 0; idx < 2; idx++) { + reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] + + offsetof(struct shmem_region, + dev_info.port_hw_config[0].default_cfg)); + reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK; + reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0; + reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT; + reset_pin[idx] = (1 << reset_pin[idx]); + } + reset_gpios = (u8)(reset_pin[0] | reset_pin[1]); + } + + bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW); + udelay(10); + bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH); + msleep(800); + DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n", + reset_gpios); + + return 0; +} + static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -9263,8 +9309,14 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN | MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK | MDIO_CTL_REG_84823_MEDIA_FIBER_1G); - val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI | - MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L; + + if (CHIP_IS_E3(bp)) { + val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | + MDIO_CTL_REG_84823_MEDIA_LINE_MASK); + } else { + val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI | + MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L); + } actual_phy_selection = bnx2x_phy_selection(params); @@ -9435,6 +9487,7 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u8 port; + u16 val16; if (!(CHIP_IS_E1(bp))) port = BP_PATH(bp); @@ -9446,9 +9499,14 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } else { - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x800); + bnx2x_cl45_read(bp, phy, + MDIO_CTL_DEVAD, + 0x400f, &val16); + /* Put to low power mode on newer FW */ + if ((val16 & 0x303f) > 0x1009) + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, 0x800); } } @@ -9647,7 +9705,17 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, } break; } + + /* + * This is a workaround for E3+84833 until autoneg + * restart is fixed in f/w + */ + if (CHIP_IS_E3(bp)) { + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_GP2_STATUS_GP_2_1, &val); + } } + /******************************************************************/ /* 54616S PHY SECTION */ /******************************************************************/ @@ -11700,6 +11768,13 @@ static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], shmem2_base_path, phy_index, chip_id); break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: + /* + * GPIO3's are linked, and so both need to be toggled + * to obtain required 2us pulse. + */ + rc = bnx2x_84833_common_init_phy(bp, shmem_base_path, chip_id); + break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: rc = -EINVAL; break; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 0dddba9532c..29c67029c75 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1955,6 +1955,53 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) return 0; } +int bnx2x_set_mult_gpio(struct bnx2x *bp, u8 pins, u32 mode) +{ + u32 gpio_reg = 0; + int rc = 0; + + /* Any port swapping should be handled by caller. */ + + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); + /* read GPIO and mask except the float bits */ + gpio_reg = REG_RD(bp, MISC_REG_GPIO); + gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_FLOAT_POS); + gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_CLR_POS); + gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_SET_POS); + + switch (mode) { + case MISC_REGISTERS_GPIO_OUTPUT_LOW: + DP(NETIF_MSG_LINK, "Set GPIO 0x%x -> output low\n", pins); + /* set CLR */ + gpio_reg |= (pins << MISC_REGISTERS_GPIO_CLR_POS); + break; + + case MISC_REGISTERS_GPIO_OUTPUT_HIGH: + DP(NETIF_MSG_LINK, "Set GPIO 0x%x -> output high\n", pins); + /* set SET */ + gpio_reg |= (pins << MISC_REGISTERS_GPIO_SET_POS); + break; + + case MISC_REGISTERS_GPIO_INPUT_HI_Z: + DP(NETIF_MSG_LINK, "Set GPIO 0x%x -> input\n", pins); + /* set FLOAT */ + gpio_reg |= (pins << MISC_REGISTERS_GPIO_FLOAT_POS); + break; + + default: + BNX2X_ERR("Invalid GPIO mode assignment %d\n", mode); + rc = -EINVAL; + break; + } + + if (rc == 0) + REG_WR(bp, MISC_REG_GPIO, gpio_reg); + + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); + + return rc; +} + int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) { /* The GPIO should be swapped if swap register is set and active */ -- cgit v1.2.3-70-g09d2 From 3deb8167ea66974b0bc8c13c8ee0beafc02a73a1 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:34:33 +0000 Subject: bnx2x: Add a periodic task for link PHY events Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 3 + drivers/net/bnx2x/bnx2x_cmn.c | 11 ++- drivers/net/bnx2x/bnx2x_link.c | 211 +++++++++++++++++++++++++++++++++++++++-- drivers/net/bnx2x/bnx2x_link.h | 11 ++- drivers/net/bnx2x/bnx2x_main.c | 74 +++++++++++++-- drivers/net/bnx2x/bnx2x_reg.h | 2 + 6 files changed, 294 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 838a4edbe94..36961494e00 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1160,6 +1160,8 @@ struct bnx2x { struct delayed_work sp_task; struct delayed_work reset_task; + + struct delayed_work period_task; struct timer_list timer; int current_interval; @@ -1940,4 +1942,5 @@ static const u32 dmae_reg_go_c[] = { }; void bnx2x_set_ethtool_ops(struct net_device *netdev); +void bnx2x_notify_link_changed(struct bnx2x *bp); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 04cacbf5d71..bb7556016f4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1736,9 +1736,16 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || - (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) + (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) { bp->port.pmf = 1; - else + /* + * We need the barrier to ensure the ordering between the + * writing to bp->port.pmf here and reading it from the + * bnx2x_periodic_task(). + */ + smp_mb(); + queue_delayed_work(bnx2x_wq, &bp->period_task, 0); + } else bp->port.pmf = 0; DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 241b1e42c37..47d80041c82 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -296,6 +296,23 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) /******************************************************************/ /* EPIO/GPIO section */ /******************************************************************/ +static void bnx2x_get_epio(struct bnx2x *bp, u32 epio_pin, u32 *en) +{ + u32 epio_mask, gp_oenable; + *en = 0; + /* Sanity check */ + if (epio_pin > 31) { + DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin); + return; + } + + epio_mask = 1 << epio_pin; + /* Set this EPIO to output */ + gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE); + REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask); + + *en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin; +} static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en) { u32 epio_mask, gp_output, gp_oenable; @@ -334,6 +351,20 @@ static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val) } } +static u32 bnx2x_get_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 *val) +{ + if (pin_cfg == PIN_CFG_NA) + return -EINVAL; + if (pin_cfg >= PIN_CFG_EPIO0) { + bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val); + } else { + u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3; + u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2; + *val = bnx2x_get_gpio(bp, gpio_num, gpio_port); + } + return 0; + +} /******************************************************************/ /* ETS section */ /******************************************************************/ @@ -2537,6 +2568,12 @@ static int bnx2x_bmac1_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, wb_data, 2); + if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) { + REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LSS_STATUS, + wb_data, 2); + if (wb_data[0] > 0) + return -ESRCH; + } return 0; } @@ -2602,6 +2639,16 @@ static int bnx2x_bmac2_enable(struct link_params *params, udelay(30); bnx2x_update_pfc_bmac2(params, vars, is_lb); + if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) { + REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LSS_STAT, + wb_data, 2); + if (wb_data[0] > 0) { + DP(NETIF_MSG_LINK, "Got bad LSS status 0x%x\n", + wb_data[0]); + return -ESRCH; + } + } + return 0; } @@ -6081,7 +6128,7 @@ static int bnx2x_update_link_down(struct link_params *params, DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); bnx2x_set_led(params, vars, LED_MODE_OFF, 0); - + vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG; /* indicate no mac active */ vars->mac_type = MAC_TYPE_NONE; @@ -6126,6 +6173,7 @@ static int bnx2x_update_link_up(struct link_params *params, int rc = 0; vars->link_status |= LINK_STATUS_LINK_UP; + vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG; if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) vars->link_status |= @@ -6135,9 +6183,15 @@ static int bnx2x_update_link_up(struct link_params *params, vars->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED; if (USES_WARPCORE(bp)) { - if (link_10g) - bnx2x_xmac_enable(params, vars, 0); - else + if (link_10g) { + if (bnx2x_xmac_enable(params, vars, 0) == + -ESRCH) { + DP(NETIF_MSG_LINK, "Found errors on XMAC\n"); + vars->link_up = 0; + vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; + vars->link_status &= ~LINK_STATUS_LINK_UP; + } + } else bnx2x_umac_enable(params, vars, 0); bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); @@ -6145,7 +6199,13 @@ static int bnx2x_update_link_up(struct link_params *params, if ((CHIP_IS_E1x(bp) || CHIP_IS_E2(bp))) { if (link_10g) { - bnx2x_bmac_enable(params, vars, 0); + if (bnx2x_bmac_enable(params, vars, 0) == + -ESRCH) { + DP(NETIF_MSG_LINK, "Found errors on BMAC\n"); + vars->link_up = 0; + vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; + vars->link_status &= ~LINK_STATUS_LINK_UP; + } bnx2x_set_led(params, vars, LED_MODE_OPER, SPEED_10000); @@ -6199,7 +6259,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) u8 is_mi_int = 0; u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; u8 active_external_phy = INT_PHY; - + vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; for (phy_index = INT_PHY; phy_index < params->num_phys; phy_index++) { phy_vars[phy_index].flow_ctrl = 0; @@ -8109,6 +8169,10 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, u32 tx_en_mode; u16 cnt, val, tmp1; struct bnx2x *bp = params->bp; + + /* SPF+ PHY: Set flag to check for Tx error */ + vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ @@ -8292,6 +8356,9 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); + /* SPF+ PHY: Set flag to check for Tx error */ + vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); bnx2x_wait_reset_complete(bp, phy, params); @@ -8460,6 +8527,9 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ + /* SPF+ PHY: Set flag to check for Tx error */ + vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; + bnx2x_wait_reset_complete(bp, phy, params); rx_alarm_ctrl_val = (1<<2) | (1<<5) ; /* Should be 0x6 to enable XS on Tx side. */ @@ -11832,6 +11902,135 @@ int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], return rc; } +static void bnx2x_check_over_curr(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u32 cfg_pin; + u8 port = params->port; + u32 pin_val; + + cfg_pin = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) & + PORT_HW_CFG_E3_OVER_CURRENT_MASK) >> + PORT_HW_CFG_E3_OVER_CURRENT_SHIFT; + + /* Ignore check if no external input PIN available */ + if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0) + return; + + if (!pin_val) { + if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) { + netdev_err(bp->dev, "Error: Power fault on Port %d has" + " been detected and the power to " + "that SFP+ module has been removed" + " to prevent failure of the card." + " Please remove the SFP+ module and" + " restart the system to clear this" + " error.\n", + params->port); + vars->phy_flags |= PHY_OVER_CURRENT_FLAG; + } + } else + vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG; +} + +static void bnx2x_analyze_link_error(struct link_params *params, + struct link_vars *vars, u32 lss_status) +{ + struct bnx2x *bp = params->bp; + /* Compare new value with previous value */ + u8 led_mode; + u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0; + + /*DP(NETIF_MSG_LINK, "CHECK LINK: %x half_open:%x-> lss:%x\n", + vars->link_up, + half_open_conn, lss_status);*/ + + if ((lss_status ^ half_open_conn) == 0) + return; + + /* If values differ */ + DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up, + half_open_conn, lss_status); + + /* + * a. Update shmem->link_status accordingly + * b. Update link_vars->link_up + */ + if (lss_status) { + vars->link_status &= ~LINK_STATUS_LINK_UP; + vars->link_up = 0; + vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; + /* + * Set LED mode to off since the PHY doesn't know about these + * errors + */ + led_mode = LED_MODE_OFF; + } else { + vars->link_status |= LINK_STATUS_LINK_UP; + vars->link_up = 1; + vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; + led_mode = LED_MODE_OPER; + } + /* Update the LED according to the link state */ + bnx2x_set_led(params, vars, led_mode, SPEED_10000); + + /* Update link status in the shared memory */ + bnx2x_update_mng(params, vars->link_status); + + /* C. Trigger General Attention */ + vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT; + bnx2x_notify_link_changed(bp); +} + +static void bnx2x_check_half_open_conn(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u32 lss_status = 0; + u32 mac_base; + /* In case link status is physically up @ 10G do */ + if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) + return; + + if (!CHIP_IS_E3(bp) && + (REG_RD(bp, MISC_REG_RESET_REG_2) & + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))) { + /* Check E1X / E2 BMAC */ + u32 lss_status_reg; + u32 wb_data[2]; + mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + /* Read BIGMAC_REGISTER_RX_LSS_STATUS */ + if (CHIP_IS_E2(bp)) + lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT; + else + lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS; + + REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2); + lss_status = (wb_data[0] > 0); + + bnx2x_analyze_link_error(params, vars, lss_status); + } +} + +void bnx2x_period_func(struct link_params *params, struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + if (!params) { + DP(NETIF_MSG_LINK, "Ininitliazed params !\n"); + return; + } + /* DP(NETIF_MSG_LINK, "Periodic called vars->phy_flags 0x%x speed 0x%x + RESET_REG_2 0x%x\n", vars->phy_flags, vars->line_speed, + REG_RD(bp, MISC_REG_RESET_REG_2)); */ + bnx2x_check_half_open_conn(params, vars); + if (CHIP_IS_E3(bp)) + bnx2x_check_over_curr(params, vars); +} + u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base) { u8 phy_index; diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 3d9c46bb108..6f299c2fd3e 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -271,6 +271,10 @@ struct link_vars { u8 phy_flags; #define PHY_XGXS_FLAG (1<<0) #define PHY_SGMII_FLAG (1<<1) +#define PHY_PHYSICAL_LINK_FLAG (1<<2) +#define PHY_HALF_OPEN_CONN_FLAG (1<<3) +#define PHY_OVER_CURRENT_FLAG (1<<4) +#define PHY_TX_ERROR_CHECK_FLAG (1<<5) u8 mac_type; #define MAC_TYPE_NONE 0 @@ -292,7 +296,9 @@ struct link_vars { u32 link_status; u8 fault_detected; u8 rsrv1; - u16 rsrv2; + u16 periodic_flags; +#define PERIODIC_FLAGS_LINK_EVENT 0x0001 + u32 aeu_int_mask; }; @@ -478,4 +484,7 @@ void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, struct link_params *params); + +void bnx2x_period_func(struct link_params *params, struct link_vars *vars); + #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 29c67029c75..af5721754f6 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1563,6 +1563,7 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) /* make sure sp_task is not running */ cancel_delayed_work(&bp->sp_task); + cancel_delayed_work(&bp->period_task); flush_workqueue(bnx2x_wq); } @@ -2150,7 +2151,8 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) { bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); bnx2x_link_report(bp); - } + } else + queue_delayed_work(bnx2x_wq, &bp->period_task, 0); bp->link_params.req_line_speed[cfx_idx] = req_line_speed; return rc; } @@ -2524,6 +2526,15 @@ static void bnx2x_pmf_update(struct bnx2x *bp) bp->port.pmf = 1; DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); + /* + * We need the mb() to ensure the ordering between the writing to + * bp->port.pmf here and reading it from the bnx2x_periodic_task(). + */ + smp_mb(); + + /* queue a periodic task */ + queue_delayed_work(bnx2x_wq, &bp->period_task, 0); + bnx2x_dcbx_pmf_update(bp); /* enable nig attention */ @@ -3242,8 +3253,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) bnx2x_fan_failure(bp); } - if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 | - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) { + if ((attn & bp->link_vars.aeu_int_mask) && bp->port.pmf) { bnx2x_acquire_phy_lock(bp); bnx2x_handle_module_detect_int(&bp->link_params); bnx2x_release_phy_lock(bp); @@ -3360,17 +3370,27 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) bnx2x_pmf_update(bp); - /* Always call it here: bnx2x_link_report() will - * prevent the link indication duplication. - */ - bnx2x__link_status_update(bp); - if (bp->port.pmf && (val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS) && bp->dcbx_enabled > 0) /* start dcbx state machine */ bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_NEG_RECEIVED); + if (bp->link_vars.periodic_flags & + PERIODIC_FLAGS_LINK_EVENT) { + /* sync with link */ + bnx2x_acquire_phy_lock(bp); + bp->link_vars.periodic_flags &= + ~PERIODIC_FLAGS_LINK_EVENT; + bnx2x_release_phy_lock(bp); + if (IS_MF(bp)) + bnx2x_link_sync_notify(bp); + bnx2x_link_report(bp); + } + /* Always call it here: bnx2x_link_report() will + * prevent the link indication duplication. + */ + bnx2x__link_status_update(bp); } else if (attn & BNX2X_MC_ASSERT_BITS) { BNX2X_ERR("MC assert!\n"); @@ -8044,6 +8064,37 @@ reset_task_exit: /* end of nic load/unload */ +static void bnx2x_period_task(struct work_struct *work) +{ + struct bnx2x *bp = container_of(work, struct bnx2x, period_task.work); + + if (!netif_running(bp->dev)) + goto period_task_exit; + + if (CHIP_REV_IS_SLOW(bp)) { + BNX2X_ERR("period task called on emulation, ignoring\n"); + goto period_task_exit; + } + + bnx2x_acquire_phy_lock(bp); + /* + * The barrier is needed to ensure the ordering between the writing to + * the bp->port.pmf in the bnx2x_nic_load() or bnx2x_pmf_update() and + * the reading here. + */ + smp_mb(); + if (bp->port.pmf) { + bnx2x_period_func(&bp->link_params, &bp->link_vars); + + /* Re-queue task in 1 sec */ + queue_delayed_work(bnx2x_wq, &bp->period_task, 1*HZ); + } + + bnx2x_release_phy_lock(bp); +period_task_exit: + return; +} + /* * Init service functions */ @@ -9237,7 +9288,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); INIT_DELAYED_WORK(&bp->reset_task, bnx2x_reset_task); - + INIT_DELAYED_WORK(&bp->period_task, bnx2x_period_task); rc = bnx2x_get_hwinfo(bp); if (rc) return rc; @@ -10515,6 +10566,11 @@ static void __exit bnx2x_cleanup(void) destroy_workqueue(bnx2x_wq); } +void bnx2x_notify_link_changed(struct bnx2x *bp) +{ + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + BP_FUNC(bp)*sizeof(u32), 1); +} + module_init(bnx2x_init); module_exit(bnx2x_cleanup); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index d0cf072d21e..2511f99a74f 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5559,6 +5559,7 @@ #define BIGMAC_REGISTER_CNT_MAX_SIZE (0x05<<3) #define BIGMAC_REGISTER_RX_CONTROL (0x21<<3) #define BIGMAC_REGISTER_RX_LLFC_MSG_FLDS (0x46<<3) +#define BIGMAC_REGISTER_RX_LSS_STATUS (0x43<<3) #define BIGMAC_REGISTER_RX_MAX_SIZE (0x23<<3) #define BIGMAC_REGISTER_RX_STAT_GR64 (0x26<<3) #define BIGMAC_REGISTER_RX_STAT_GRIPJ (0x42<<3) @@ -5574,6 +5575,7 @@ #define BIGMAC2_REGISTER_PFC_CONTROL (0x06<<3) #define BIGMAC2_REGISTER_RX_CONTROL (0x3A<<3) #define BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS (0x62<<3) +#define BIGMAC2_REGISTER_RX_LSS_STAT (0x3E<<3) #define BIGMAC2_REGISTER_RX_MAX_SIZE (0x3C<<3) #define BIGMAC2_REGISTER_RX_STAT_GR64 (0x40<<3) #define BIGMAC2_REGISTER_RX_STAT_GRIPJ (0x5f<<3) -- cgit v1.2.3-70-g09d2 From 60d2fe0312b3301fb5a65e9ed0b44465c8237055 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 14 Jun 2011 01:34:38 +0000 Subject: bnx2x: Rename LASI registers to definitions in mdio.h Signed-off-by: Yaniv Rosner Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 82 +++++++++++++++++++++--------------------- drivers/net/bnx2x/bnx2x_reg.h | 6 ---- 2 files changed, 41 insertions(+), 47 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 47d80041c82..836363645da 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -6821,9 +6821,9 @@ static int bnx2x_8073_config_init(struct bnx2x_phy *phy, /* enable LASI */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2)); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2)); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0004); bnx2x_8073_set_pause_cl37(params, phy, vars); @@ -6831,7 +6831,7 @@ static int bnx2x_8073_config_init(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1); DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); @@ -6965,7 +6965,7 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, u16 an1000_status = 0; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); @@ -6981,7 +6981,7 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, /* Check the LASI */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2); DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); @@ -8109,16 +8109,16 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); /* Clear RX Alarm*/ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2); - bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM, - MDIO_PMA_REG_TX_ALARM_CTRL); + bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT, + MDIO_PMA_LASI_TXCTRL); /* clear LASI indication*/ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2); DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2); bnx2x_cl45_read(bp, phy, @@ -8149,9 +8149,9 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, /* Capture 10G link fault. Read twice to clear stale value. */ if (vars->line_speed == SPEED_10000) { bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_ALARM, &val1); + MDIO_PMA_LASI_TXSTAT, &val1); bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_ALARM, &val1); + MDIO_PMA_LASI_TXSTAT, &val1); if (val1 & (1<<0)) vars->fault_detected = 1; } @@ -8215,11 +8215,11 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, 0x400); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL, 0); /* Arm LASI for link and Tx fault. */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 3); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3); } else { /* Force 1Gbps using autoneg with 1G advertisement */ @@ -8242,10 +8242,10 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 0x0400); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0004); } bnx2x_save_bcm_spirom_ver(bp, phy, params->port); @@ -8379,9 +8379,9 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 0x400); } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & @@ -8407,14 +8407,14 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, * change */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, 0x400); } else { /* Default 10G. Set only LASI control */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1); } /* Set TX PreEmphasis if needed */ @@ -8538,13 +8538,13 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); /* enable LASI */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, rx_alarm_ctrl_val); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL, 0); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val); /* * Initially configure MOD_ABS to interrupt when module is @@ -8586,7 +8586,7 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1); /* Set option 1G speed */ if (phy->req_line_speed == SPEED_1000) { @@ -8726,7 +8726,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + MDIO_PMA_LASI_RXSTAT, &rx_alarm_status); } else { /* Module is present */ @@ -8755,7 +8755,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + MDIO_PMA_LASI_RXSTAT, &rx_alarm_status); if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == @@ -8785,23 +8785,23 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, /* If PHY is not initialized, do not check link status */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, &lasi_ctrl); if (!lasi_ctrl) return 0; /* Check the LASI on Rx */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &rx_alarm_status); vars->line_speed = 0; DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); - bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM, - MDIO_PMA_REG_TX_ALARM_CTRL); + bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT, + MDIO_PMA_LASI_TXCTRL); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1); @@ -8835,7 +8835,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, /* Disable all RX_ALARMs except for mod_abs */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5)); + MDIO_PMA_LASI_RXCTRL, (1<<5)); bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, @@ -8848,7 +8848,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, /* Clear RX alarm */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + MDIO_PMA_LASI_RXSTAT, &rx_alarm_status); return 0; } } /* Over current check */ @@ -8858,7 +8858,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, bnx2x_8727_handle_mod_abs(phy, params); /* Enable all mod_abs and link detection bits */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, ((1<<5) | (1<<2))); } DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n"); @@ -8898,10 +8898,10 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, /* Capture 10G link fault. */ if (vars->line_speed == SPEED_10000) { bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_ALARM, &val1); + MDIO_PMA_LASI_TXSTAT, &val1); bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_ALARM, &val1); + MDIO_PMA_LASI_TXSTAT, &val1); if (val1 & (1<<0)) { vars->fault_detected = 1; @@ -8941,7 +8941,7 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, /* Disable Transmitter */ bnx2x_sfp_set_transmitter(params, phy, 0); /* Clear LASI */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0); } @@ -10137,7 +10137,7 @@ static int bnx2x_7101_config_init(struct bnx2x_phy *phy, bnx2x_wait_reset_complete(bp, phy, params); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1); DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n"); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); @@ -10169,9 +10169,9 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, u8 link_up; u16 val1, val2; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1); DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", val2, val1); bnx2x_cl45_read(bp, phy, diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 2511f99a74f..53da4ef1992 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6610,12 +6610,6 @@ Theotherbitsarereservedandshouldbezero*/ /*bcm*/ #define MDIO_PMA_REG_BCM_CTRL 0x0096 #define MDIO_PMA_REG_FEC_CTRL 0x00ab -#define MDIO_PMA_REG_RX_ALARM_CTRL 0x9000 -#define MDIO_PMA_REG_TX_ALARM_CTRL 0x9001 -#define MDIO_PMA_REG_LASI_CTRL 0x9002 -#define MDIO_PMA_REG_RX_ALARM 0x9003 -#define MDIO_PMA_REG_TX_ALARM 0x9004 -#define MDIO_PMA_REG_LASI_STATUS 0x9005 #define MDIO_PMA_REG_PHY_IDENTIFIER 0xc800 #define MDIO_PMA_REG_DIGITAL_CTRL 0xc808 #define MDIO_PMA_REG_DIGITAL_STATUS 0xc809 -- cgit v1.2.3-70-g09d2 From d1976b2e6478a1b8ff2dc35979e7791e2d668285 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 14 Jun 2011 01:34:42 +0000 Subject: bnx2x: PFC support for 578xx Add supoprt for 3 COSes for 578xx devices. Fix HW configuration for PFC feature according to new HSI in link layer. Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_dcb.c | 504 ++++++++++++++++++++++++++++++++---------- drivers/net/bnx2x/bnx2x_dcb.h | 23 +- 2 files changed, 406 insertions(+), 121 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 50a5c4f3d58..b51a759c103 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -47,33 +47,39 @@ static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, struct cos_help_data *cos_data, u32 *pg_pri_orginal_spread, struct dcbx_ets_feature *ets); -static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp); +static void bnx2x_dcbx_fw_struct(struct bnx2x *bp); static void bnx2x_pfc_set(struct bnx2x *bp) { struct bnx2x_nig_brb_pfc_port_params pfc_params = {0}; u32 pri_bit, val = 0; - u8 pri; int i; + pfc_params.num_of_rx_cos_priority_mask = + bp->dcbx_port_params.ets.num_of_cos; + /* Tx COS configuration */ for (i = 0; i < bp->dcbx_port_params.ets.num_of_cos; i++) - if (bp->dcbx_port_params.ets.cos_params[i].pauseable) - pfc_params.rx_cos_priority_mask[i] = - bp->dcbx_port_params.ets. - cos_params[i].pri_bitmask; + /* + * We configure only the pauseable bits (non pauseable aren't + * configured at all) it's done to avoid false pauses from + * network + */ + pfc_params.rx_cos_priority_mask[i] = + bp->dcbx_port_params.ets.cos_params[i].pri_bitmask + & DCBX_PFC_PRI_PAUSE_MASK(bp); - /** + /* * Rx COS configuration * Changing PFC RX configuration . * In RX COS0 will always be configured to lossy and COS1 to lossless */ - for (pri = 0 ; pri < MAX_PFC_PRIORITIES ; pri++) { - pri_bit = 1 << pri; + for (i = 0 ; i < MAX_PFC_PRIORITIES ; i++) { + pri_bit = 1 << i; if (pri_bit & DCBX_PFC_PRI_PAUSE_MASK(bp)) - val |= 1 << (pri * 4); + val |= 1 << (i * 4); } pfc_params.pkt_priority_to_cos = val; @@ -252,12 +258,11 @@ static void bnx2x_dcbx_get_ets_feature(struct bnx2x *bp, /* Clean up old settings of ets on COS */ - for (i = 0; i < E2_NUM_OF_COS ; i++) { - + for (i = 0; i < ARRAY_SIZE(bp->dcbx_port_params.ets.cos_params) ; i++) { cos_params[i].pauseable = false; - cos_params[i].strict = BNX2X_DCBX_COS_NOT_STRICT; + cos_params[i].strict = BNX2X_DCBX_STRICT_INVALID; cos_params[i].bw_tbl = DCBX_INVALID_COS_BW; - cos_params[i].pri_bitmask = DCBX_PFC_PRI_GET_NON_PAUSE(bp, 0); + cos_params[i].pri_bitmask = 0; } if (bp->dcbx_port_params.app.enabled && @@ -377,25 +382,19 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, static void bnx2x_pfc_set_pfc(struct bnx2x *bp) { - if (!CHIP_IS_E1x(bp)) { - if (BP_PORT(bp)) { - BNX2X_ERR("4 port mode is not supported"); - return; - } - - if (bp->dcbx_port_params.pfc.enabled) - - /* 1. Fills up common PFC structures if required.*/ - /* 2. Configure NIG, MAC and BRB via the elink: - * elink must first check if BMAC is not in reset - * and only then configures the BMAC - * Or, configure EMAC. - */ - bnx2x_pfc_set(bp); - - else - bnx2x_pfc_clear(bp); + if (BP_PORT(bp)) { + BNX2X_ERR("4 port mode is not supported"); + return; } + + if (bp->dcbx_port_params.pfc.enabled) + /* + * 1. Fills up common PFC structures if required + * 2. Configure NIG, MAC and BRB via the elink + */ + bnx2x_pfc_set(bp); + else + bnx2x_pfc_clear(bp); } static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) @@ -410,7 +409,7 @@ static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) { - bnx2x_pfc_fw_struct_e2(bp); + bnx2x_dcbx_fw_struct(bp); DP(NETIF_MSG_LINK, "sending START TRAFFIC\n"); bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0, /* connectionless */ @@ -419,18 +418,13 @@ static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) NONE_CONNECTION_TYPE); } -static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) +static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp) { struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets); - u8 status = 0; - - bnx2x_ets_disabled(&bp->link_params, &bp->link_vars); - - if (!ets->enabled) - return; + int rc = 0; - if ((ets->num_of_cos == 0) || (ets->num_of_cos > E2_NUM_OF_COS)) { - BNX2X_ERR("illegal num of cos= %x", ets->num_of_cos); + if (ets->num_of_cos == 0 || ets->num_of_cos > DCBX_COS_MAX_NUM_E2) { + BNX2X_ERR("Illegal number of COSes %d\n", ets->num_of_cos); return; } @@ -439,9 +433,9 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) return; /* sanity */ - if (((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[0].strict) && + if (((BNX2X_DCBX_STRICT_INVALID == ets->cos_params[0].strict) && (DCBX_INVALID_COS_BW == ets->cos_params[0].bw_tbl)) || - ((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[1].strict) && + ((BNX2X_DCBX_STRICT_INVALID == ets->cos_params[1].strict) && (DCBX_INVALID_COS_BW == ets->cos_params[1].bw_tbl))) { BNX2X_ERR("all COS should have at least bw_limit or strict" "ets->cos_params[0].strict= %x" @@ -473,17 +467,70 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) bnx2x_ets_bw_limit(&bp->link_params, bw_tbl_0, bw_tbl_1); } else { - if (ets->cos_params[0].strict == BNX2X_DCBX_COS_HIGH_STRICT) - status = bnx2x_ets_strict(&bp->link_params, 0); + if (ets->cos_params[0].strict == BNX2X_DCBX_STRICT_COS_HIGHEST) + rc = bnx2x_ets_strict(&bp->link_params, 0); else if (ets->cos_params[1].strict - == BNX2X_DCBX_COS_HIGH_STRICT) - status = bnx2x_ets_strict(&bp->link_params, 1); - - if (status) + == BNX2X_DCBX_STRICT_COS_HIGHEST) + rc = bnx2x_ets_strict(&bp->link_params, 1); + if (rc) BNX2X_ERR("update_ets_params failed\n"); } } +/* + * In E3B0 the configuration may have more than 2 COS. + */ +void bnx2x_dcbx_update_ets_config(struct bnx2x *bp) +{ + struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets); + struct bnx2x_ets_params ets_params = { 0 }; + u8 i; + + ets_params.num_of_cos = ets->num_of_cos; + + for (i = 0; i < ets->num_of_cos; i++) { + /* COS is SP */ + if (ets->cos_params[i].strict != BNX2X_DCBX_STRICT_INVALID) { + if (ets->cos_params[i].bw_tbl != DCBX_INVALID_COS_BW) { + BNX2X_ERR("COS can't be not BW and not SP\n"); + return; + } + + ets_params.cos[i].state = bnx2x_cos_state_strict; + ets_params.cos[i].params.sp_params.pri = + ets->cos_params[i].strict; + } else { /* COS is BW */ + if (ets->cos_params[i].bw_tbl == DCBX_INVALID_COS_BW) { + BNX2X_ERR("COS can't be not BW and not SP\n"); + return; + } + ets_params.cos[i].state = bnx2x_cos_state_bw; + ets_params.cos[i].params.bw_params.bw = + (u8)ets->cos_params[i].bw_tbl; + } + } + + /* Configure the ETS in HW */ + if (bnx2x_ets_e3b0_config(&bp->link_params, &bp->link_vars, + &ets_params)) { + BNX2X_ERR("bnx2x_ets_e3b0_config failed\n"); + bnx2x_ets_disabled(&bp->link_params, &bp->link_vars); + } +} + +static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) +{ + bnx2x_ets_disabled(&bp->link_params, &bp->link_vars); + + if (!bp->dcbx_port_params.ets.enabled) + return; + + if (CHIP_IS_E3B0(bp)) + bnx2x_dcbx_update_ets_config(bp); + else + bnx2x_dcbx_2cos_limit_update_ets_config(bp); +} + #ifdef BCM_DCBNL static int bnx2x_dcbx_read_shmem_remote_mib(struct bnx2x *bp) { @@ -1113,7 +1160,7 @@ static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, /* If we join a group and one is strict * than the bw rulls */ cos_data->data[entry].strict = - BNX2X_DCBX_COS_HIGH_STRICT; + BNX2X_DCBX_STRICT_COS_HIGHEST; } if ((0 == cos_data->data[0].pri_join_mask) && (0 == cos_data->data[1].pri_join_mask)) @@ -1125,7 +1172,7 @@ static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, #define POWER_OF_2(x) ((0 != x) && (0 == (x & (x-1)))) #endif -static void bxn2x_dcbx_single_pg_to_cos_params(struct bnx2x *bp, +static void bnx2x_dcbx_2cos_limit_cee_single_pg_to_cos_params(struct bnx2x *bp, struct pg_help_data *pg_help_data, struct cos_help_data *cos_data, u32 pri_join_mask, @@ -1205,14 +1252,16 @@ static void bxn2x_dcbx_single_pg_to_cos_params(struct bnx2x *bp, if (DCBX_PFC_PRI_GET_PAUSE(bp, pri_join_mask) > DCBX_PFC_PRI_GET_NON_PAUSE(bp, pri_join_mask)) { cos_data->data[0].strict = - BNX2X_DCBX_COS_HIGH_STRICT; + BNX2X_DCBX_STRICT_COS_HIGHEST; cos_data->data[1].strict = - BNX2X_DCBX_COS_LOW_STRICT; + BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI( + BNX2X_DCBX_STRICT_COS_HIGHEST); } else { cos_data->data[0].strict = - BNX2X_DCBX_COS_LOW_STRICT; + BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI( + BNX2X_DCBX_STRICT_COS_HIGHEST); cos_data->data[1].strict = - BNX2X_DCBX_COS_HIGH_STRICT; + BNX2X_DCBX_STRICT_COS_HIGHEST; } /* Pauseable */ cos_data->data[0].pausable = true; @@ -1248,13 +1297,16 @@ static void bxn2x_dcbx_single_pg_to_cos_params(struct bnx2x *bp, * and that with the highest priority * gets the highest strict priority in the arbiter. */ - cos_data->data[0].strict = BNX2X_DCBX_COS_LOW_STRICT; - cos_data->data[1].strict = BNX2X_DCBX_COS_HIGH_STRICT; + cos_data->data[0].strict = + BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI( + BNX2X_DCBX_STRICT_COS_HIGHEST); + cos_data->data[1].strict = + BNX2X_DCBX_STRICT_COS_HIGHEST; } } } -static void bnx2x_dcbx_two_pg_to_cos_params( +static void bnx2x_dcbx_2cos_limit_cee_two_pg_to_cos_params( struct bnx2x *bp, struct pg_help_data *pg_help_data, struct dcbx_ets_feature *ets, @@ -1264,7 +1316,7 @@ static void bnx2x_dcbx_two_pg_to_cos_params( u8 num_of_dif_pri) { u8 i = 0; - u8 pg[E2_NUM_OF_COS] = {0}; + u8 pg[DCBX_COS_MAX_NUM_E2] = { 0 }; /* If there are both pauseable and non-pauseable priorities, * the pauseable priorities go to the first queue and @@ -1320,16 +1372,68 @@ static void bnx2x_dcbx_two_pg_to_cos_params( } /* There can be only one strict pg */ - for (i = 0 ; i < E2_NUM_OF_COS; i++) { + for (i = 0 ; i < ARRAY_SIZE(pg); i++) { if (pg[i] < DCBX_MAX_NUM_PG_BW_ENTRIES) cos_data->data[i].cos_bw = DCBX_PG_BW_GET(ets->pg_bw_tbl, pg[i]); else - cos_data->data[i].strict = BNX2X_DCBX_COS_HIGH_STRICT; + cos_data->data[i].strict = + BNX2X_DCBX_STRICT_COS_HIGHEST; + } +} + +static int bnx2x_dcbx_join_pgs( + struct bnx2x *bp, + struct dcbx_ets_feature *ets, + struct pg_help_data *pg_help_data, + u8 required_num_of_pg) +{ + u8 entry_joined = pg_help_data->num_of_pg - 1; + u8 entry_removed = entry_joined + 1; + u8 pg_joined = 0; + + if (required_num_of_pg == 0 || ARRAY_SIZE(pg_help_data->data) + <= pg_help_data->num_of_pg) { + + BNX2X_ERR("required_num_of_pg can't be zero\n"); + return -EINVAL; } + + while (required_num_of_pg < pg_help_data->num_of_pg) { + entry_joined = pg_help_data->num_of_pg - 2; + entry_removed = entry_joined + 1; + /* protect index */ + entry_removed %= ARRAY_SIZE(pg_help_data->data); + + pg_help_data->data[entry_joined].pg_priority |= + pg_help_data->data[entry_removed].pg_priority; + + pg_help_data->data[entry_joined].num_of_dif_pri += + pg_help_data->data[entry_removed].num_of_dif_pri; + + if (pg_help_data->data[entry_joined].pg == DCBX_STRICT_PRI_PG || + pg_help_data->data[entry_removed].pg == DCBX_STRICT_PRI_PG) + /* Entries joined strict priority rules */ + pg_help_data->data[entry_joined].pg = + DCBX_STRICT_PRI_PG; + else { + /* Entries can be joined join BW */ + pg_joined = DCBX_PG_BW_GET(ets->pg_bw_tbl, + pg_help_data->data[entry_joined].pg) + + DCBX_PG_BW_GET(ets->pg_bw_tbl, + pg_help_data->data[entry_removed].pg); + + DCBX_PG_BW_SET(ets->pg_bw_tbl, + pg_help_data->data[entry_joined].pg, pg_joined); + } + /* Joined the entries */ + pg_help_data->num_of_pg--; + } + + return 0; } -static void bnx2x_dcbx_three_pg_to_cos_params( +static void bnx2x_dcbx_2cos_limit_cee_three_pg_to_cos_params( struct bnx2x *bp, struct pg_help_data *pg_help_data, struct dcbx_ets_feature *ets, @@ -1401,102 +1505,272 @@ static void bnx2x_dcbx_three_pg_to_cos_params( /* If we join a group and one is strict * than the bw rulls */ cos_data->data[1].strict = - BNX2X_DCBX_COS_HIGH_STRICT; + BNX2X_DCBX_STRICT_COS_HIGHEST; } } } } -static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp, +static void bnx2x_dcbx_2cos_limit_cee_fill_cos_params(struct bnx2x *bp, struct pg_help_data *help_data, struct dcbx_ets_feature *ets, - u32 *pg_pri_orginal_spread) + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + u32 pri_join_mask, + u8 num_of_dif_pri) { - struct cos_help_data cos_data ; - u8 i = 0; - u32 pri_join_mask = 0; - u8 num_of_dif_pri = 0; - memset(&cos_data, 0, sizeof(cos_data)); - /* Validate the pg value */ - for (i = 0; i < help_data->num_of_pg ; i++) { - if (DCBX_STRICT_PRIORITY != help_data->data[i].pg && - DCBX_MAX_NUM_PG_BW_ENTRIES <= help_data->data[i].pg) - BNX2X_ERR("Invalid pg[%d] data %x\n", i, - help_data->data[i].pg); - pri_join_mask |= help_data->data[i].pg_priority; - num_of_dif_pri += help_data->data[i].num_of_dif_pri; - } - - /* default settings */ - cos_data.num_of_cos = 2; - for (i = 0; i < E2_NUM_OF_COS ; i++) { - cos_data.data[i].pri_join_mask = pri_join_mask; - cos_data.data[i].pausable = false; - cos_data.data[i].strict = BNX2X_DCBX_COS_NOT_STRICT; - cos_data.data[i].cos_bw = DCBX_INVALID_COS_BW; - } + /* default E2 settings */ + cos_data->num_of_cos = DCBX_COS_MAX_NUM_E2; switch (help_data->num_of_pg) { case 1: - - bxn2x_dcbx_single_pg_to_cos_params( + bnx2x_dcbx_2cos_limit_cee_single_pg_to_cos_params( bp, help_data, - &cos_data, + cos_data, pri_join_mask, num_of_dif_pri); break; case 2: - bnx2x_dcbx_two_pg_to_cos_params( + bnx2x_dcbx_2cos_limit_cee_two_pg_to_cos_params( bp, help_data, ets, - &cos_data, + cos_data, pg_pri_orginal_spread, pri_join_mask, num_of_dif_pri); break; case 3: - bnx2x_dcbx_three_pg_to_cos_params( + bnx2x_dcbx_2cos_limit_cee_three_pg_to_cos_params( bp, help_data, ets, - &cos_data, + cos_data, pg_pri_orginal_spread, pri_join_mask, num_of_dif_pri); - break; default: BNX2X_ERR("Wrong pg_help_data.num_of_pg\n"); bnx2x_dcbx_ets_disabled_entry_data(bp, - &cos_data, pri_join_mask); + cos_data, pri_join_mask); + } +} + +static int bnx2x_dcbx_spread_strict_pri(struct bnx2x *bp, + struct cos_help_data *cos_data, + u8 entry, + u8 num_spread_of_entries, + u8 strict_app_pris) +{ + u8 strict_pri = BNX2X_DCBX_STRICT_COS_HIGHEST; + u8 num_of_app_pri = MAX_PFC_PRIORITIES; + u8 app_pri_bit = 0; + + while (num_spread_of_entries && num_of_app_pri > 0) { + app_pri_bit = 1 << (num_of_app_pri - 1); + if (app_pri_bit & strict_app_pris) { + struct cos_entry_help_data *data = &cos_data-> + data[entry]; + num_spread_of_entries--; + if (num_spread_of_entries == 0) { + /* last entry needed put all the entries left */ + data->cos_bw = DCBX_INVALID_COS_BW; + data->strict = strict_pri; + data->pri_join_mask = strict_app_pris; + data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp, + data->pri_join_mask); + } else { + strict_app_pris &= ~app_pri_bit; + + data->cos_bw = DCBX_INVALID_COS_BW; + data->strict = strict_pri; + data->pri_join_mask = app_pri_bit; + data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp, + data->pri_join_mask); + } + + strict_pri = + BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI(strict_pri); + entry++; + } + + num_of_app_pri--; + } + + if (num_spread_of_entries) + return -EINVAL; + + return 0; +} + +static u8 bnx2x_dcbx_cee_fill_strict_pri(struct bnx2x *bp, + struct cos_help_data *cos_data, + u8 entry, + u8 num_spread_of_entries, + u8 strict_app_pris) +{ + + if (bnx2x_dcbx_spread_strict_pri(bp, cos_data, entry, + num_spread_of_entries, + strict_app_pris)) { + struct cos_entry_help_data *data = &cos_data-> + data[entry]; + /* Fill BW entry */ + data->cos_bw = DCBX_INVALID_COS_BW; + data->strict = BNX2X_DCBX_STRICT_COS_HIGHEST; + data->pri_join_mask = strict_app_pris; + data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp, + data->pri_join_mask); + return 1; + } + + return num_spread_of_entries; +} + +static void bnx2x_dcbx_cee_fill_cos_params(struct bnx2x *bp, + struct pg_help_data *help_data, + struct dcbx_ets_feature *ets, + struct cos_help_data *cos_data, + u32 pri_join_mask) + +{ + u8 need_num_of_entries = 0; + u8 i = 0; + u8 entry = 0; + + /* + * if the number of requested PG-s in CEE is greater than 3 + * then the results are not determined since this is a violation + * of the standard. + */ + if (help_data->num_of_pg > DCBX_COS_MAX_NUM_E3B0) { + if (bnx2x_dcbx_join_pgs(bp, ets, help_data, + DCBX_COS_MAX_NUM_E3B0)) { + BNX2X_ERR("Unable to reduce the number of PGs -" + "we will disables ETS\n"); + bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data, + pri_join_mask); + return; + } + } + + for (i = 0 ; i < help_data->num_of_pg; i++) { + struct pg_entry_help_data *pg = &help_data->data[i]; + if (pg->pg < DCBX_MAX_NUM_PG_BW_ENTRIES) { + struct cos_entry_help_data *data = &cos_data-> + data[entry]; + /* Fill BW entry */ + data->cos_bw = DCBX_PG_BW_GET(ets->pg_bw_tbl, pg->pg); + data->strict = BNX2X_DCBX_STRICT_INVALID; + data->pri_join_mask = pg->pg_priority; + data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp, + data->pri_join_mask); + + entry++; + } else { + need_num_of_entries = min_t(u8, + (u8)pg->num_of_dif_pri, + (u8)DCBX_COS_MAX_NUM_E3B0 - + help_data->num_of_pg + 1); + /* + * If there are still VOQ-s which have no associated PG, + * then associate these VOQ-s to PG15. These PG-s will + * be used for SP between priorities on PG15. + */ + entry += bnx2x_dcbx_cee_fill_strict_pri(bp, cos_data, + entry, need_num_of_entries, pg->pg_priority); + } + } + + /* the entry will represent the number of COSes used */ + cos_data->num_of_cos = entry; +} +static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp, + struct pg_help_data *help_data, + struct dcbx_ets_feature *ets, + u32 *pg_pri_orginal_spread) +{ + struct cos_help_data cos_data; + u8 i = 0; + u32 pri_join_mask = 0; + u8 num_of_dif_pri = 0; + + memset(&cos_data, 0, sizeof(cos_data)); + + /* Validate the pg value */ + for (i = 0; i < help_data->num_of_pg ; i++) { + if (DCBX_STRICT_PRIORITY != help_data->data[i].pg && + DCBX_MAX_NUM_PG_BW_ENTRIES <= help_data->data[i].pg) + BNX2X_ERR("Invalid pg[%d] data %x\n", i, + help_data->data[i].pg); + pri_join_mask |= help_data->data[i].pg_priority; + num_of_dif_pri += help_data->data[i].num_of_dif_pri; + } + + /* defaults */ + cos_data.num_of_cos = 1; + for (i = 0; i < ARRAY_SIZE(cos_data.data); i++) { + cos_data.data[i].pri_join_mask = 0; + cos_data.data[i].pausable = false; + cos_data.data[i].strict = BNX2X_DCBX_STRICT_INVALID; + cos_data.data[i].cos_bw = DCBX_INVALID_COS_BW; } + if (CHIP_IS_E3B0(bp)) + bnx2x_dcbx_cee_fill_cos_params(bp, help_data, ets, + &cos_data, pri_join_mask); + else /* E2 + E3A0 */ + bnx2x_dcbx_2cos_limit_cee_fill_cos_params(bp, + help_data, ets, + &cos_data, + pg_pri_orginal_spread, + pri_join_mask, + num_of_dif_pri); + + for (i = 0; i < cos_data.num_of_cos ; i++) { - struct bnx2x_dcbx_cos_params *params = + struct bnx2x_dcbx_cos_params *p = &bp->dcbx_port_params.ets.cos_params[i]; - params->pauseable = cos_data.data[i].pausable; - params->strict = cos_data.data[i].strict; - params->bw_tbl = cos_data.data[i].cos_bw; - if (params->pauseable) { - params->pri_bitmask = - DCBX_PFC_PRI_GET_PAUSE(bp, - cos_data.data[i].pri_join_mask); + p->strict = cos_data.data[i].strict; + p->bw_tbl = cos_data.data[i].cos_bw; + p->pri_bitmask = cos_data.data[i].pri_join_mask; + p->pauseable = cos_data.data[i].pausable; + + /* sanity */ + if (p->bw_tbl != DCBX_INVALID_COS_BW || + p->strict != BNX2X_DCBX_STRICT_INVALID) { + if (p->pri_bitmask == 0) + BNX2X_ERR("Invalid pri_bitmask for %d\n", i); + + if (CHIP_IS_E2(bp) || CHIP_IS_E3A0(bp)) { + + if (p->pauseable && + DCBX_PFC_PRI_GET_NON_PAUSE(bp, + p->pri_bitmask) != 0) + BNX2X_ERR("Inconsistent config for " + "pausable COS %d\n", i); + + if (!p->pauseable && + DCBX_PFC_PRI_GET_PAUSE(bp, + p->pri_bitmask) != 0) + BNX2X_ERR("Inconsistent config for " + "nonpausable COS %d\n", i); + } + } + + if (p->pauseable) DP(NETIF_MSG_LINK, "COS %d PAUSABLE prijoinmask 0x%x\n", i, cos_data.data[i].pri_join_mask); - } else { - params->pri_bitmask = - DCBX_PFC_PRI_GET_NON_PAUSE(bp, - cos_data.data[i].pri_join_mask); + else DP(NETIF_MSG_LINK, "COS %d NONPAUSABLE prijoinmask " "0x%x\n", i, cos_data.data[i].pri_join_mask); - } } bp->dcbx_port_params.ets.num_of_cos = cos_data.num_of_cos ; @@ -1516,7 +1790,7 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, } } -static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) +static void bnx2x_dcbx_fw_struct(struct bnx2x *bp) { struct flow_control_configuration *pfc_fw_cfg = NULL; u16 pri_bit = 0; @@ -1838,10 +2112,12 @@ static u8 bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num) if (bp->dcb_state) { switch (tcid) { case DCB_NUMTCS_ATTR_PG: - *num = E2_NUM_OF_COS; + *num = CHIP_IS_E3B0(bp) ? DCBX_COS_MAX_NUM_E3B0 : + DCBX_COS_MAX_NUM_E2; break; case DCB_NUMTCS_ATTR_PFC: - *num = E2_NUM_OF_COS; + *num = CHIP_IS_E3B0(bp) ? DCBX_COS_MAX_NUM_E3B0 : + DCBX_COS_MAX_NUM_E2; break; default: rval = -EINVAL; diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h index b3a655ff2ba..2c6a3bca6f2 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.h +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -27,22 +27,30 @@ struct bnx2x_dcbx_app_params { u32 traffic_type_priority[LLFC_DRIVER_TRAFFIC_TYPE_MAX]; }; -#define E2_NUM_OF_COS 2 -#define BNX2X_DCBX_COS_NOT_STRICT 0 -#define BNX2X_DCBX_COS_LOW_STRICT 1 -#define BNX2X_DCBX_COS_HIGH_STRICT 2 +#define DCBX_COS_MAX_NUM_E2 DCBX_E2E3_MAX_NUM_COS +/* bnx2x currently limits numbers of supported COSes to 3 to be extended to 6 */ +#define BNX2X_MAX_COS_SUPPORT 3 +#define DCBX_COS_MAX_NUM_E3B0 BNX2X_MAX_COS_SUPPORT +#define DCBX_COS_MAX_NUM BNX2X_MAX_COS_SUPPORT struct bnx2x_dcbx_cos_params { u32 bw_tbl; u32 pri_bitmask; + /* + * strict priority: valid values are 0..5; 0 is highest priority. + * There can't be two COSes with the same priority. + */ u8 strict; +#define BNX2X_DCBX_STRICT_INVALID DCBX_COS_MAX_NUM +#define BNX2X_DCBX_STRICT_COS_HIGHEST 0 +#define BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI(sp) ((sp) + 1) u8 pauseable; }; struct bnx2x_dcbx_pg_params { u32 enabled; u8 num_of_cos; /* valid COS entries */ - struct bnx2x_dcbx_cos_params cos_params[E2_NUM_OF_COS]; + struct bnx2x_dcbx_cos_params cos_params[DCBX_COS_MAX_NUM]; }; struct bnx2x_dcbx_pfc_params { @@ -134,7 +142,7 @@ struct cos_entry_help_data { }; struct cos_help_data { - struct cos_entry_help_data data[E2_NUM_OF_COS]; + struct cos_entry_help_data data[DCBX_COS_MAX_NUM]; u8 num_of_cos; }; @@ -150,6 +158,8 @@ struct cos_help_data { ((pg_pri) & (DCBX_PFC_PRI_PAUSE_MASK(bp))) #define DCBX_PFC_PRI_GET_NON_PAUSE(bp, pg_pri) \ (DCBX_PFC_PRI_NON_PAUSE_MASK(bp) & (pg_pri)) +#define DCBX_IS_PFC_PRI_SOME_PAUSE(bp, pg_pri) \ + (0 != DCBX_PFC_PRI_GET_PAUSE(bp, pg_pri)) #define IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pg_pri) \ (pg_pri == DCBX_PFC_PRI_GET_PAUSE((bp), (pg_pri))) #define IS_DCBX_PFC_PRI_ONLY_NON_PAUSE(bp, pg_pri)\ @@ -172,7 +182,6 @@ struct pg_help_data { /* forward DCB/PFC related declarations */ struct bnx2x; -void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp); void bnx2x_dcbx_update(struct work_struct *work); void bnx2x_dcbx_init_params(struct bnx2x *bp); void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled); -- cgit v1.2.3-70-g09d2 From b96368e9365a4db7429da87cfd25bb54b24954f8 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 14 Jun 2011 01:34:46 +0000 Subject: bnx2x: Update date to 2011/06/13 and version to 1.70.00-0 Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 36961494e00..69fc7280be3 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,8 +22,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.62.12-0" -#define DRV_MODULE_RELDATE "2011/03/20" +#define DRV_MODULE_VERSION "1.70.00-0" +#define DRV_MODULE_RELDATE "2011/06/13" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_DCB) -- cgit v1.2.3-70-g09d2 From 0e6cf6a9e3cf911577b1dde0dc724f634e4ca119 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:38:55 +0000 Subject: tg3: Workaround tagged status update bug On rare occasions, writing the tag to the interrupt mailbox does not reenable interrupts. This patch fixes the problem by reissuing the mailbox update. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 38 +++++++++++++++++++++++++++++++++++++- drivers/net/tg3.h | 3 +++ 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index aa1d1defc82..46352da36a8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7754,6 +7754,9 @@ static void tg3_rings_reset(struct tg3 *tp) /* Disable interrupts */ tw32_mailbox_f(tp->napi[0].int_mbox, 1); + tp->napi[0].chk_msi_cnt = 0; + tp->napi[0].last_rx_cons = 0; + tp->napi[0].last_tx_cons = 0; /* Zero mailbox registers. */ if (tg3_flag(tp, SUPPORT_MSIX)) { @@ -7764,6 +7767,9 @@ static void tg3_rings_reset(struct tg3 *tp) tw32_mailbox(tp->napi[i].prodmbox, 0); tw32_rx_mbox(tp->napi[i].consmbox, 0); tw32_mailbox_f(tp->napi[i].int_mbox, 1); + tp->napi[0].chk_msi_cnt = 0; + tp->napi[i].last_rx_cons = 0; + tp->napi[i].last_tx_cons = 0; } if (!tg3_flag(tp, ENABLE_TSS)) tw32_mailbox(tp->napi[0].prodmbox, 0); @@ -8819,6 +8825,30 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp) TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT); } +static void tg3_chk_missed_msi(struct tg3 *tp) +{ + u32 i; + + for (i = 0; i < tp->irq_cnt; i++) { + struct tg3_napi *tnapi = &tp->napi[i]; + + if (tg3_has_work(tnapi)) { + if (tnapi->last_rx_cons == tnapi->rx_rcb_ptr && + tnapi->last_tx_cons == tnapi->tx_cons) { + if (tnapi->chk_msi_cnt < 1) { + tnapi->chk_msi_cnt++; + return; + } + tw32_mailbox(tnapi->int_mbox, + tnapi->last_tag << 24); + } + } + tnapi->chk_msi_cnt = 0; + tnapi->last_rx_cons = tnapi->rx_rcb_ptr; + tnapi->last_tx_cons = tnapi->tx_cons; + } +} + static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; @@ -8828,6 +8858,10 @@ static void tg3_timer(unsigned long __opaque) spin_lock(&tp->lock); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + tg3_chk_missed_msi(tp); + if (!tg3_flag(tp, TAGGED_STATUS)) { /* All of this garbage is because when using non-tagged * IRQ status the mailbox/status_block protocol the chip @@ -9303,7 +9337,9 @@ static int tg3_open(struct net_device *dev) tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_free_rings(tp); } else { - if (tg3_flag(tp, TAGGED_STATUS)) + if (tg3_flag(tp, TAGGED_STATUS) && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) tp->timer_offset = HZ; else tp->timer_offset = HZ / 10; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 5b3d2f34da7..3c113c1e9d3 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2800,6 +2800,7 @@ struct tg3_napi { struct tg3 *tp; struct tg3_hw_status *hw_status; + u32 chk_msi_cnt; u32 last_tag; u32 last_irq_tag; u32 int_mbox; @@ -2807,6 +2808,7 @@ struct tg3_napi { u32 consmbox ____cacheline_aligned; u32 rx_rcb_ptr; + u32 last_rx_cons; u16 *rx_rcb_prod_idx; struct tg3_rx_prodring_set prodring; struct tg3_rx_buffer_desc *rx_rcb; @@ -2814,6 +2816,7 @@ struct tg3_napi { u32 tx_prod ____cacheline_aligned; u32 tx_cons; u32 tx_pending; + u32 last_tx_cons; u32 prodmbox; struct tg3_tx_buffer_desc *tx_ring; struct ring_info *tx_buffers; -- cgit v1.2.3-70-g09d2 From daf9a55387df8f429d1219bbdabba1ab33d2a479 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:38:56 +0000 Subject: tg3: Remove 40BIT_DMA_LIMIT_BUG This patch removes the 40BIT_DMA_LIMIT_BUG flag. There already exists a flag for this purpose (TG3_FLAG_40BIT_DMA_BUG) and was already being used in the correct spot. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 ++------ drivers/net/tg3.h | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 46352da36a8..c4f193eba82 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6022,8 +6022,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) tg3_4g_overflow_test(mapping, len)) would_hit_hwbug = 1; - if (tg3_flag(tp, 40BIT_DMA_LIMIT_BUG) && - tg3_40bit_overflow_test(tp, mapping, len)) + if (tg3_40bit_overflow_test(tp, mapping, len)) would_hit_hwbug = 1; if (tg3_flag(tp, 5701_DMA_BUG)) @@ -6060,8 +6059,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) tg3_4g_overflow_test(mapping, len)) would_hit_hwbug = 1; - if (tg3_flag(tp, 40BIT_DMA_LIMIT_BUG) && - tg3_40bit_overflow_test(tp, mapping, len)) + if (tg3_40bit_overflow_test(tp, mapping, len)) would_hit_hwbug = 1; if (tg3_flag(tp, HW_TSO_1) || @@ -13712,8 +13710,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tg3_flag(tp, 5755_PLUS)) tg3_flag_set(tp, SHORT_DMA_BUG); - else - tg3_flag_set(tp, 40BIT_DMA_LIMIT_BUG); if (tg3_flag(tp, 5717_PLUS)) tg3_flag_set(tp, LRG_PROD_RING_CAP); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 3c113c1e9d3..4f5dbf6adfe 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2897,7 +2897,6 @@ enum TG3_FLAGS { TG3_FLAG_ENABLE_RSS, TG3_FLAG_ENABLE_TSS, TG3_FLAG_4G_DMA_BNDRY_BUG, - TG3_FLAG_40BIT_DMA_LIMIT_BUG, TG3_FLAG_SHORT_DMA_BUG, TG3_FLAG_USE_JUMBO_BDFLAG, TG3_FLAG_L1PLLPD_EN, -- cgit v1.2.3-70-g09d2 From eb69d564a3f34df602bd9b0fae94e14fad23de2d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:38:57 +0000 Subject: tg3: Remove 4G_DMA_BNDRY_BUG flag Now that all chips have this bug, the flag checks become useless code. This patch removes the flag. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 14 +++----------- drivers/net/tg3.h | 1 - 2 files changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c4f193eba82..8483664b9ce 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5822,8 +5822,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, /* Make sure new skb does not cross any 4G boundaries. * Drop the packet if it does. */ - } else if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) && - tg3_4g_overflow_test(new_addr, new_skb->len)) { + } else if (tg3_4g_overflow_test(new_addr, new_skb->len)) { pci_unmap_single(tp->pdev, new_addr, new_skb->len, PCI_DMA_TODEVICE); ret = -1; @@ -6018,8 +6017,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8) would_hit_hwbug = 1; - if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) && - tg3_4g_overflow_test(mapping, len)) + if (tg3_4g_overflow_test(mapping, len)) would_hit_hwbug = 1; if (tg3_40bit_overflow_test(tp, mapping, len)) @@ -6055,8 +6053,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) len <= 8) would_hit_hwbug = 1; - if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) && - tg3_4g_overflow_test(mapping, len)) + if (tg3_4g_overflow_test(mapping, len)) would_hit_hwbug = 1; if (tg3_40bit_overflow_test(tp, mapping, len)) @@ -13703,11 +13700,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } } - /* All chips can get confused if TX buffers - * straddle the 4GB address boundary. - */ - tg3_flag_set(tp, 4G_DMA_BNDRY_BUG); - if (tg3_flag(tp, 5755_PLUS)) tg3_flag_set(tp, SHORT_DMA_BUG); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 4f5dbf6adfe..fc33566b9f9 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2896,7 +2896,6 @@ enum TG3_FLAGS { TG3_FLAG_NO_NVRAM, TG3_FLAG_ENABLE_RSS, TG3_FLAG_ENABLE_TSS, - TG3_FLAG_4G_DMA_BNDRY_BUG, TG3_FLAG_SHORT_DMA_BUG, TG3_FLAG_USE_JUMBO_BDFLAG, TG3_FLAG_L1PLLPD_EN, -- cgit v1.2.3-70-g09d2 From 727a6d9f39604b5592e474295960fceeb523ae4f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:38:58 +0000 Subject: tg3: Add more selfboot formats to NVRAM selftest This patch adds more selfboot formats to the NVRAM selftest. It also changes the code to return an error on an unsupported NVRAM format. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8483664b9ce..b4f5e923515 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10470,6 +10470,9 @@ error: #define NVRAM_SELFBOOT_FORMAT1_0_SIZE 0x14 #define NVRAM_SELFBOOT_FORMAT1_2_SIZE 0x18 #define NVRAM_SELFBOOT_FORMAT1_3_SIZE 0x1c +#define NVRAM_SELFBOOT_FORMAT1_4_SIZE 0x20 +#define NVRAM_SELFBOOT_FORMAT1_5_SIZE 0x24 +#define NVRAM_SELFBOOT_FORMAT1_6_SIZE 0x4c #define NVRAM_SELFBOOT_HW_SIZE 0x20 #define NVRAM_SELFBOOT_DATA_SIZE 0x1c @@ -10500,8 +10503,17 @@ static int tg3_test_nvram(struct tg3 *tp) case TG3_EEPROM_SB_REVISION_3: size = NVRAM_SELFBOOT_FORMAT1_3_SIZE; break; + case TG3_EEPROM_SB_REVISION_4: + size = NVRAM_SELFBOOT_FORMAT1_4_SIZE; + break; + case TG3_EEPROM_SB_REVISION_5: + size = NVRAM_SELFBOOT_FORMAT1_5_SIZE; + break; + case TG3_EEPROM_SB_REVISION_6: + size = NVRAM_SELFBOOT_FORMAT1_6_SIZE; + break; default: - return 0; + return -EIO; } } else return 0; -- cgit v1.2.3-70-g09d2 From ad0fad9eb2577ffc2d1a4fd522e6a71fd51127fd Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:38:59 +0000 Subject: tg3: Fix EEE debounce timer values This patch fixes the EEE debounce timer values. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index fc33566b9f9..54441a346cb 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1118,10 +1118,10 @@ #define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000 #define TG3_CPMU_EEE_DBTMR1 0x000036b4 #define TG3_CPMU_DBTMR1_PCIEXIT_2047US 0x07ff0000 -#define TG3_CPMU_DBTMR1_LNKIDLE_2047US 0x000070ff +#define TG3_CPMU_DBTMR1_LNKIDLE_2047US 0x000007ff #define TG3_CPMU_EEE_DBTMR2 0x000036b8 #define TG3_CPMU_DBTMR2_APE_TX_2047US 0x07ff0000 -#define TG3_CPMU_DBTMR2_TXIDXEQ_2047US 0x000070ff +#define TG3_CPMU_DBTMR2_TXIDXEQ_2047US 0x000007ff #define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc #define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000 #define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004 -- cgit v1.2.3-70-g09d2 From 5bb09778e2196770d218e82904f15b558d9a1e50 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:39:00 +0000 Subject: tg3: Show flowctrl settings through get_settings() This patch adds code to present the flow control advertisements through the ethtool get_settings callback. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b4f5e923515..7b1e2abf0ce 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9936,6 +9936,18 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) } cmd->advertising = tp->link_config.advertising; + if (tg3_flag(tp, PAUSE_AUTONEG)) { + if (tp->link_config.flowctrl & FLOW_CTRL_RX) { + if (tp->link_config.flowctrl & FLOW_CTRL_TX) { + cmd->advertising |= ADVERTISED_Pause; + } else { + cmd->advertising |= ADVERTISED_Pause | + ADVERTISED_Asym_Pause; + } + } else if (tp->link_config.flowctrl & FLOW_CTRL_TX) { + cmd->advertising |= ADVERTISED_Asym_Pause; + } + } if (netif_running(dev)) { ethtool_cmd_speed_set(cmd, tp->link_config.active_speed); cmd->duplex = tp->link_config.active_duplex; -- cgit v1.2.3-70-g09d2 From 221c56373ee7088dd3015b928782d5e70dc5074e Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:39:01 +0000 Subject: tg3: Migrate phy preprocessor defs to system defs This patch changes to code to use some of the preprocessor definitions from mii.h over its homegrown equivalents. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 26 ++++++++++++-------------- drivers/net/tg3.h | 8 -------- include/linux/mii.h | 2 ++ 3 files changed, 14 insertions(+), 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7b1e2abf0ce..da5e9105b9f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -861,7 +861,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val) int ret; if ((tp->phy_flags & TG3_PHYFLG_IS_FET) && - (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL)) + (reg == MII_CTRL1000 || reg == MII_TG3_AUX_CTRL)) return 0; if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { @@ -1981,15 +1981,14 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) /* Set full-duplex, 1000 mbps. */ tg3_writephy(tp, MII_BMCR, - BMCR_FULLDPLX | TG3_BMCR_SPEED1000); + BMCR_FULLDPLX | BMCR_SPEED1000); /* Set to master mode. */ - if (tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig)) + if (tg3_readphy(tp, MII_CTRL1000, &phy9_orig)) continue; - tg3_writephy(tp, MII_TG3_CTRL, - (MII_TG3_CTRL_AS_MASTER | - MII_TG3_CTRL_ENABLE_AS_MASTER)); + tg3_writephy(tp, MII_CTRL1000, + CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); if (err) @@ -2014,7 +2013,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); - tg3_writephy(tp, MII_TG3_CTRL, phy9_orig); + tg3_writephy(tp, MII_CTRL1000, phy9_orig); if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) { reg32 &= ~0x3000; @@ -2958,16 +2957,15 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) new_adv = 0; if (advertise & ADVERTISED_1000baseT_Half) - new_adv |= MII_TG3_CTRL_ADV_1000_HALF; + new_adv |= ADVERTISE_1000HALF; if (advertise & ADVERTISED_1000baseT_Full) - new_adv |= MII_TG3_CTRL_ADV_1000_FULL; + new_adv |= ADVERTISE_1000FULL; if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) - new_adv |= (MII_TG3_CTRL_AS_MASTER | - MII_TG3_CTRL_ENABLE_AS_MASTER); + new_adv |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER; - err = tg3_writephy(tp, MII_TG3_CTRL, new_adv); + err = tg3_writephy(tp, MII_CTRL1000, new_adv); if (err) goto done; @@ -3076,7 +3074,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp) break; case SPEED_1000: - bmcr |= TG3_BMCR_SPEED1000; + bmcr |= BMCR_SPEED1000; break; } @@ -3153,7 +3151,7 @@ static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask) if (mask & ADVERTISED_1000baseT_Full) all_mask |= ADVERTISE_1000FULL; - if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl)) + if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl)) return 0; if ((tg3_ctrl & all_mask) != all_mask) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 54441a346cb..bedc3b4557b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2152,14 +2152,6 @@ /*** Tigon3 specific PHY MII registers. ***/ -#define TG3_BMCR_SPEED1000 0x0040 - -#define MII_TG3_CTRL 0x09 /* 1000-baseT control register */ -#define MII_TG3_CTRL_ADV_1000_HALF 0x0100 -#define MII_TG3_CTRL_ADV_1000_FULL 0x0200 -#define MII_TG3_CTRL_AS_MASTER 0x0800 -#define MII_TG3_CTRL_ENABLE_AS_MASTER 0x1000 - #define MII_TG3_MMD_CTRL 0x0d /* MMD Access Control register */ #define MII_TG3_MMD_CTRL_DATA_NOINC 0x4000 #define MII_TG3_MMD_ADDRESS 0x0e /* MMD Address Data register */ diff --git a/include/linux/mii.h b/include/linux/mii.h index 359fba88027..103113a2fd1 100644 --- a/include/linux/mii.h +++ b/include/linux/mii.h @@ -128,6 +128,8 @@ /* 1000BASE-T Control register */ #define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ #define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ +#define CTL1000_AS_MASTER 0x0800 +#define CTL1000_ENABLE_MASTER 0x1000 /* 1000BASE-T Status register */ #define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ -- cgit v1.2.3-70-g09d2 From 520b2756d9414cb6b0f6fc70714e95ee9248ebf4 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 13 Jun 2011 13:39:02 +0000 Subject: tg3: Create funcs for power source switching The power source switching code is about to get a little more complex. This patch seeks to simplify future power source switching patches by clarifying the existing code. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 201 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 119 insertions(+), 82 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index da5e9105b9f..ca6687a9422 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -107,6 +107,8 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) NETIF_MSG_RX_ERR | \ NETIF_MSG_TX_ERR) +#define TG3_GRC_LCLCTL_PWRSW_DELAY 100 + /* length of time before we decide the hardware is borked, * and dev->tx_timeout() should be called to fix the problem */ @@ -2165,6 +2167,118 @@ out: return 0; } +static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp) +{ + if (!tg3_flag(tp, IS_NIC)) + return 0; + + tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + return 0; +} + +static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp) +{ + u32 grc_local_ctrl; + + if (!tg3_flag(tp, IS_NIC) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) + return; + + grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1; + + tw32_wait_f(GRC_LOCAL_CTRL, + grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + tw32_wait_f(GRC_LOCAL_CTRL, + grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + tw32_wait_f(GRC_LOCAL_CTRL, + grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1, + TG3_GRC_LCLCTL_PWRSW_DELAY); +} + +static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) +{ + if (!tg3_flag(tp, IS_NIC)) + return; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + (GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1), + TG3_GRC_LCLCTL_PWRSW_DELAY); + } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) { + /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */ + u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1 | + tp->grc_local_ctrl; + tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2; + tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0; + tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + } else { + u32 no_gpio2; + u32 grc_local_ctrl = 0; + + /* Workaround to prevent overdrawing Amps. */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { + grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; + tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + } + + /* On 5753 and variants, GPIO2 cannot be used. */ + no_gpio2 = tp->nic_sram_data_cfg & + NIC_SRAM_DATA_CFG_NO_GPIO2; + + grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 | + GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT1 | + GRC_LCLCTRL_GPIO_OUTPUT2; + if (no_gpio2) { + grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | + GRC_LCLCTRL_GPIO_OUTPUT2); + } + tw32_wait_f(GRC_LOCAL_CTRL, + tp->grc_local_ctrl | grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; + + tw32_wait_f(GRC_LOCAL_CTRL, + tp->grc_local_ctrl | grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + if (!no_gpio2) { + grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; + tw32_wait_f(GRC_LOCAL_CTRL, + tp->grc_local_ctrl | grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + } + } +} + static void tg3_frob_aux_power(struct tg3 *tp) { bool need_vaux = false; @@ -2200,86 +2314,10 @@ static void tg3_frob_aux_power(struct tg3 *tp) if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF)) need_vaux = true; - if (need_vaux) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - (GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1), - 100); - } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) { - /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */ - u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1 | - tp->grc_local_ctrl; - tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); - - grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2; - tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); - - grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0; - tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); - } else { - u32 no_gpio2; - u32 grc_local_ctrl = 0; - - /* Workaround to prevent overdrawing Amps. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == - ASIC_REV_5714) { - grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - grc_local_ctrl, 100); - } - - /* On 5753 and variants, GPIO2 cannot be used. */ - no_gpio2 = tp->nic_sram_data_cfg & - NIC_SRAM_DATA_CFG_NO_GPIO2; - - grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT1 | - GRC_LCLCTRL_GPIO_OUTPUT2; - if (no_gpio2) { - grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT2); - } - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - grc_local_ctrl, 100); - - grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; - - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - grc_local_ctrl, 100); - - if (!no_gpio2) { - grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - grc_local_ctrl, 100); - } - } - } else { - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - (GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OUTPUT1), 100); - - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - GRC_LCLCTRL_GPIO_OE1, 100); - - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - (GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OUTPUT1), 100); - } - } + if (need_vaux) + tg3_pwrsrc_switch_to_vaux(tp); + else + tg3_pwrsrc_die_with_vmain(tp); } static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed) @@ -2624,8 +2662,7 @@ static int tg3_power_up(struct tg3 *tp) pci_set_power_state(tp->pdev, PCI_D0); /* Switch out of Vaux if it is a NIC */ - if (tg3_flag(tp, IS_NIC)) - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100); + tg3_pwrsrc_switch_to_vmain(tp); return 0; } -- cgit v1.2.3-70-g09d2 From 3c8def9776c3d4636291432522ea312f7a44be95 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 12 Jun 2011 20:01:58 +0000 Subject: be2net: support multiple TX queues This patch provides support for multiple TX queues. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 13 ++- drivers/net/benet/be_ethtool.c | 50 ++++++--- drivers/net/benet/be_main.c | 227 +++++++++++++++++++++++------------------ 3 files changed, 171 insertions(+), 119 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index a7db870d164..a36f5a6a846 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -87,6 +87,7 @@ static inline char *nic_name(struct pci_dev *pdev) #define MAX_RSS_QS 4 /* BE limit is 4 queues/port */ #define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ +#define MAX_TX_QS 8 #define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */ #define BE_NAPI_WEIGHT 64 #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ @@ -170,7 +171,6 @@ struct be_tx_stats { u32 be_tx_reqs; /* number of TX requests initiated */ u32 be_tx_stops; /* number of times TX Q was stopped */ u32 be_tx_wrbs; /* number of tx WRBs used */ - u32 be_tx_events; /* number of tx completion events */ u32 be_tx_compl; /* number of tx completion entries processed */ ulong be_tx_jiffies; u64 be_tx_bytes; @@ -184,6 +184,7 @@ struct be_tx_obj { struct be_queue_info cq; /* Remember the skbs that were transmitted */ struct sk_buff *sent_skb_list[TX_Q_LEN]; + struct be_tx_stats stats; }; /* Struct to remember the pages posted for rx frags */ @@ -319,8 +320,8 @@ struct be_adapter { /* TX Rings */ struct be_eq_obj tx_eq; - struct be_tx_obj tx_obj; - struct be_tx_stats tx_stats; + struct be_tx_obj tx_obj[MAX_TX_QS]; + u8 num_tx_qs; u32 cache_line_break[8]; @@ -391,7 +392,7 @@ struct be_adapter { extern const struct ethtool_ops be_ethtool_ops; #define msix_enabled(adapter) (adapter->num_msix_vec > 0) -#define tx_stats(adapter) (&adapter->tx_stats) +#define tx_stats(txo) (&txo->stats) #define rx_stats(rxo) (&rxo->stats) #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) @@ -405,6 +406,10 @@ extern const struct ethtool_ops be_ethtool_ops; for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\ i++, rxo++) +#define for_all_tx_queues(adapter, txo, i) \ + for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs; \ + i++, txo++) + #define PAGE_SHIFT_4K 12 #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index facfe3ca5c4..84e03a74786 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -52,12 +52,7 @@ static const struct be_ethtool_stat et_stats[] = { {NETSTAT_INFO(tx_errors)}, {NETSTAT_INFO(rx_dropped)}, {NETSTAT_INFO(tx_dropped)}, - {DRVSTAT_TX_INFO(be_tx_rate)}, - {DRVSTAT_TX_INFO(be_tx_reqs)}, - {DRVSTAT_TX_INFO(be_tx_wrbs)}, - {DRVSTAT_TX_INFO(be_tx_stops)}, - {DRVSTAT_TX_INFO(be_tx_events)}, - {DRVSTAT_TX_INFO(be_tx_compl)}, + {DRVSTAT_INFO(be_tx_events)}, {DRVSTAT_INFO(rx_crc_errors)}, {DRVSTAT_INFO(rx_alignment_symbol_errors)}, {DRVSTAT_INFO(rx_pause_frames)}, @@ -111,6 +106,16 @@ static const struct be_ethtool_stat et_rx_stats[] = { }; #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) +/* Stats related to multi TX queues */ +static const struct be_ethtool_stat et_tx_stats[] = { + {DRVSTAT_TX_INFO(be_tx_rate)}, + {DRVSTAT_TX_INFO(be_tx_reqs)}, + {DRVSTAT_TX_INFO(be_tx_wrbs)}, + {DRVSTAT_TX_INFO(be_tx_stops)}, + {DRVSTAT_TX_INFO(be_tx_compl)} +}; +#define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats)) + static const char et_self_tests[][ETH_GSTRING_LEN] = { "MAC Loopback test", "PHY Loopback test", @@ -253,17 +258,15 @@ be_get_ethtool_stats(struct net_device *netdev, { struct be_adapter *adapter = netdev_priv(netdev); struct be_rx_obj *rxo; + struct be_tx_obj *txo; void *p = NULL; - int i, j; + int i, j, base; for (i = 0; i < ETHTOOL_STATS_NUM; i++) { switch (et_stats[i].type) { case NETSTAT: p = &netdev->stats; break; - case DRVSTAT_TX: - p = &adapter->tx_stats; - break; case DRVSTAT: p = &adapter->drv_stats; break; @@ -274,6 +277,7 @@ be_get_ethtool_stats(struct net_device *netdev, *(u64 *)p: *(u32 *)p; } + base = ETHTOOL_STATS_NUM; for_all_rx_queues(adapter, rxo, j) { for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) { switch (et_rx_stats[i].type) { @@ -285,11 +289,21 @@ be_get_ethtool_stats(struct net_device *netdev, rxo->q.id; break; } - data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] = + data[base + j * ETHTOOL_RXSTATS_NUM + i] = (et_rx_stats[i].size == sizeof(u64)) ? *(u64 *)p: *(u32 *)p; } } + + base = ETHTOOL_STATS_NUM + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM; + for_all_tx_queues(adapter, txo, j) { + for (i = 0; i < ETHTOOL_TXSTATS_NUM; i++) { + p = (u8 *)&txo->stats + et_tx_stats[i].offset; + data[base + j * ETHTOOL_TXSTATS_NUM + i] = + (et_tx_stats[i].size == sizeof(u64)) ? + *(u64 *)p: *(u32 *)p; + } + } } static void @@ -312,6 +326,13 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset, data += ETH_GSTRING_LEN; } } + for (i = 0; i < adapter->num_tx_qs; i++) { + for (j = 0; j < ETHTOOL_TXSTATS_NUM; j++) { + sprintf(data, "txq%d: %s", i, + et_tx_stats[j].desc); + data += ETH_GSTRING_LEN; + } + } break; case ETH_SS_TEST: for (i = 0; i < ETHTOOL_TESTS_NUM; i++) { @@ -331,7 +352,8 @@ static int be_get_sset_count(struct net_device *netdev, int stringset) return ETHTOOL_TESTS_NUM; case ETH_SS_STATS: return ETHTOOL_STATS_NUM + - adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM; + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM + + adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM; default: return -EINVAL; } @@ -457,10 +479,10 @@ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) struct be_adapter *adapter = netdev_priv(netdev); ring->rx_max_pending = adapter->rx_obj[0].q.len; - ring->tx_max_pending = adapter->tx_obj.q.len; + ring->tx_max_pending = adapter->tx_obj[0].q.len; ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used); - ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); + ring->tx_pending = atomic_read(&adapter->tx_obj[0].q.used); } static void diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 6ddaa34121e..c4f564cd745 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -427,6 +427,7 @@ void netdev_stats_update(struct be_adapter *adapter) struct be_drv_stats *drvs = &adapter->drv_stats; struct net_device_stats *dev_stats = &adapter->netdev->stats; struct be_rx_obj *rxo; + struct be_tx_obj *txo; int i; memset(dev_stats, 0, sizeof(*dev_stats)); @@ -450,8 +451,10 @@ void netdev_stats_update(struct be_adapter *adapter) } } - dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts; - dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes; + for_all_tx_queues(adapter, txo, i) { + dev_stats->tx_packets += tx_stats(txo)->be_tx_pkts; + dev_stats->tx_bytes += tx_stats(txo)->be_tx_bytes; + } /* bad pkts received */ dev_stats->rx_errors = drvs->rx_crc_errors + @@ -554,9 +557,9 @@ static u32 be_calc_rate(u64 bytes, unsigned long ticks) return rate; } -static void be_tx_rate_update(struct be_adapter *adapter) +static void be_tx_rate_update(struct be_tx_obj *txo) { - struct be_tx_stats *stats = tx_stats(adapter); + struct be_tx_stats *stats = tx_stats(txo); ulong now = jiffies; /* Wrapped around? */ @@ -575,10 +578,11 @@ static void be_tx_rate_update(struct be_adapter *adapter) } } -static void be_tx_stats_update(struct be_adapter *adapter, +static void be_tx_stats_update(struct be_tx_obj *txo, u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped) { - struct be_tx_stats *stats = tx_stats(adapter); + struct be_tx_stats *stats = tx_stats(txo); + stats->be_tx_reqs++; stats->be_tx_wrbs += wrb_cnt; stats->be_tx_bytes += copied; @@ -682,14 +686,13 @@ static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb, } } -static int make_tx_wrbs(struct be_adapter *adapter, +static int make_tx_wrbs(struct be_adapter *adapter, struct be_queue_info *txq, struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb) { dma_addr_t busaddr; int i, copied = 0; struct device *dev = &adapter->pdev->dev; struct sk_buff *first_skb = skb; - struct be_queue_info *txq = &adapter->tx_obj.q; struct be_eth_wrb *wrb; struct be_eth_hdr_wrb *hdr; bool map_single = false; @@ -753,19 +756,19 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_tx_obj *tx_obj = &adapter->tx_obj; - struct be_queue_info *txq = &tx_obj->q; + struct be_tx_obj *txo = &adapter->tx_obj[skb_get_queue_mapping(skb)]; + struct be_queue_info *txq = &txo->q; u32 wrb_cnt = 0, copied = 0; u32 start = txq->head; bool dummy_wrb, stopped = false; wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb); - copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); + copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb); if (copied) { /* record the sent skb in the sent_skb table */ - BUG_ON(tx_obj->sent_skb_list[start]); - tx_obj->sent_skb_list[start] = skb; + BUG_ON(txo->sent_skb_list[start]); + txo->sent_skb_list[start] = skb; /* Ensure txq has space for the next skb; Else stop the queue * *BEFORE* ringing the tx doorbell, so that we serialze the @@ -774,13 +777,13 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, atomic_add(wrb_cnt, &txq->used); if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >= txq->len) { - netif_stop_queue(netdev); + netif_stop_subqueue(netdev, skb_get_queue_mapping(skb)); stopped = true; } be_txq_notify(adapter, txq->id, wrb_cnt); - be_tx_stats_update(adapter, wrb_cnt, copied, + be_tx_stats_update(txo, wrb_cnt, copied, skb_shinfo(skb)->gso_segs, stopped); } else { txq->head = start; @@ -1459,11 +1462,12 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq) return txcp; } -static u16 be_tx_compl_process(struct be_adapter *adapter, u16 last_index) +static u16 be_tx_compl_process(struct be_adapter *adapter, + struct be_tx_obj *txo, u16 last_index) { - struct be_queue_info *txq = &adapter->tx_obj.q; + struct be_queue_info *txq = &txo->q; struct be_eth_wrb *wrb; - struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; + struct sk_buff **sent_skbs = txo->sent_skb_list; struct sk_buff *sent_skb; u16 cur_index, num_wrbs = 1; /* account for hdr wrb */ bool unmap_skb_hdr = true; @@ -1504,7 +1508,8 @@ static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj) } static int event_handle(struct be_adapter *adapter, - struct be_eq_obj *eq_obj) + struct be_eq_obj *eq_obj, + bool rearm) { struct be_eq_entry *eqe; u16 num = 0; @@ -1517,7 +1522,10 @@ static int event_handle(struct be_adapter *adapter, /* Deal with any spurious interrupts that come * without events */ - be_eq_notify(adapter, eq_obj->q.id, true, true, num); + if (!num) + rearm = true; + + be_eq_notify(adapter, eq_obj->q.id, rearm, true, num); if (num) napi_schedule(&eq_obj->napi); @@ -1565,13 +1573,14 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) BUG_ON(atomic_read(&rxq->used)); } -static void be_tx_compl_clean(struct be_adapter *adapter) +static void be_tx_compl_clean(struct be_adapter *adapter, + struct be_tx_obj *txo) { - struct be_queue_info *tx_cq = &adapter->tx_obj.cq; - struct be_queue_info *txq = &adapter->tx_obj.q; + struct be_queue_info *tx_cq = &txo->cq; + struct be_queue_info *txq = &txo->q; struct be_eth_tx_compl *txcp; u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0; - struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; + struct sk_buff **sent_skbs = txo->sent_skb_list; struct sk_buff *sent_skb; bool dummy_wrb; @@ -1580,7 +1589,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter) while ((txcp = be_tx_compl_get(tx_cq))) { end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, wrb_index, txcp); - num_wrbs += be_tx_compl_process(adapter, end_idx); + num_wrbs += be_tx_compl_process(adapter, txo, end_idx); cmpl++; } if (cmpl) { @@ -1607,7 +1616,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter) index_adv(&end_idx, wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, txq->len); - num_wrbs = be_tx_compl_process(adapter, end_idx); + num_wrbs = be_tx_compl_process(adapter, txo, end_idx); atomic_sub(num_wrbs, &txq->used); } } @@ -1666,16 +1675,20 @@ err: static void be_tx_queues_destroy(struct be_adapter *adapter) { struct be_queue_info *q; + struct be_tx_obj *txo; + u8 i; - q = &adapter->tx_obj.q; - if (q->created) - be_cmd_q_destroy(adapter, q, QTYPE_TXQ); - be_queue_free(adapter, q); + for_all_tx_queues(adapter, txo, i) { + q = &txo->q; + if (q->created) + be_cmd_q_destroy(adapter, q, QTYPE_TXQ); + be_queue_free(adapter, q); - q = &adapter->tx_obj.cq; - if (q->created) - be_cmd_q_destroy(adapter, q, QTYPE_CQ); - be_queue_free(adapter, q); + q = &txo->cq; + if (q->created) + be_cmd_q_destroy(adapter, q, QTYPE_CQ); + be_queue_free(adapter, q); + } /* Clear any residual events */ be_eq_clean(adapter, &adapter->tx_eq); @@ -1686,56 +1699,48 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) be_queue_free(adapter, q); } +/* One TX event queue is shared by all TX compl qs */ static int be_tx_queues_create(struct be_adapter *adapter) { struct be_queue_info *eq, *q, *cq; + struct be_tx_obj *txo; + u8 i; adapter->tx_eq.max_eqd = 0; adapter->tx_eq.min_eqd = 0; adapter->tx_eq.cur_eqd = 96; adapter->tx_eq.enable_aic = false; - /* Alloc Tx Event queue */ + eq = &adapter->tx_eq.q; - if (be_queue_alloc(adapter, eq, EVNT_Q_LEN, sizeof(struct be_eq_entry))) + if (be_queue_alloc(adapter, eq, EVNT_Q_LEN, + sizeof(struct be_eq_entry))) return -1; - /* Ask BE to create Tx Event queue */ if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) - goto tx_eq_free; - + goto err; adapter->tx_eq.eq_idx = adapter->eq_next_idx++; - - /* Alloc TX eth compl queue */ - cq = &adapter->tx_obj.cq; - if (be_queue_alloc(adapter, cq, TX_CQ_LEN, + for_all_tx_queues(adapter, txo, i) { + cq = &txo->cq; + if (be_queue_alloc(adapter, cq, TX_CQ_LEN, sizeof(struct be_eth_tx_compl))) - goto tx_eq_destroy; + goto err; - /* Ask BE to create Tx eth compl queue */ - if (be_cmd_cq_create(adapter, cq, eq, false, false, 3)) - goto tx_cq_free; + if (be_cmd_cq_create(adapter, cq, eq, false, false, 3)) + goto err; - /* Alloc TX eth queue */ - q = &adapter->tx_obj.q; - if (be_queue_alloc(adapter, q, TX_Q_LEN, sizeof(struct be_eth_wrb))) - goto tx_cq_destroy; + q = &txo->q; + if (be_queue_alloc(adapter, q, TX_Q_LEN, + sizeof(struct be_eth_wrb))) + goto err; - /* Ask BE to create Tx eth queue */ - if (be_cmd_txq_create(adapter, q, cq)) - goto tx_q_free; + if (be_cmd_txq_create(adapter, q, cq)) + goto err; + } return 0; -tx_q_free: - be_queue_free(adapter, q); -tx_cq_destroy: - be_cmd_q_destroy(adapter, cq, QTYPE_CQ); -tx_cq_free: - be_queue_free(adapter, cq); -tx_eq_destroy: - be_cmd_q_destroy(adapter, eq, QTYPE_EQ); -tx_eq_free: - be_queue_free(adapter, eq); +err: + be_tx_queues_destroy(adapter); return -1; } @@ -1876,10 +1881,10 @@ static irqreturn_t be_intx(int irq, void *dev) if (lancer_chip(adapter)) { if (event_peek(&adapter->tx_eq)) - tx = event_handle(adapter, &adapter->tx_eq); + tx = event_handle(adapter, &adapter->tx_eq, false); for_all_rx_queues(adapter, rxo, i) { if (event_peek(&rxo->rx_eq)) - rx |= event_handle(adapter, &rxo->rx_eq); + rx |= event_handle(adapter, &rxo->rx_eq, true); } if (!(tx || rx)) @@ -1892,11 +1897,11 @@ static irqreturn_t be_intx(int irq, void *dev) return IRQ_NONE; if ((1 << adapter->tx_eq.eq_idx & isr)) - event_handle(adapter, &adapter->tx_eq); + event_handle(adapter, &adapter->tx_eq, false); for_all_rx_queues(adapter, rxo, i) { if ((1 << rxo->rx_eq.eq_idx & isr)) - event_handle(adapter, &rxo->rx_eq); + event_handle(adapter, &rxo->rx_eq, true); } } @@ -1908,7 +1913,7 @@ static irqreturn_t be_msix_rx(int irq, void *dev) struct be_rx_obj *rxo = dev; struct be_adapter *adapter = rxo->adapter; - event_handle(adapter, &rxo->rx_eq); + event_handle(adapter, &rxo->rx_eq, true); return IRQ_HANDLED; } @@ -1917,7 +1922,7 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev) { struct be_adapter *adapter = dev; - event_handle(adapter, &adapter->tx_eq); + event_handle(adapter, &adapter->tx_eq, false); return IRQ_HANDLED; } @@ -1978,45 +1983,48 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi); struct be_adapter *adapter = container_of(tx_eq, struct be_adapter, tx_eq); - struct be_queue_info *txq = &adapter->tx_obj.q; - struct be_queue_info *tx_cq = &adapter->tx_obj.cq; + struct be_tx_obj *txo; struct be_eth_tx_compl *txcp; - int tx_compl = 0, mcc_compl, status = 0; - u16 end_idx, num_wrbs = 0; + int tx_compl, mcc_compl, status = 0; + u8 i; + u16 num_wrbs; + + for_all_tx_queues(adapter, txo, i) { + tx_compl = 0; + num_wrbs = 0; + while ((txcp = be_tx_compl_get(&txo->cq))) { + num_wrbs += be_tx_compl_process(adapter, txo, + AMAP_GET_BITS(struct amap_eth_tx_compl, + wrb_index, txcp)); + tx_compl++; + } + if (tx_compl) { + be_cq_notify(adapter, txo->cq.id, true, tx_compl); + + atomic_sub(num_wrbs, &txo->q.used); - while ((txcp = be_tx_compl_get(tx_cq))) { - end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, - wrb_index, txcp); - num_wrbs += be_tx_compl_process(adapter, end_idx); - tx_compl++; + /* As Tx wrbs have been freed up, wake up netdev queue + * if it was stopped due to lack of tx wrbs. */ + if (__netif_subqueue_stopped(adapter->netdev, i) && + atomic_read(&txo->q.used) < txo->q.len / 2) { + netif_wake_subqueue(adapter->netdev, i); + } + + adapter->drv_stats.be_tx_events++; + txo->stats.be_tx_compl += tx_compl; + } } mcc_compl = be_process_mcc(adapter, &status); - napi_complete(napi); - if (mcc_compl) { struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; be_cq_notify(adapter, mcc_obj->cq.id, true, mcc_compl); } - if (tx_compl) { - be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); - - atomic_sub(num_wrbs, &txq->used); - - /* As Tx wrbs have been freed up, wake up netdev queue if - * it was stopped due to lack of tx wrbs. - */ - if (netif_queue_stopped(adapter->netdev) && - atomic_read(&txq->used) < txq->len / 2) { - netif_wake_queue(adapter->netdev); - } - - tx_stats(adapter)->be_tx_events++; - tx_stats(adapter)->be_tx_compl += tx_compl; - } + napi_complete(napi); + be_eq_notify(adapter, tx_eq->q.id, true, false, 0); return 1; } @@ -2065,6 +2073,7 @@ static void be_worker(struct work_struct *work) struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); struct be_rx_obj *rxo; + struct be_tx_obj *txo; int i; if (!adapter->ue_detected && !lancer_chip(adapter)) @@ -2092,7 +2101,9 @@ static void be_worker(struct work_struct *work) else be_cmd_get_stats(adapter, &adapter->stats_cmd); } - be_tx_rate_update(adapter); + + for_all_tx_queues(adapter, txo, i) + be_tx_rate_update(txo); for_all_rx_queues(adapter, rxo, i) { be_rx_rate_update(rxo); @@ -2294,6 +2305,7 @@ static int be_close(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); struct be_rx_obj *rxo; + struct be_tx_obj *txo; struct be_eq_obj *tx_eq = &adapter->tx_eq; int vec, i; @@ -2311,10 +2323,11 @@ static int be_close(struct net_device *netdev) napi_disable(&tx_eq->napi); if (lancer_chip(adapter)) { - be_cq_notify(adapter, adapter->tx_obj.cq.id, false, 0); be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0); for_all_rx_queues(adapter, rxo, i) be_cq_notify(adapter, rxo->cq.id, false, 0); + for_all_tx_queues(adapter, txo, i) + be_cq_notify(adapter, txo->cq.id, false, 0); } if (msix_enabled(adapter)) { @@ -2333,7 +2346,8 @@ static int be_close(struct net_device *netdev) /* Wait for all pending tx completions to arrive so that * all tx skbs are freed. */ - be_tx_compl_clean(adapter); + for_all_tx_queues(adapter, txo, i) + be_tx_compl_clean(adapter, txo); return 0; } @@ -3183,6 +3197,17 @@ static int be_get_config(struct be_adapter *adapter) return status; be_cmd_check_native_mode(adapter); + + if ((num_vfs && adapter->sriov_enabled) || + (adapter->function_mode & 0x400) || + lancer_chip(adapter) || !be_physfn(adapter)) { + adapter->num_tx_qs = 1; + netif_set_real_num_tx_queues(adapter->netdev, + adapter->num_tx_qs); + } else { + adapter->num_tx_qs = MAX_TX_QS; + } + return 0; } @@ -3285,7 +3310,7 @@ static int __devinit be_probe(struct pci_dev *pdev, goto disable_dev; pci_set_master(pdev); - netdev = alloc_etherdev(sizeof(struct be_adapter)); + netdev = alloc_etherdev_mq(sizeof(struct be_adapter), MAX_TX_QS); if (netdev == NULL) { status = -ENOMEM; goto rel_reg; -- cgit v1.2.3-70-g09d2 From 59deab26c1974b29b7f501e0ace0673d5acadae1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 14 Jun 2011 08:57:47 +0000 Subject: gianfar: Use pr_, netdev_ and netif_ Use the current logging styles. Add #define DEBUG to get same output for _dbg messages. Convert a few bare printks to pr_err. Fix a likely copy/paste defect where a test was done with RX values: if (num_rx_qs > MAX_RX_QS) { but TX limits were emitted: printk(KERN_ERR "num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n", num_tx_qs, MAX_TX_QS); Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 113 ++++++++++++++++++------------------------ drivers/net/gianfar_ethtool.c | 21 ++++---- 2 files changed, 58 insertions(+), 76 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index ff60b23a5b7..0c748328ca7 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -62,6 +62,9 @@ * The driver then cleans up the buffer. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#define DEBUG + #include #include #include @@ -213,8 +216,7 @@ static int gfar_init_bds(struct net_device *ndev) } else { skb = gfar_new_skb(ndev); if (!skb) { - pr_err("%s: Can't allocate RX buffers\n", - ndev->name); + netdev_err(ndev, "Can't allocate RX buffers\n"); goto err_rxalloc_fail; } rx_queue->rx_skbuff[j] = skb; @@ -258,9 +260,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) sizeof(struct rxbd8) * priv->total_rx_ring_size, &addr, GFP_KERNEL); if (!vaddr) { - if (netif_msg_ifup(priv)) - pr_err("%s: Could not allocate buffer descriptors!\n", - ndev->name); + netif_err(priv, ifup, ndev, + "Could not allocate buffer descriptors!\n"); return -ENOMEM; } @@ -290,9 +291,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) tx_queue->tx_skbuff = kmalloc(sizeof(*tx_queue->tx_skbuff) * tx_queue->tx_ring_size, GFP_KERNEL); if (!tx_queue->tx_skbuff) { - if (netif_msg_ifup(priv)) - pr_err("%s: Could not allocate tx_skbuff\n", - ndev->name); + netif_err(priv, ifup, ndev, + "Could not allocate tx_skbuff\n"); goto cleanup; } @@ -306,9 +306,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) rx_queue->rx_ring_size, GFP_KERNEL); if (!rx_queue->rx_skbuff) { - if (netif_msg_ifup(priv)) - pr_err("%s: Could not allocate rx_skbuff\n", - ndev->name); + netif_err(priv, ifup, ndev, + "Could not allocate rx_skbuff\n"); goto cleanup; } @@ -628,9 +627,9 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) num_tx_qs = tx_queues ? *tx_queues : 1; if (num_tx_qs > MAX_TX_QS) { - printk(KERN_ERR "num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n", - num_tx_qs, MAX_TX_QS); - printk(KERN_ERR "Cannot do alloc_etherdev, aborting\n"); + pr_err("num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n", + num_tx_qs, MAX_TX_QS); + pr_err("Cannot do alloc_etherdev, aborting\n"); return -EINVAL; } @@ -638,9 +637,9 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) num_rx_qs = rx_queues ? *rx_queues : 1; if (num_rx_qs > MAX_RX_QS) { - printk(KERN_ERR "num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n", - num_tx_qs, MAX_TX_QS); - printk(KERN_ERR "Cannot do alloc_etherdev, aborting\n"); + pr_err("num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n", + num_rx_qs, MAX_RX_QS); + pr_err("Cannot do alloc_etherdev, aborting\n"); return -EINVAL; } @@ -1163,8 +1162,7 @@ static int gfar_probe(struct platform_device *ofdev) err = register_netdev(dev); if (err) { - printk(KERN_ERR "%s: Cannot register net device, aborting.\n", - dev->name); + pr_err("%s: Cannot register net device, aborting\n", dev->name); goto register_fail; } @@ -1215,17 +1213,17 @@ static int gfar_probe(struct platform_device *ofdev) gfar_init_sysfs(dev); /* Print out the device info */ - printk(KERN_INFO DEVICE_NAME "%pM\n", dev->name, dev->dev_addr); + netdev_info(dev, "mac: %pM\n", dev->dev_addr); /* Even more device info helps when determining which kernel */ /* provided which set of benchmarks. */ - printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name); + netdev_info(dev, "Running with NAPI enabled\n"); for (i = 0; i < priv->num_rx_queues; i++) - printk(KERN_INFO "%s: RX BD ring size for Q[%d]: %d\n", - dev->name, i, priv->rx_queue[i]->rx_ring_size); + netdev_info(dev, "RX BD ring size for Q[%d]: %d\n", + i, priv->rx_queue[i]->rx_ring_size); for(i = 0; i < priv->num_tx_queues; i++) - printk(KERN_INFO "%s: TX BD ring size for Q[%d]: %d\n", - dev->name, i, priv->tx_queue[i]->tx_ring_size); + netdev_info(dev, "TX BD ring size for Q[%d]: %d\n", + i, priv->tx_queue[i]->tx_ring_size); return 0; @@ -1858,34 +1856,30 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) * Transmit, and Receive */ if ((err = request_irq(grp->interruptError, gfar_error, 0, grp->int_name_er,grp)) < 0) { - if (netif_msg_intr(priv)) - printk(KERN_ERR "%s: Can't get IRQ %d\n", - dev->name, grp->interruptError); + netif_err(priv, intr, dev, "Can't get IRQ %d\n", + grp->interruptError); goto err_irq_fail; } if ((err = request_irq(grp->interruptTransmit, gfar_transmit, 0, grp->int_name_tx, grp)) < 0) { - if (netif_msg_intr(priv)) - printk(KERN_ERR "%s: Can't get IRQ %d\n", - dev->name, grp->interruptTransmit); + netif_err(priv, intr, dev, "Can't get IRQ %d\n", + grp->interruptTransmit); goto tx_irq_fail; } if ((err = request_irq(grp->interruptReceive, gfar_receive, 0, grp->int_name_rx, grp)) < 0) { - if (netif_msg_intr(priv)) - printk(KERN_ERR "%s: Can't get IRQ %d\n", - dev->name, grp->interruptReceive); + netif_err(priv, intr, dev, "Can't get IRQ %d\n", + grp->interruptReceive); goto rx_irq_fail; } } else { if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, 0, grp->int_name_tx, grp)) < 0) { - if (netif_msg_intr(priv)) - printk(KERN_ERR "%s: Can't get IRQ %d\n", - dev->name, grp->interruptTransmit); + netif_err(priv, intr, dev, "Can't get IRQ %d\n", + grp->interruptTransmit); goto err_irq_fail; } } @@ -2354,9 +2348,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) frame_size += VLAN_HLEN; if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) { - if (netif_msg_drv(priv)) - printk(KERN_ERR "%s: Invalid MTU setting\n", - dev->name); + netif_err(priv, drv, dev, "Invalid MTU setting\n"); return -EINVAL; } @@ -2776,9 +2768,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) gfar_process_frame(dev, skb, amount_pull); } else { - if (netif_msg_rx_err(priv)) - printk(KERN_WARNING - "%s: Missing skb!\n", dev->name); + netif_warn(priv, rx_err, dev, "Missing skb!\n"); rx_queue->stats.rx_dropped++; priv->extra_stats.rx_skbmissing++; } @@ -2981,10 +2971,9 @@ static void adjust_link(struct net_device *dev) ecntrl &= ~(ECNTRL_R100); break; default: - if (netif_msg_link(priv)) - printk(KERN_WARNING - "%s: Ack! Speed (%d) is not 10/100/1000!\n", - dev->name, phydev->speed); + netif_warn(priv, link, dev, + "Ack! Speed (%d) is not 10/100/1000!\n", + phydev->speed); break; } @@ -3189,8 +3178,8 @@ static irqreturn_t gfar_error(int irq, void *grp_id) /* Hmm... */ if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv)) - printk(KERN_DEBUG "%s: error interrupt (ievent=0x%08x imask=0x%08x)\n", - dev->name, events, gfar_read(®s->imask)); + netdev_dbg(dev, "error interrupt (ievent=0x%08x imask=0x%08x)\n", + events, gfar_read(®s->imask)); /* Update the error counters */ if (events & IEVENT_TXE) { @@ -3203,9 +3192,8 @@ static irqreturn_t gfar_error(int irq, void *grp_id) if (events & IEVENT_XFUN) { unsigned long flags; - if (netif_msg_tx_err(priv)) - printk(KERN_DEBUG "%s: TX FIFO underrun, " - "packet dropped.\n", dev->name); + netif_dbg(priv, tx_err, dev, + "TX FIFO underrun, packet dropped\n"); dev->stats.tx_dropped++; priv->extra_stats.tx_underrun++; @@ -3218,8 +3206,7 @@ static irqreturn_t gfar_error(int irq, void *grp_id) unlock_tx_qs(priv); local_irq_restore(flags); } - if (netif_msg_tx_err(priv)) - printk(KERN_DEBUG "%s: Transmit Error\n", dev->name); + netif_dbg(priv, tx_err, dev, "Transmit Error\n"); } if (events & IEVENT_BSY) { dev->stats.rx_errors++; @@ -3227,29 +3214,25 @@ static irqreturn_t gfar_error(int irq, void *grp_id) gfar_receive(irq, grp_id); - if (netif_msg_rx_err(priv)) - printk(KERN_DEBUG "%s: busy error (rstat: %x)\n", - dev->name, gfar_read(®s->rstat)); + netif_dbg(priv, rx_err, dev, "busy error (rstat: %x)\n", + gfar_read(®s->rstat)); } if (events & IEVENT_BABR) { dev->stats.rx_errors++; priv->extra_stats.rx_babr++; - if (netif_msg_rx_err(priv)) - printk(KERN_DEBUG "%s: babbling RX error\n", dev->name); + netif_dbg(priv, rx_err, dev, "babbling RX error\n"); } if (events & IEVENT_EBERR) { priv->extra_stats.eberr++; - if (netif_msg_rx_err(priv)) - printk(KERN_DEBUG "%s: bus error\n", dev->name); + netif_dbg(priv, rx_err, dev, "bus error\n"); } - if ((events & IEVENT_RXC) && netif_msg_rx_status(priv)) - printk(KERN_DEBUG "%s: control frame\n", dev->name); + if (events & IEVENT_RXC) + netif_dbg(priv, rx_status, dev, "control frame\n"); if (events & IEVENT_BABT) { priv->extra_stats.tx_babt++; - if (netif_msg_tx_err(priv)) - printk(KERN_DEBUG "%s: babbling TX error\n", dev->name); + netif_dbg(priv, tx_err, dev, "babbling TX error\n"); } return IRQ_HANDLED; } diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 493d743839d..92d7ac09c87 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -16,6 +16,8 @@ * by reference. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -375,13 +377,13 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals /* Check the bounds of the values */ if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) { pr_info("Coalescing is limited to %d microseconds\n", - GFAR_MAX_COAL_USECS); + GFAR_MAX_COAL_USECS); return -EINVAL; } if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) { pr_info("Coalescing is limited to %d frames\n", - GFAR_MAX_COAL_FRAMES); + GFAR_MAX_COAL_FRAMES); return -EINVAL; } @@ -404,13 +406,13 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals /* Check the bounds of the values */ if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) { pr_info("Coalescing is limited to %d microseconds\n", - GFAR_MAX_COAL_USECS); + GFAR_MAX_COAL_USECS); return -EINVAL; } if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) { pr_info("Coalescing is limited to %d frames\n", - GFAR_MAX_COAL_FRAMES); + GFAR_MAX_COAL_FRAMES); return -EINVAL; } @@ -464,8 +466,7 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva return -EINVAL; if (!is_power_of_2(rvals->rx_pending)) { - printk("%s: Ring sizes must be a power of 2\n", - dev->name); + netdev_err(dev, "Ring sizes must be a power of 2\n"); return -EINVAL; } @@ -473,8 +474,7 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva return -EINVAL; if (!is_power_of_2(rvals->tx_pending)) { - printk("%s: Ring sizes must be a power of 2\n", - dev->name); + netdev_err(dev, "Ring sizes must be a power of 2\n"); return -EINVAL; } @@ -700,7 +700,7 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP; break; default: - printk(KERN_ERR "Right now this class is not supported\n"); + pr_err("Right now this class is not supported\n"); return 0; } @@ -715,8 +715,7 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u } if (i == MAX_FILER_IDX + 1) { - printk(KERN_ERR "No parse rule found, "); - printk(KERN_ERR "can't create hash rules\n"); + pr_err("No parse rule found, can't create hash rules\n"); return 0; } -- cgit v1.2.3-70-g09d2 From 0a3f084179731f6755462aa7fec677f8e1f0580a Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Thu, 16 Jun 2011 07:04:30 +0000 Subject: net: icplus: remove unnecessary code Compile tested. remove unnecessary code that matches this coccinelle pattern if (...) return ret; return ret; Signed-off-by: Greg Dietsche Signed-off-by: David S. Miller --- drivers/net/phy/icplus.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index 9a09e24c30b..d4cbc2922b2 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -109,11 +109,7 @@ static int ip1001_config_init(struct phy_device *phydev) value = phy_read(phydev, 16); value |= 0x3; - err = phy_write(phydev, 16, value); - if (err < 0) - return err; - - return err; + return phy_write(phydev, 16, value); } static int ip175c_read_status(struct phy_device *phydev) -- cgit v1.2.3-70-g09d2 From c4dc4d108ace27cc0c594b67bd6bd945deaac8c2 Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Thu, 16 Jun 2011 07:09:30 +0000 Subject: e1000: remove unnecessary code Compile tested. remove unnecessary code that matches this coccinelle pattern if (...) return ret; return ret; Signed-off-by: Greg Dietsche Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_hw.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 7501d977d99..1698622af43 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -3080,7 +3080,6 @@ s32 e1000_phy_hw_reset(struct e1000_hw *hw) { u32 ctrl, ctrl_ext; u32 led_ctrl; - s32 ret_val; e_dbg("e1000_phy_hw_reset"); @@ -3126,11 +3125,7 @@ s32 e1000_phy_hw_reset(struct e1000_hw *hw) } /* Wait for FW to finish PHY configuration. */ - ret_val = e1000_get_phy_cfg_done(hw); - if (ret_val != E1000_SUCCESS) - return ret_val; - - return ret_val; + return e1000_get_phy_cfg_done(hw); } /** -- cgit v1.2.3-70-g09d2 From 443c1a24710ce151874acdca7efb47622c098e80 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 13 Jun 2011 16:20:05 +0200 Subject: b43: define new PHYs and radio regs for cores >= 24 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 1cb2ddee9dc..666515e348b 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -92,6 +92,8 @@ #define B43_MMIO_PIO11_BASE4 0x300 #define B43_MMIO_PIO11_BASE5 0x340 +#define B43_MMIO_RADIO24_CONTROL 0x3D8 /* core rev >= 24 only */ +#define B43_MMIO_RADIO24_DATA 0x3DA /* core rev >= 24 only */ #define B43_MMIO_PHY_VER 0x3E0 #define B43_MMIO_PHY_RADIO 0x3E2 #define B43_MMIO_PHY0 0x3E6 @@ -363,6 +365,10 @@ enum { #define B43_PHYTYPE_G 0x02 #define B43_PHYTYPE_N 0x04 #define B43_PHYTYPE_LP 0x05 +#define B43_PHYTYPE_SSLPN 0x06 +#define B43_PHYTYPE_HT 0x07 +#define B43_PHYTYPE_LCN 0x08 +#define B43_PHYTYPE_LCNXN 0x09 /* PHYRegisters */ #define B43_PHY_ILT_A_CTRL 0x0072 -- cgit v1.2.3-70-g09d2 From d7520b1d2a9ffae94323ffac9dc37d92f656051f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 13 Jun 2011 16:20:06 +0200 Subject: b43: HT-PHY: add place for writing HT PHY support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is totally broken plus we do not have specs for HT PHY yet. Just introduce place for writing driver if we discover anything. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 8 +++ drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/main.c | 10 +++ drivers/net/wireless/b43/phy_common.c | 6 ++ drivers/net/wireless/b43/phy_common.h | 3 + drivers/net/wireless/b43/phy_ht.c | 119 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_ht.h | 19 ++++++ 7 files changed, 166 insertions(+) create mode 100644 drivers/net/wireless/b43/phy_ht.c create mode 100644 drivers/net/wireless/b43/phy_ht.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index fe26bf448fd..e02db1be172 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -112,6 +112,14 @@ config B43_PHY_LP and embedded devices. It supports 802.11a/g (802.11a support is optional, and currently disabled). +config B43_PHY_HT + bool "Support for HT-PHY devices (BROKEN)" + depends on B43 && BROKEN + ---help--- + Support for the HT-PHY. + + Say N, this is BROKEN and crashes driver. + # This config option automatically enables b43 LEDS support, # if it's possible. config B43_LEDS diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 95f7c001fda..58d614a889b 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -10,6 +10,7 @@ b43-y += phy_a.o b43-$(CONFIG_B43_PHY_N) += phy_n.o b43-$(CONFIG_B43_PHY_LP) += phy_lp.o b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o +b43-$(CONFIG_B43_PHY_HT) += phy_ht.o b43-y += sysfs.o b43-y += xmit.o b43-y += lo.o diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7aed9a0eabc..acee7b6af29 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4096,6 +4096,12 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (phy_rev > 2) unsupported = 1; break; +#endif +#ifdef CONFIG_B43_PHY_HT + case B43_PHYTYPE_HT: + if (phy_rev > 1) + unsupported = 1; + break; #endif default: unsupported = 1; @@ -4153,6 +4159,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (radio_ver != 0x2062 && radio_ver != 0x2063) unsupported = 1; break; + case B43_PHYTYPE_HT: + if (radio_ver != 0x2059) + unsupported = 1; + break; default: B43_WARN_ON(1); } diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 425af28ea4e..9705950f059 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -31,6 +31,7 @@ #include "phy_a.h" #include "phy_n.h" #include "phy_lp.h" +#include "phy_ht.h" #include "b43.h" #include "main.h" @@ -57,6 +58,11 @@ int b43_phy_allocate(struct b43_wldev *dev) case B43_PHYTYPE_LP: #ifdef CONFIG_B43_PHY_LP phy->ops = &b43_phyops_lp; +#endif + break; + case B43_PHYTYPE_HT: +#ifdef CONFIG_B43_PHY_HT + phy->ops = &b43_phyops_ht; #endif break; } diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 2401bee8b08..47dcb800a3c 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -194,6 +194,7 @@ struct b43_phy_a; struct b43_phy_g; struct b43_phy_n; struct b43_phy_lp; +struct b43_phy_ht; struct b43_phy { /* Hardware operation callbacks. */ @@ -216,6 +217,8 @@ struct b43_phy { struct b43_phy_n *n; /* LP-PHY specific information */ struct b43_phy_lp *lp; + /* HT-PHY specific information */ + struct b43_phy_ht *ht; }; /* Band support flags. */ diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c new file mode 100644 index 00000000000..320be0eeaf3 --- /dev/null +++ b/drivers/net/wireless/b43/phy_ht.c @@ -0,0 +1,119 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n HT-PHY support + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include + +#include "b43.h" +#include "phy_ht.h" +#include "main.h" + +/************************************************** + * Basic PHY ops. + **************************************************/ + +static int b43_phy_ht_op_allocate(struct b43_wldev *dev) +{ + struct b43_phy_ht *phy_ht; + + phy_ht = kzalloc(sizeof(*phy_ht), GFP_KERNEL); + if (!phy_ht) + return -ENOMEM; + dev->phy.ht = phy_ht; + + return 0; +} + +static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_ht *phy_ht = phy->ht; + + memset(phy_ht, 0, sizeof(*phy_ht)); +} + +static void b43_phy_ht_op_free(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_ht *phy_ht = phy->ht; + + kfree(phy_ht); + phy->ht = NULL; +} + +static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev) +{ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + return 1; + return 36; +} + +/************************************************** + * R/W ops. + **************************************************/ + +static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + return b43_read16(dev, B43_MMIO_PHY_DATA); +} + +static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, value); +} + +static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, + u16 set) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, + (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); +} + +/************************************************** + * PHY ops struct. + **************************************************/ + +const struct b43_phy_operations b43_phyops_ht = { + .allocate = b43_phy_ht_op_allocate, + .free = b43_phy_ht_op_free, + .prepare_structs = b43_phy_ht_op_prepare_structs, + /* + .init = b43_phy_ht_op_init, + */ + .phy_read = b43_phy_ht_op_read, + .phy_write = b43_phy_ht_op_write, + .phy_maskset = b43_phy_ht_op_maskset, + /* + .radio_read = b43_phy_ht_op_radio_read, + .radio_write = b43_phy_ht_op_radio_write, + .software_rfkill = b43_phy_ht_op_software_rfkill, + .switch_analog = b43_phy_ht_op_switch_analog, + .switch_channel = b43_phy_ht_op_switch_channel, + */ + .get_default_chan = b43_phy_ht_op_get_default_chan, + /* + .recalc_txpower = b43_phy_ht_op_recalc_txpower, + .adjust_txpower = b43_phy_ht_op_adjust_txpower, + */ +}; diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h new file mode 100644 index 00000000000..aabad6f2294 --- /dev/null +++ b/drivers/net/wireless/b43/phy_ht.h @@ -0,0 +1,19 @@ +#ifndef B43_PHY_HT_H_ +#define B43_PHY_HT_H_ + +#include "phy_common.h" + + +#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ +#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ +#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ + + +struct b43_phy_ht { +}; + + +struct b43_phy_operations; +extern const struct b43_phy_operations b43_phyops_ht; + +#endif /* B43_PHY_HT_H_ */ -- cgit v1.2.3-70-g09d2 From 545a8aa793e04bee7a7e2aa8caa70bed94fd7a5c Mon Sep 17 00:00:00 2001 From: Nikanth Karthikesan Date: Tue, 14 Jun 2011 11:23:46 +0530 Subject: if_spi: Fix compilation warning - unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if_spi: Fix compilation warning - unused variable 'spi' drivers/net/wireless/libertas/if_spi.c: In function ‘if_spi_init_card’: drivers/net/wireless/libertas/if_spi.c:1035: warning: unused variable ‘spi’ The variable is used only in a macro which uses the args only for DEBUG builds. Remove the 'spi' variable completely. Signed-off-by: Nikanth Karthikesan Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 463352c890d..d041bb2b577 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -1032,7 +1032,6 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) static int if_spi_init_card(struct if_spi_card *card) { struct lbs_private *priv = card->priv; - struct spi_device *spi = card->spi; int err, i; u32 scratch; const struct firmware *helper = NULL; @@ -1080,8 +1079,9 @@ static int if_spi_init_card(struct if_spi_card *card) "attached to SPI bus_num %d, chip_select %d. " "spi->max_speed_hz=%d\n", card->card_id, card->card_rev, - spi->master->bus_num, spi->chip_select, - spi->max_speed_hz); + card->spi->master->bus_num, + card->spi->chip_select, + card->spi->max_speed_hz); err = if_spi_prog_helper_firmware(card, helper); if (err) goto out; -- cgit v1.2.3-70-g09d2 From aec7ffdf4ff24df1fe85ed5bc9e050c4dd77617b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 14 Jun 2011 08:18:59 +0200 Subject: b43: add Kconfig option for compiling SSB driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is always "y" for now, b43 will not compile without CONFIG_SSB yet. This is just a first step of dropping SSB dependency. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 5 +++++ drivers/net/wireless/b43/bus.c | 3 ++- drivers/net/wireless/b43/main.c | 25 +++++++++++++++++-------- 3 files changed, 24 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index e02db1be172..d5add69aac8 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -31,6 +31,11 @@ config B43_BCMA depends on B43 && BCMA && BROKEN default y +config B43_SSB + bool + depends on B43 && SSB + default y + # Auto-select SSB PCI-HOST support, if possible config B43_PCI_AUTOSELECT bool diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 8a10b82f8ea..4200713eb59 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -25,7 +25,7 @@ /* SSB */ - +#ifdef CONFIG_B43_SSB static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev) { return ssb_bus_may_powerdown(dev->sdev->bus); @@ -124,3 +124,4 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) return dev; } +#endif /* CONFIG_B43_SSB */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index acee7b6af29..834df5a3fb6 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -123,6 +123,7 @@ static const struct bcma_device_id b43_bcma_tbl[] = { MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); #endif +#ifdef CONFIG_B43_SSB static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), @@ -136,8 +137,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), SSB_DEVTABLE_END }; - MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); +#endif /* Channel and ratetables are shared for all devices. * They can't be const, because ieee80211 puts some precalculated @@ -5026,6 +5027,7 @@ static struct bcma_driver b43_bcma_driver = { }; #endif +#ifdef CONFIG_B43_SSB static int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) { @@ -5103,6 +5105,14 @@ static void b43_ssb_remove(struct ssb_device *sdev) } } +static struct ssb_driver b43_ssb_driver = { + .name = KBUILD_MODNAME, + .id_table = b43_ssb_tbl, + .probe = b43_ssb_probe, + .remove = b43_ssb_remove, +}; +#endif /* CONFIG_B43_SSB */ + /* Perform a hardware reset. This can be called from any context. */ void b43_controller_restart(struct b43_wldev *dev, const char *reason) { @@ -5113,13 +5123,6 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason) ieee80211_queue_work(dev->wl->hw, &dev->restart_work); } -static struct ssb_driver b43_ssb_driver = { - .name = KBUILD_MODNAME, - .id_table = b43_ssb_tbl, - .probe = b43_ssb_probe, - .remove = b43_ssb_remove, -}; - static void b43_print_driverinfo(void) { const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", @@ -5163,14 +5166,18 @@ static int __init b43_init(void) if (err) goto err_sdio_exit; #endif +#ifdef CONFIG_B43_SSB err = ssb_driver_register(&b43_ssb_driver); if (err) goto err_bcma_driver_exit; +#endif b43_print_driverinfo(); return err; +#ifdef CONFIG_B43_SSB err_bcma_driver_exit: +#endif #ifdef CONFIG_B43_BCMA bcma_driver_unregister(&b43_bcma_driver); err_sdio_exit: @@ -5185,7 +5192,9 @@ err_dfs_exit: static void __exit b43_exit(void) { +#ifdef CONFIG_B43_SSB ssb_driver_unregister(&b43_ssb_driver); +#endif #ifdef CONFIG_B43_BCMA bcma_driver_unregister(&b43_bcma_driver); #endif -- cgit v1.2.3-70-g09d2 From d4bb17c4bed70892ea8b749a843a516424ba5638 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 15 Jun 2011 18:25:31 +0530 Subject: ath9k: Add debug messages to track PAPRD failures Add few debug messages for some of the possible scenarios where we can detect PAPRD failures. this will help us to be sure that we had really enabled PAPRD Cc: susinder@qca.qualcomm.com Cc: senthilb@qca.qualcomm.com Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7f945333e2d..e0e0e86578b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -360,7 +360,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int txctl.paprd = BIT(chain); if (ath_tx_start(hw, skb, &txctl) != 0) { - ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); + ath_dbg(common, ATH_DBG_CALIBRATE, "PAPRD TX failed\n"); dev_kfree_skb_any(skb); return false; } @@ -369,7 +369,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); if (!time_left) - ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, + ath_dbg(common, ATH_DBG_CALIBRATE, "Timeout waiting for paprd training on TX chain %d\n", chain); @@ -431,11 +431,18 @@ void ath_paprd_calibrate(struct work_struct *work) if (!ath_paprd_send_frame(sc, skb, chain)) goto fail_paprd; - if (!ar9003_paprd_is_done(ah)) + if (!ar9003_paprd_is_done(ah)) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "PAPRD not yet done on chain %d\n", chain); break; + } - if (ar9003_paprd_create_curve(ah, caldata, chain) != 0) + if (ar9003_paprd_create_curve(ah, caldata, chain)) { + ath_dbg(common, ATH_DBG_CALIBRATE, + "PAPRD create curve failed on chain %d\n", + chain); break; + } chain_ok = 1; } -- cgit v1.2.3-70-g09d2 From a6f0f048875a07b2926c075744eb5edc41bc3c1d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Jun 2011 16:10:10 +0300 Subject: iwlegacy: fix up brokenness caused by cleanup Patch 7f1f9742514 "iwlegacy: refactor iwl4965_mac_channel_switch" reversed a test and also it changed a spin_lock_irq() to spin_lock(). I assume the spin_lock change was a mistake because the unlock was left as spin_unlock_irq(). Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl4965-base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 49a80bb7063..46242d2aa5a 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -2526,7 +2526,7 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, if (!iwl_legacy_is_associated_ctx(ctx)) goto out; - if (priv->cfg->ops->lib->set_channel_switch) + if (!priv->cfg->ops->lib->set_channel_switch) goto out; ch = channel->hw_value; @@ -2539,7 +2539,7 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, goto out; } - spin_lock(&priv->lock); + spin_lock_irq(&priv->lock); priv->current_ht_config.smps = conf->smps_mode; -- cgit v1.2.3-70-g09d2 From d3af4396cff3d86a6a37e1cc5fe8d077f62c263e Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 15 Jun 2011 21:22:16 +0530 Subject: ath9k: remove a redundant call to pcipowersave during suspend/resume ath9k_stop will always call ath_radio_disable which will inturn call ath9k_hw_configpcipowersave, so no need to call it explicitly in ath9k_stop Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e0e0e86578b..5ae303b11e6 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1266,7 +1266,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) /* disable HAL and put h/w to sleep */ ath9k_hw_disable(ah); - ath9k_hw_configpcipowersave(ah, 1, 1); spin_unlock_bh(&sc->sc_pcu_lock); -- cgit v1.2.3-70-g09d2 From f6351d486dfecd56d57ee194f5d358d9a4fec840 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Wed, 15 Jun 2011 18:01:05 -0400 Subject: ath9k: use standard max(), remove A_MAX macro Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/rc.c | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3bf1d83ab41..b9c177f532b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -54,8 +54,6 @@ struct ath_node; (_l) &= ((_sz) - 1); \ } while (0) -#define A_MAX(a, b) ((a) > (b) ? (a) : (b)) - #define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index ba7f36ab0a7..e7fe4d9aee7 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -533,7 +533,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, [valid_rate_count] = j; ath_rc_priv->valid_phy_ratecnt[phy] += 1; ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); - hi = A_MAX(hi, j); + hi = max(hi, j); } } } @@ -569,7 +569,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, [ath_rc_priv->valid_phy_ratecnt[phy]] = j; ath_rc_priv->valid_phy_ratecnt[phy] += 1; ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); - hi = A_MAX(hi, j); + hi = max(hi, j); } } @@ -1228,7 +1228,7 @@ static void ath_rc_init(struct ath_softc *sc, ht_mcs, ath_rc_priv->ht_cap); } - hi = A_MAX(hi, hthi); + hi = max(hi, hthi); } ath_rc_priv->rate_table_size = hi + 1; -- cgit v1.2.3-70-g09d2 From e707549a80d5e5b37c4b0b9b60c5836396a11163 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Wed, 15 Jun 2011 18:01:11 -0400 Subject: ath9k: typo fix in a comment Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b9c177f532b..56a0ac4ddc6 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -577,7 +577,7 @@ struct ath9k_vif_iter_data { int naps; /* number of AP vifs */ int nmeshes; /* number of mesh vifs */ int nstations; /* number of station vifs */ - int nwds; /* number of nwd vifs */ + int nwds; /* number of WDS vifs */ int nadhocs; /* number of adhoc vifs */ int nothers; /* number of vifs not specified above. */ }; -- cgit v1.2.3-70-g09d2 From f5cbc8bac939f38c0c55cfaa348c170663a16767 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Wed, 15 Jun 2011 18:03:22 -0400 Subject: ath5k: minor cleanup Move an extern variable declaration to a header file. Prefix all functions with "ath5k_". Make ath5k_intr() static. Remove unneeded forward declarations. Remove pointless "extern" in a function declaration. Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 7 ++++--- drivers/net/wireless/ath/ath5k/base.c | 14 ++++++-------- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 6 ++---- 3 files changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index bb50700436f..c4c02d5145c 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -767,6 +767,7 @@ struct ath5k_athchan_2ghz { */ #define AR5K_KEYCACHE_SIZE 8 +extern int ath5k_modparam_nohwcrypt; /***********************\ HW RELATED DEFINITIONS @@ -1180,8 +1181,8 @@ void ath5k_sysfs_unregister(struct ath5k_softc *sc); struct ath5k_buf; struct ath5k_txq; -void set_beacon_filter(struct ieee80211_hw *hw, bool enable); -bool ath_any_vif_assoc(struct ath5k_softc *sc); +void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable); +bool ath5k_any_vif_assoc(struct ath5k_softc *sc); void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath5k_txq *txq); int ath5k_init_hw(struct ath5k_softc *sc); @@ -1253,7 +1254,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, int len, struct ieee80211_rate *rate, bool shortpre); unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); -extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); +int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); /* RX filter control*/ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b6c5d3715b9..3e70b1418a4 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -87,8 +87,6 @@ MODULE_LICENSE("Dual BSD/GPL"); static int ath5k_init(struct ieee80211_hw *hw); static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, bool skip_pcu); -int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { @@ -2161,7 +2159,7 @@ ath5k_schedule_tx(struct ath5k_softc *sc) tasklet_schedule(&sc->txtq); } -irqreturn_t +static irqreturn_t ath5k_intr(int irq, void *dev_id) { struct ath5k_softc *sc = dev_id; @@ -2615,7 +2613,7 @@ done: return ret; } -static void stop_tasklets(struct ath5k_softc *sc) +static void ath5k_stop_tasklets(struct ath5k_softc *sc) { sc->rx_pending = false; sc->tx_pending = false; @@ -2669,7 +2667,7 @@ ath5k_stop_hw(struct ath5k_softc *sc) mmiowb(); mutex_unlock(&sc->lock); - stop_tasklets(sc); + ath5k_stop_tasklets(sc); cancel_delayed_work_sync(&sc->tx_complete_work); @@ -2697,7 +2695,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, ath5k_hw_set_imr(ah, 0); synchronize_irq(sc->irq); - stop_tasklets(sc); + ath5k_stop_tasklets(sc); /* Save ani mode and disable ANI during * reset. If we don't we might get false @@ -2966,7 +2964,7 @@ ath5k_deinit_softc(struct ath5k_softc *sc) } bool -ath_any_vif_assoc(struct ath5k_softc *sc) +ath5k_any_vif_assoc(struct ath5k_softc *sc) { struct ath5k_vif_iter_data iter_data; iter_data.hw_macaddr = NULL; @@ -2980,7 +2978,7 @@ ath_any_vif_assoc(struct ath5k_softc *sc) } void -set_beacon_filter(struct ieee80211_hw *hw, bool enable) +ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable) { struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 807bd644016..493908299bb 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -46,8 +46,6 @@ #include "base.h" #include "reg.h" -extern int ath5k_modparam_nohwcrypt; - /********************\ * Mac80211 functions * \********************/ @@ -296,10 +294,10 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (bss_conf->assoc) sc->assoc = bss_conf->assoc; else - sc->assoc = ath_any_vif_assoc(sc); + sc->assoc = ath5k_any_vif_assoc(sc); if (sc->opmode == NL80211_IFTYPE_STATION) - set_beacon_filter(hw, sc->assoc); + ath5k_set_beacon_filter(hw, sc->assoc); ath5k_hw_set_ledstate(sc->ah, sc->assoc ? AR5K_LED_ASSOC : AR5K_LED_INIT); if (bss_conf->assoc) { -- cgit v1.2.3-70-g09d2 From d816ab26f6637282feb8a93c9def9925883ba0a7 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Wed, 15 Jun 2011 18:03:28 -0400 Subject: ath5k: annotate reg in ath5k_hw_nic_reset() as __iomem Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 126a4eab35f..1676a3e3dc3 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -375,19 +375,19 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) { u32 mask = flags ? flags : ~0U; - volatile u32 *reg; + volatile __iomem u32 *reg; u32 regval; u32 val = 0; /* ah->ah_mac_srev is not available at this point yet */ if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) { - reg = (u32 *) AR5K_AR2315_RESET; + reg = (u32 __iomem *) AR5K_AR2315_RESET; if (mask & AR5K_RESET_CTL_PCU) val |= AR5K_AR2315_RESET_WMAC; if (mask & AR5K_RESET_CTL_BASEBAND) val |= AR5K_AR2315_RESET_BB_WARM; } else { - reg = (u32 *) AR5K_AR5312_RESET; + reg = (u32 __iomem *) AR5K_AR5312_RESET; if (to_platform_device(ah->ah_sc->dev)->id == 0) { if (mask & AR5K_RESET_CTL_PCU) val |= AR5K_AR5312_RESET_WMAC0; -- cgit v1.2.3-70-g09d2 From 4cabd4254bc6b52a65da859a2c7591f67199ca81 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 16 Jun 2011 01:59:19 +0200 Subject: b43: HT-PHY: implement radio ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every PHY has some specific bit used for reading radio regs. Analyze of MMIO dumps from BCM4331 and ndiswrapper has shown it is 0x200 for HT. radio_read(0x037f) -> 0x0073 radio_write(0x017f) <- 0x0072 Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 320be0eeaf3..e535041c404 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -90,6 +90,22 @@ static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); } +static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg) +{ + /* HT-PHY needs 0x200 for read access */ + reg |= 0x200; + + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); + return b43_read16(dev, B43_MMIO_RADIO24_DATA); +} + +static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg, + u16 value) +{ + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); + b43_write16(dev, B43_MMIO_RADIO24_DATA, value); +} + /************************************************** * PHY ops struct. **************************************************/ @@ -104,9 +120,9 @@ const struct b43_phy_operations b43_phyops_ht = { .phy_read = b43_phy_ht_op_read, .phy_write = b43_phy_ht_op_write, .phy_maskset = b43_phy_ht_op_maskset, - /* .radio_read = b43_phy_ht_op_radio_read, .radio_write = b43_phy_ht_op_radio_write, + /* .software_rfkill = b43_phy_ht_op_software_rfkill, .switch_analog = b43_phy_ht_op_switch_analog, .switch_channel = b43_phy_ht_op_switch_channel, -- cgit v1.2.3-70-g09d2 From a8e827495a3e4d3a096e91b79e644e0665937927 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 16 Jun 2011 01:59:20 +0200 Subject: b43: HT-PHY: implement switching analog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turning it on is always done between reading PHY version and radio version, so it was easy to find it in MMIO dumps from ndiswrapper. Turning off is done by writing different values to the same registers. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 21 +++++++++++++++++++++ drivers/net/wireless/b43/phy_ht.h | 7 +++++++ 2 files changed, 28 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index e535041c404..5777cdbc047 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -59,6 +59,25 @@ static void b43_phy_ht_op_free(struct b43_wldev *dev) phy->ht = NULL; } +static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) +{ + if (on) { + b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000); + } else { + b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff); + b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd); + } +} + static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -124,7 +143,9 @@ const struct b43_phy_operations b43_phyops_ht = { .radio_write = b43_phy_ht_op_radio_write, /* .software_rfkill = b43_phy_ht_op_software_rfkill, + */ .switch_analog = b43_phy_ht_op_switch_analog, + /* .switch_channel = b43_phy_ht_op_switch_channel, */ .get_default_chan = b43_phy_ht_op_get_default_chan, diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index aabad6f2294..84ac47cbfaa 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -8,6 +8,13 @@ #define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ #define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ +#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) +#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111) +#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114) +#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115) +#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118) +#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119) + struct b43_phy_ht { }; -- cgit v1.2.3-70-g09d2 From b6ffd97f5bcfd12df88ece6bc6df7a761ac5a049 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 17 Jun 2011 17:00:05 +0200 Subject: r8169: move the firmware down into the device private data. No functional difference. Signed-off-by: Francois Romieu --- drivers/net/r8169.c | 74 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 73108249462..3eeefe4b49e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -667,7 +667,9 @@ struct rtl8169_private { struct rtl8169_counters counters; u32 saved_wolopts; - const struct firmware *fw; + struct rtl_fw { + const struct firmware *fw; + } *rtl_fw; #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN); }; @@ -1222,11 +1224,12 @@ static void rtl8169_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct rtl8169_private *tp = netdev_priv(dev); + struct rtl_fw *rtl_fw = tp->rtl_fw; strcpy(info->driver, MODULENAME); strcpy(info->version, RTL8169_VERSION); strcpy(info->bus_info, pci_name(tp->pci_dev)); - strncpy(info->fw_version, IS_ERR_OR_NULL(tp->fw) ? "N/A" : + strncpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" : rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1); } @@ -1741,9 +1744,9 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_DELAY_MS 0xe0000000 #define PHY_WRITE_ERI_WORD 0xf0000000 -static void -rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) +static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { + const struct firmware *fw = rtl_fw->fw; __le32 *phytable = (__le32 *)fw->data; struct net_device *dev = tp->dev; size_t index, fw_size = fw->size / sizeof(*phytable); @@ -1879,18 +1882,20 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) static void rtl_release_firmware(struct rtl8169_private *tp) { - if (!IS_ERR_OR_NULL(tp->fw)) - release_firmware(tp->fw); - tp->fw = RTL_FIRMWARE_UNKNOWN; + if (!IS_ERR_OR_NULL(tp->rtl_fw)) { + release_firmware(tp->rtl_fw->fw); + kfree(tp->rtl_fw); + } + tp->rtl_fw = RTL_FIRMWARE_UNKNOWN; } static void rtl_apply_firmware(struct rtl8169_private *tp) { - const struct firmware *fw = tp->fw; + struct rtl_fw *rtl_fw = tp->rtl_fw; /* TODO: release firmware once rtl_phy_write_fw signals failures. */ - if (!IS_ERR_OR_NULL(fw)) - rtl_phy_write_fw(tp, fw); + if (!IS_ERR_OR_NULL(rtl_fw)) + rtl_phy_write_fw(tp, rtl_fw); } static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -3443,7 +3448,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->timer.data = (unsigned long) dev; tp->timer.function = rtl8169_phy_timer; - tp->fw = RTL_FIRMWARE_UNKNOWN; + tp->rtl_fw = RTL_FIRMWARE_UNKNOWN; rc = register_netdev(dev); if (rc < 0) @@ -3512,25 +3517,42 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static void rtl_request_firmware(struct rtl8169_private *tp) +static void rtl_request_uncached_firmware(struct rtl8169_private *tp) { - /* Return early if the firmware is already loaded / cached. */ - if (IS_ERR(tp->fw)) { - const char *name; + struct rtl_fw *rtl_fw; + const char *name; + int rc = -ENOMEM; - name = rtl_lookup_firmware_name(tp); - if (name) { - int rc; + name = rtl_lookup_firmware_name(tp); + if (!name) + goto out_no_firmware; - rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev); - if (rc >= 0) - return; + rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); + if (!rtl_fw) + goto err_warn; - netif_warn(tp, ifup, tp->dev, "unable to load " - "firmware patch %s (%d)\n", name, rc); - } - tp->fw = NULL; - } + rc = request_firmware(&rtl_fw->fw, name, &tp->pci_dev->dev); + if (rc < 0) + goto err_free; + + tp->rtl_fw = rtl_fw; +out: + return; + +err_free: + kfree(rtl_fw); +err_warn: + netif_warn(tp, ifup, tp->dev, "unable to load firmware patch %s (%d)\n", + name, rc); +out_no_firmware: + tp->rtl_fw = NULL; + goto out; +} + +static void rtl_request_firmware(struct rtl8169_private *tp) +{ + if (IS_ERR(tp->rtl_fw)) + rtl_request_uncached_firmware(tp); } static int rtl8169_open(struct net_device *dev) -- cgit v1.2.3-70-g09d2 From 1c361efb226d609a07403057a71557faf500b17a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 17 Jun 2011 17:16:24 +0200 Subject: r8169: explicit firmware format check. Signed-off-by: Francois Romieu --- drivers/net/r8169.c | 62 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 3eeefe4b49e..8fc9af24694 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -669,6 +669,15 @@ struct rtl8169_private { struct rtl_fw { const struct firmware *fw; + +#define RTL_VER_SIZE 32 + + char version[RTL_VER_SIZE]; + + struct rtl_fw_phy_action { + __le32 *code; + size_t size; + } phy_action; } *rtl_fw; #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN); }; @@ -1229,8 +1238,9 @@ static void rtl8169_get_drvinfo(struct net_device *dev, strcpy(info->driver, MODULENAME); strcpy(info->version, RTL8169_VERSION); strcpy(info->bus_info, pci_name(tp->pci_dev)); - strncpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" : - rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1); + BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); + strcpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" : + rtl_fw->version); } static int rtl8169_get_regs_len(struct net_device *dev) @@ -1744,21 +1754,47 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_DELAY_MS 0xe0000000 #define PHY_WRITE_ERI_WORD 0xf0000000 -static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +#define FW_OPCODE_SIZE sizeof(typeof(*((struct rtl_fw_phy_action *)0)->code)) + +static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { const struct firmware *fw = rtl_fw->fw; - __le32 *phytable = (__le32 *)fw->data; + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + char *version = rtl_fw->version; + bool rc = false; + + if (fw->size < FW_OPCODE_SIZE) + goto out; + else { + if (fw->size % FW_OPCODE_SIZE) + goto out; + + strlcpy(version, rtl_lookup_firmware_name(tp), RTL_VER_SIZE); + + pa->code = (__le32 *)fw->data; + pa->size = fw->size / FW_OPCODE_SIZE; + } + version[RTL_VER_SIZE - 1] = 0; + + rc = true; +out: + return rc; +} + +static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +{ + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; struct net_device *dev = tp->dev; - size_t index, fw_size = fw->size / sizeof(*phytable); u32 predata, count; + size_t index; - if (fw->size % sizeof(*phytable)) { - netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size); + if (!rtl_fw_format_ok(tp, rtl_fw)) { + netif_err(tp, probe, dev, "invalid firwmare\n"); return; } - for (index = 0; index < fw_size; index++) { - u32 action = le32_to_cpu(phytable[index]); + for (index = 0; index < pa->size; index++) { + u32 action = le32_to_cpu(pa->code[index]); u32 regno = (action & 0x0fff0000) >> 16; switch(action & 0xf0000000) { @@ -1780,7 +1816,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) } break; case PHY_READCOUNT_EQ_SKIP: - if (index + 2 >= fw_size) { + if (index + 2 >= pa->size) { netif_err(tp, probe, tp->dev, "Out of range of firmware\n"); return; @@ -1789,7 +1825,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) case PHY_COMP_EQ_SKIPN: case PHY_COMP_NEQ_SKIPN: case PHY_SKIPN: - if (index + 1 + regno >= fw_size) { + if (index + 1 + regno >= pa->size) { netif_err(tp, probe, tp->dev, "Out of range of firmware\n"); return; @@ -1809,8 +1845,8 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) predata = 0; count = 0; - for (index = 0; index < fw_size; ) { - u32 action = le32_to_cpu(phytable[index]); + for (index = 0; index < pa->size; ) { + u32 action = le32_to_cpu(pa->code[index]); u32 data = action & 0x0000ffff; u32 regno = (action & 0x0fff0000) >> 16; -- cgit v1.2.3-70-g09d2 From 960aee6c7d5951ac20c0227ad73bad56392f0afc Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Sat, 18 Jun 2011 11:37:48 +0200 Subject: r8169: support new firmware format. The new firmware format adds versioning as firmware for a specific chipset appears to be subject to change. Current "legacy" format is still supported. Signed-off-by: Hayes Wang Signed-off-by: Francois Romieu --- drivers/net/r8169.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 8fc9af24694..7074989d5f7 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1754,18 +1754,52 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_DELAY_MS 0xe0000000 #define PHY_WRITE_ERI_WORD 0xf0000000 +struct fw_info { + u32 magic; + char version[RTL_VER_SIZE]; + __le32 fw_start; + __le32 fw_len; + u8 chksum; +} __packed; + #define FW_OPCODE_SIZE sizeof(typeof(*((struct rtl_fw_phy_action *)0)->code)) static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { const struct firmware *fw = rtl_fw->fw; + struct fw_info *fw_info = (struct fw_info *)fw->data; struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; char *version = rtl_fw->version; bool rc = false; if (fw->size < FW_OPCODE_SIZE) goto out; - else { + + if (!fw_info->magic) { + size_t i, size, start; + u8 checksum = 0; + + if (fw->size < sizeof(*fw_info)) + goto out; + + for (i = 0; i < fw->size; i++) + checksum += fw->data[i]; + if (checksum != 0) + goto out; + + start = le32_to_cpu(fw_info->fw_start); + if (start > fw->size) + goto out; + + size = le32_to_cpu(fw_info->fw_len); + if (size > (fw->size - start) / FW_OPCODE_SIZE) + goto out; + + memcpy(version, fw_info->version, RTL_VER_SIZE); + + pa->code = (__le32 *)(fw->data + start); + pa->size = size; + } else { if (fw->size % FW_OPCODE_SIZE) goto out; -- cgit v1.2.3-70-g09d2 From fd112f2e15ba85d387de446a81aeb11e46ecc55d Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sat, 18 Jun 2011 00:10:29 +0200 Subject: r8169: check firmware content sooner. Firmware checking is only performed when the firmware is loaded instead of each time the driver inits the phy. Signed-off-by: Francois Romieu --- drivers/net/r8169.c | 63 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7074989d5f7..bc5bb378d00 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1815,18 +1815,12 @@ out: return rc; } -static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, + struct rtl_fw_phy_action *pa) { - struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; - struct net_device *dev = tp->dev; - u32 predata, count; + bool rc = false; size_t index; - if (!rtl_fw_format_ok(tp, rtl_fw)) { - netif_err(tp, probe, dev, "invalid firwmare\n"); - return; - } - for (index = 0; index < pa->size; index++) { u32 action = le32_to_cpu(pa->code[index]); u32 regno = (action & 0x0fff0000) >> 16; @@ -1844,25 +1838,25 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) case PHY_BJMPN: if (regno > index) { - netif_err(tp, probe, tp->dev, + netif_err(tp, ifup, tp->dev, "Out of range of firmware\n"); - return; + goto out; } break; case PHY_READCOUNT_EQ_SKIP: if (index + 2 >= pa->size) { - netif_err(tp, probe, tp->dev, + netif_err(tp, ifup, tp->dev, "Out of range of firmware\n"); - return; + goto out; } break; case PHY_COMP_EQ_SKIPN: case PHY_COMP_NEQ_SKIPN: case PHY_SKIPN: if (index + 1 + regno >= pa->size) { - netif_err(tp, probe, tp->dev, + netif_err(tp, ifup, tp->dev, "Out of range of firmware\n"); - return; + goto out; } break; @@ -1870,14 +1864,39 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) case PHY_WRITE_MAC_BYTE: case PHY_WRITE_ERI_WORD: default: - netif_err(tp, probe, tp->dev, + netif_err(tp, ifup, tp->dev, "Invalid action 0x%08x\n", action); - return; + goto out; } } + rc = true; +out: + return rc; +} - predata = 0; - count = 0; +static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +{ + struct net_device *dev = tp->dev; + int rc = -EINVAL; + + if (!rtl_fw_format_ok(tp, rtl_fw)) { + netif_err(tp, ifup, dev, "invalid firwmare\n"); + goto out; + } + + if (rtl_fw_data_ok(tp, dev, &rtl_fw->phy_action)) + rc = 0; +out: + return rc; +} + +static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +{ + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + u32 predata, count; + size_t index; + + predata = count = 0; for (index = 0; index < pa->size; ) { u32 action = le32_to_cpu(pa->code[index]); @@ -3605,10 +3624,16 @@ static void rtl_request_uncached_firmware(struct rtl8169_private *tp) if (rc < 0) goto err_free; + rc = rtl_check_firmware(tp, rtl_fw); + if (rc < 0) + goto err_release_firmware; + tp->rtl_fw = rtl_fw; out: return; +err_release_firmware: + release_firmware(rtl_fw->fw); err_free: kfree(rtl_fw); err_warn: -- cgit v1.2.3-70-g09d2 From c68744fb935400964f7af4835017cad5014c8c88 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 18 Jun 2011 08:03:18 -0700 Subject: iwlagn: Remove un-necessary indirect call After driver split, no need to make indirect call to txfifo flush function Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 12 +++--------- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ---- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 5 ++--- 8 files changed, 6 insertions(+), 29 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 7aa240e6ba1..454b5410b70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -194,8 +194,6 @@ static struct iwl_lib_ops iwl1000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, - .txfifo_flush = iwlagn_txfifo_flush, - .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl1000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 5484ab712da..a6a259b7cbe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -204,8 +204,6 @@ static struct iwl_lib_ops iwl2000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, - .txfifo_flush = iwlagn_txfifo_flush, - .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl2000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 4353a658de2..c71fa4495d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -361,8 +361,6 @@ static struct iwl_lib_ops iwl5000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, - .txfifo_flush = iwlagn_txfifo_flush, - .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static struct iwl_lib_ops iwl5150_lib = { @@ -391,8 +389,6 @@ static struct iwl_lib_ops iwl5150_lib = { .temp_ops = { .temperature = iwl5150_temperature, }, - .txfifo_flush = iwlagn_txfifo_flush, - .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 6e5ce447849..b3785ec3f4a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -301,8 +301,6 @@ static struct iwl_lib_ops iwl6000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, - .txfifo_flush = iwlagn_txfifo_flush, - .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static struct iwl_lib_ops iwl6030_lib = { @@ -333,8 +331,6 @@ static struct iwl_lib_ops iwl6030_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, - .txfifo_flush = iwlagn_txfifo_flush, - .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static struct iwl_nic_ops iwl6050_nic_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a8c1e2493dc..3d9e1e86742 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1546,7 +1546,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) { mutex_lock(&priv->mutex); ieee80211_stop_queues(priv->hw); - if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { + if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); goto done; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0acf9291904..d66f1c29232 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -440,10 +440,8 @@ static void iwl_bg_tx_flush(struct work_struct *work) if (!iwl_is_ready_rf(priv)) return; - if (priv->cfg->ops->lib->txfifo_flush) { - IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); - iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); - } + IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); + iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); } /** @@ -3052,10 +3050,6 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); - /* do not support "flush" */ - if (!priv->cfg->ops->lib->txfifo_flush) - goto done; - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); goto done; @@ -3071,7 +3065,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) */ if (drop) { IWL_DEBUG_MAC80211(priv, "send flush command\n"); - if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { + if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); goto done; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 83ec5eb64ed..84f28e10631 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -142,10 +142,6 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; - - int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); - void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); - }; /* NIC specific ops */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 5f335c7815b..6f9ebae8ca0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2493,7 +2493,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, if (iwl_is_rfkill(priv)) return -EFAULT; - priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL); + iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); return count; } @@ -2693,8 +2693,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); - if (priv->cfg->ops->lib->dev_txfifo_flush) - DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); -- cgit v1.2.3-70-g09d2 From f88e0ecc896f91d6965ba2935dcdf2280044a30a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 8 Jun 2011 09:57:25 -0700 Subject: iwlagn: add PAN to tx flush When issue tx flush, also consider PAN Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 11 +++++++++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 20 ++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3d9e1e86742..8bed3ae1196 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1530,8 +1530,15 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) might_sleep(); memset(&flush_cmd, 0, sizeof(flush_cmd)); - flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK | - IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK; + flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | + IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | + IWL_SCD_MGMT_MSK; + if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | + IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | + IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | + IWL_PAN_SCD_MULTICAST_MSK; + if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 8dcb2108bce..189bc181c36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -972,10 +972,22 @@ struct iwl_rem_sta_cmd { u8 reserved2[2]; } __packed; -#define IWL_TX_FIFO_BK_MSK cpu_to_le32(BIT(0)) -#define IWL_TX_FIFO_BE_MSK cpu_to_le32(BIT(1)) -#define IWL_TX_FIFO_VI_MSK cpu_to_le32(BIT(2)) -#define IWL_TX_FIFO_VO_MSK cpu_to_le32(BIT(3)) + +/* WiFi queues mask */ +#define IWL_SCD_BK_MSK cpu_to_le32(BIT(0)) +#define IWL_SCD_BE_MSK cpu_to_le32(BIT(1)) +#define IWL_SCD_VI_MSK cpu_to_le32(BIT(2)) +#define IWL_SCD_VO_MSK cpu_to_le32(BIT(3)) +#define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3)) + +/* PAN queues mask */ +#define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4)) +#define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5)) +#define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6)) +#define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7)) +#define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7)) +#define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8)) + #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) #define IWL_DROP_SINGLE 0 -- cgit v1.2.3-70-g09d2 From ecdbe86eda74005d1b4bc8387e1825ad95fab705 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 8 Jun 2011 09:57:26 -0700 Subject: iwlagn: Support flush queues for specified interface Flush command can target specified interface or all interfaces Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 8bed3ae1196..99d473f527d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1530,10 +1530,12 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) might_sleep(); memset(&flush_cmd, 0, sizeof(flush_cmd)); - flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | + if (flush_control & BIT(IWL_RXON_CTX_BSS)) + flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | IWL_SCD_MGMT_MSK; - if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && + (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 189bc181c36..8a2edf8dce3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -991,8 +991,7 @@ struct iwl_rem_sta_cmd { #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) #define IWL_DROP_SINGLE 0 -#define IWL_DROP_SELECTED 1 -#define IWL_DROP_ALL 2 +#define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN)) /* * REPLY_TXFIFO_FLUSH = 0x1e(command and response) -- cgit v1.2.3-70-g09d2 From 7299751df36c02adafb5b897c56de71f0d7e2cb5 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 24 May 2011 10:44:47 +0300 Subject: iwlagn: don't disable interrupts after the NIC has been reset It is superfluous to disable the interrupts after we reset the NIC. The only entity that could enable the interrupts after the NIC is reset is the driver. So remove this pointless action. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d66f1c29232..0c747c3de6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3485,7 +3485,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct iwl_priv *priv; struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); - unsigned long flags; u16 pci_cmd, num_mac; u32 hw_rev; @@ -3646,10 +3645,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /******************** * 7. Setup services ********************/ - spin_lock_irqsave(&priv->lock, flags); - iwl_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - pci_enable_msi(priv->pci_dev); iwl_alloc_isr_ict(priv); -- cgit v1.2.3-70-g09d2 From 48d1a2110ad9cb86e5cb0d790729824fa3cca83b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 24 May 2011 11:39:02 +0300 Subject: iwlagn: add a iwl_pci.[ch] files that will contain all PCI specific code Move some PCI functionality to the new iwl_pci.[ch] files: * the PCI_DEVICE_TABLE * the pci_driver struct definition * the PCI probe / remove functions * the PCI suspend / resume functions All these functions are now split: the trigger comes from the PCI layer which calls to the bus generic code located in the other files. This is the beginning only. There are still a lot of PCI related code needs to be gathered. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 219 +------------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 3 + drivers/net/wireless/iwlwifi/iwl-core.c | 24 +-- drivers/net/wireless/iwlwifi/iwl-core.h | 17 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 + drivers/net/wireless/iwlwifi/iwl-pci.c | 340 ++++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-pci.h | 69 +++++++ 8 files changed, 427 insertions(+), 248 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-pci.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-pci.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 822660483f9..9a56ce54671 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -13,6 +13,7 @@ iwlagn-objs += iwl-5000.o iwlagn-objs += iwl-6000.o iwlagn-objs += iwl-1000.o iwlagn-objs += iwl-2000.o +iwlagn-objs += iwl-pci.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0c747c3de6f..d5eeb3e19b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -32,6 +32,7 @@ #include #include #include +/* TODO: remove include to PCI*.h when no PCI will be needed here */ #include #include #include @@ -49,8 +50,6 @@ #include -#define DRV_NAME "iwlagn" - #include "iwl-eeprom.h" #include "iwl-dev.h" #include "iwl-core.h" @@ -59,6 +58,7 @@ #include "iwl-sta.h" #include "iwl-agn-calib.h" #include "iwl-agn.h" +#include "iwl-pci.h" /****************************************************************************** @@ -3479,12 +3479,11 @@ static void iwl_init_context(struct iwl_priv *priv) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); } -static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg) { int err = 0; struct iwl_priv *priv; struct ieee80211_hw *hw; - struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); u16 pci_cmd, num_mac; u32 hw_rev; @@ -3717,7 +3716,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return err; } -static void __devexit iwl_pci_remove(struct pci_dev *pdev) +void __devexit iwl_remove(struct pci_dev *pdev) { struct iwl_priv *priv = pci_get_drvdata(pdev); unsigned long flags; @@ -3801,206 +3800,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) * driver and module entry point * *****************************************************************************/ - -/* Hardware specific file defines the PCI IDs table for that hardware module */ -static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { - {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ - -/* 5300 Series WiFi */ - {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ - -/* 5350 Series WiFi/WiMax */ - {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ - -/* 5150 Series Wifi/WiMax */ - {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ - - {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ - -/* 6x00 Series */ - {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, - {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, - -/* 6x05 Series */ - {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, - -/* 6x30 Series */ - {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, - -/* 6x50 WiFi/WiMax Series */ - {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, - -/* 6150 WiFi/WiMax Series */ - {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, - -/* 1000 Series WiFi */ - {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, - -/* 100 Series WiFi */ - {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, - {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, - -/* 130 Series WiFi */ - {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, - -/* 2x00 Series */ - {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, - -/* 2x30 Series */ - {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, - -/* 6x35 Series */ - {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, - -/* 105 Series */ - {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, - {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, - -/* 135 Series */ - {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, - {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, - {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, - - {0} -}; -MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); - -static struct pci_driver iwl_driver = { - .name = DRV_NAME, - .id_table = iwl_hw_card_ids, - .probe = iwl_pci_probe, - .remove = __devexit_p(iwl_pci_remove), - .driver.pm = IWL_PM_OPS, -}; - static int __init iwl_init(void) { @@ -4014,12 +3813,10 @@ static int __init iwl_init(void) return ret; } - ret = pci_register_driver(&iwl_driver); - if (ret) { - pr_err("Unable to initialize PCI module\n"); - goto error_register; - } + ret = iwl_pci_register_driver(); + if (ret) + goto error_register; return ret; error_register: @@ -4029,7 +3826,7 @@ error_register: static void __exit iwl_exit(void) { - pci_unregister_driver(&iwl_driver); + iwl_pci_unregister_driver(); iwlagn_rate_control_unregister(); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5d8b2db82a9..9dab387753a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -379,4 +379,7 @@ void iwl_testmode_cleanup(struct iwl_priv *priv) } #endif +int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg); +void iwl_remove(struct pci_dev *pdev); + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 445ddac0654..4268a3f4141 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1948,11 +1948,8 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, #ifdef CONFIG_PM -int iwl_pci_suspend(struct device *device) +int iwl_suspend(struct iwl_priv *priv) { - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); - /* * This function is called when system goes into suspend state * mac80211 will call iwl_mac_stop() from the mac80211 suspend function @@ -1965,18 +1962,10 @@ int iwl_pci_suspend(struct device *device) return 0; } -int iwl_pci_resume(struct device *device) +int iwl_resume(struct iwl_priv *priv) { - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); bool hw_rfkill = false; - /* - * We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - iwl_enable_interrupts(priv); if (!(iwl_read32(priv, CSR_GP_CNTRL) & @@ -1993,13 +1982,4 @@ int iwl_pci_resume(struct device *device) return 0; } -const struct dev_pm_ops iwl_pm_ops = { - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, - .freeze = iwl_pci_suspend, - .thaw = iwl_pci_resume, - .poweroff = iwl_pci_suspend, - .restore = iwl_pci_resume, -}; - #endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 84f28e10631..84032bbfefd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -76,11 +76,6 @@ struct iwl_cmd; #define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" #define DRV_AUTHOR "" -#define IWL_PCI_DEVICE(dev, subdev, cfg) \ - .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ - .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ - .driver_data = (kernel_ulong_t)&(cfg) - #define TIME_UNIT 1024 #define IWL_CMD(x) case x: return #x @@ -495,16 +490,8 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, u32 addon, u32 beacon_interval); #ifdef CONFIG_PM -int iwl_pci_suspend(struct device *device); -int iwl_pci_resume(struct device *device); -extern const struct dev_pm_ops iwl_pm_ops; - -#define IWL_PM_OPS (&iwl_pm_ops) - -#else /* !CONFIG_PM */ - -#define IWL_PM_OPS NULL - +int iwl_suspend(struct iwl_priv *priv); +int iwl_resume(struct iwl_priv *priv); #endif /* !CONFIG_PM */ /***************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ffed30207e9..59316fb1e8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -48,6 +48,8 @@ #include "iwl-agn-rs.h" #include "iwl-agn-tt.h" +#define DRV_NAME "iwlagn" + struct iwl_tx_queue; /* CT-KILL constants */ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c new file mode 100644 index 00000000000..d930be41cff --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -0,0 +1,340 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#include +#include + +#include "iwl-pci.h" +#include "iwl-agn.h" +#include "iwl-core.h" + +#define IWL_PCI_DEVICE(dev, subdev, cfg) \ + .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ + .driver_data = (kernel_ulong_t)&(cfg) + +/* Hardware specific file defines the PCI IDs table for that hardware module */ +static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { + {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ + +/* 5300 Series WiFi */ + {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ + +/* 5350 Series WiFi/WiMax */ + {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ + +/* 5150 Series Wifi/WiMax */ + {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ + + {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ + +/* 6x00 Series */ + {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, + +/* 6x05 Series */ + {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, + +/* 6x30 Series */ + {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, + +/* 6x50 WiFi/WiMax Series */ + {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, + +/* 6150 WiFi/WiMax Series */ + {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, + +/* 1000 Series WiFi */ + {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, + +/* 100 Series WiFi */ + {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, + +/* 130 Series WiFi */ + {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, + +/* 2x00 Series */ + {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, + +/* 2x30 Series */ + {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, + +/* 6x35 Series */ + {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, + +/* 105 Series */ + {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, + {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, + +/* 135 Series */ + {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, + {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, + + {0} +}; +MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); + +static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + + return iwl_probe(pdev, cfg); +} + +static void __devexit iwl_pci_remove(struct pci_dev *pdev) +{ + iwl_remove(pdev); +} + +#ifdef CONFIG_PM + +static int iwl_pci_suspend(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct iwl_priv *priv = pci_get_drvdata(pdev); + + return iwl_suspend(priv); +} + +static int iwl_pci_resume(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct iwl_priv *priv = pci_get_drvdata(pdev); + + /* + * We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + + return iwl_resume(priv); +} + +static const struct dev_pm_ops iwl_dev_pm_ops = { + .suspend = iwl_pci_suspend, + .resume = iwl_pci_resume, + .freeze = iwl_pci_suspend, + .thaw = iwl_pci_resume, + .poweroff = iwl_pci_suspend, + .restore = iwl_pci_resume, +}; + +#define IWL_PM_OPS (&iwl_dev_pm_ops) + +#else + +#define IWL_PM_OPS NULL + +#endif + +static struct pci_driver iwl_pci_driver = { + .name = DRV_NAME, + .id_table = iwl_hw_card_ids, + .probe = iwl_pci_probe, + .remove = __devexit_p(iwl_pci_remove), + .driver.pm = IWL_PM_OPS, +}; + +int __must_check iwl_pci_register_driver(void) +{ + int ret; + ret = pci_register_driver(&iwl_pci_driver); + if (ret) + pr_err("Unable to initialize PCI module\n"); + + return ret; +} + +void iwl_pci_unregister_driver(void) +{ + pci_unregister_driver(&iwl_pci_driver); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.h b/drivers/net/wireless/iwlwifi/iwl-pci.h new file mode 100644 index 00000000000..9396c7c8d6a --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-pci.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef __iwl_pci_h__ +#define __iwl_pci_h__ + +int __must_check iwl_pci_register_driver(void); +void iwl_pci_unregister_driver(void); + +#endif -- cgit v1.2.3-70-g09d2 From c6ca8bc46cc320e31e8fcb8b104eeed044febd6f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 30 May 2011 07:36:49 +0300 Subject: iwlagn: remove uneeded include to pci.h and dma_mapping.h from a few files Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-led.c | 2 -- 5 files changed, 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 454b5410b70..2daca80f086 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index a6a259b7cbe..406eb2ff5d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index c71fa4495d8..06fe9aded1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index b3785ec3f4a..c66bbc6c004 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 1a8ce4a8f82..7ef2b23565d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From a48709c5d076aa3a3f9b6426f462abe6bf432b11 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 31 May 2011 08:22:30 +0300 Subject: iwlagn: introduce iwl_bus and iwl_bus_ops iwl_bus will represent a bus, and iwl_bus_ops all the operations that can be done on this bus. For the moment only set_prv_data is implemented. More to come... Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 28 +++++++++++------- drivers/net/wireless/iwlwifi/iwl-agn.h | 5 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 23 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl-pci.c | 54 ++++++++++++++++++++++++++++++++-- 4 files changed, 94 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d5eeb3e19b4..1eeb4a75da0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3479,7 +3479,8 @@ static void iwl_init_context(struct iwl_priv *priv) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); } -int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg) +int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, + struct iwl_cfg *cfg) { int err = 0; struct iwl_priv *priv; @@ -3490,12 +3491,23 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg) /************************ * 1. Allocating HW data ************************/ + /* TODO: remove this nasty hack when PCI encapsulation is done + * assumes that struct pci_dev * is at the very beginning of whatever + * is pointed by bus_specific */ + unsigned long *ppdev = bus_specific; + struct pci_dev *pdev = (struct pci_dev *) *ppdev; hw = iwl_alloc_all(cfg); if (!hw) { err = -ENOMEM; goto out; } priv = hw->priv; + + priv->bus.priv = priv; + priv->bus.bus_specific = bus_specific; + priv->bus.ops = bus_ops; + priv->bus.ops->set_drv_data(&priv->bus, priv); + /* At this point both hw and priv are allocated. */ SET_IEEE80211_DEV(hw, &pdev->dev); @@ -3549,9 +3561,6 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg) if (err) goto out_pci_disable_device; - pci_set_drvdata(pdev, priv); - - /*********************** * 3. Read REV register ***********************/ @@ -3705,7 +3714,7 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg) out_iounmap: pci_iounmap(pdev, priv->hw_base); out_pci_release_regions: - pci_set_drvdata(pdev, NULL); + priv->bus.ops->set_drv_data(&priv->bus, NULL); pci_release_regions(pdev); out_pci_disable_device: pci_disable_device(pdev); @@ -3716,14 +3725,11 @@ int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg) return err; } -void __devexit iwl_remove(struct pci_dev *pdev) +void __devexit iwl_remove(struct iwl_priv * priv) { - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct pci_dev *pdev = priv->pci_dev; unsigned long flags; - if (!priv) - return; - wait_for_completion(&priv->_agn.firmware_loading_complete); IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); @@ -3783,7 +3789,7 @@ void __devexit iwl_remove(struct pci_dev *pdev) pci_iounmap(pdev, priv->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); + priv->bus.ops->set_drv_data(&priv->bus, NULL); iwl_uninit_drv(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 9dab387753a..34638692799 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -379,7 +379,8 @@ void iwl_testmode_cleanup(struct iwl_priv *priv) } #endif -int iwl_probe(struct pci_dev *pdev, struct iwl_cfg *cfg); -void iwl_remove(struct pci_dev *pdev); +int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, + struct iwl_cfg *cfg); +void __devexit iwl_remove(struct iwl_priv * priv); #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 59316fb1e8c..8865514226b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1188,6 +1188,26 @@ struct iwl_testmode_trace { bool trace_enabled; }; #endif + +struct iwl_bus; + +/** + * struct iwl_bus_ops - bus specific operations + * @set_drv_data: set the priv pointer to the bus layer + */ +struct iwl_bus_ops { + void (*set_drv_data)(struct iwl_bus *bus, void *priv); +}; + +struct iwl_bus { + /* pointer to bus specific struct */ + void *bus_specific; + + /* Common data to all buses */ + struct iwl_priv *priv; /* driver's context */ + struct iwl_bus_ops *ops; +}; + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1255,12 +1275,15 @@ struct iwl_priv { spinlock_t reg_lock; /* protect hw register access */ struct mutex mutex; + /* TODO: remove this after PCI abstraction is done */ /* basic pci-network driver stuff */ struct pci_dev *pci_dev; /* pci hardware address support */ void __iomem *hw_base; + struct iwl_bus bus; /* bus specific data */ + /* microcode/device supports multiple contexts */ u8 valid_contexts; diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index d930be41cff..ef9cb0813c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -67,6 +67,29 @@ #include "iwl-agn.h" #include "iwl-core.h" +struct iwl_pci_bus { + /* basic pci-network driver stuff */ + struct pci_dev *pci_dev; + + /* pci hardware address support */ + void __iomem *hw_base; +}; + +#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ + ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) + +#define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ + ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) + +static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_priv) +{ + pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_priv); +} + +static struct iwl_bus_ops pci_ops = { + .set_drv_data = iwl_pci_set_drv_data, +}; + #define IWL_PCI_DEVICE(dev, subdev, cfg) \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ @@ -266,13 +289,38 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); - - return iwl_probe(pdev, cfg); + struct iwl_pci_bus *bus; + int err; + + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) { + pr_err("Couldn't allocate iwl_pci_bus"); + err = -ENOMEM; + goto out_no_pci; + } + + bus->pci_dev = pdev; + + err = iwl_probe((void *) bus, &pci_ops, cfg); + if (err) + goto out_no_pci; + return 0; + +out_no_pci: + kfree(bus); + return err; } static void __devexit iwl_pci_remove(struct pci_dev *pdev) { - iwl_remove(pdev); + struct iwl_priv *priv = pci_get_drvdata(pdev); + + /* This can happen if probe failed */ + if (unlikely(!priv)) + return; + + iwl_remove(priv); + kfree(IWL_BUS_GET_PCI_BUS(&priv->bus)); } #ifdef CONFIG_PM -- cgit v1.2.3-70-g09d2 From 3599d39a8525b01540e2c7ec8c5d0df0dd11d6cf Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 31 May 2011 08:52:10 +0300 Subject: iwlagn: add get_dev to iwl_bus_ops Bus specific layer must know how to return the struct device* of the device. Implement that as a callback of iwl_bus_ops and use that callback instead of using the priv->pdev pointer which is meant to disappear soon. Since the struct device * is needed in hot path, iwl_bus holds a pointer to it instead of calling get_dev all the time. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ict.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 7 ++-- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 7 ++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 53 ++++++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl-debug.h | 8 ++--- drivers/net/wireless/iwlwifi/iwl-dev.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-led.c | 3 +- drivers/net/wireless/iwlwifi/iwl-pci.c | 6 ++++ drivers/net/wireless/iwlwifi/iwl-rx.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-sv-open.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-tx.c | 6 ++-- 11 files changed, 60 insertions(+), 45 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index 0d5fda44c3a..f1b40ec1c87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -44,7 +44,7 @@ void iwl_free_isr_ict(struct iwl_priv *priv) { if (priv->_agn.ict_tbl_vir) { - dma_free_coherent(&priv->pci_dev->dev, + dma_free_coherent(priv->bus.dev, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, priv->_agn.ict_tbl_vir, priv->_agn.ict_tbl_dma); @@ -61,7 +61,7 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv) /* allocate shrared data table */ priv->_agn.ict_tbl_vir = - dma_alloc_coherent(&priv->pci_dev->dev, + dma_alloc_coherent(priv->bus.dev, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, &priv->_agn.ict_tbl_dma, GFP_KERNEL); if (!priv->_agn.ict_tbl_vir) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 99d473f527d..4c11edcb4e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -966,9 +966,10 @@ void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) } } - dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->bd_dma); - dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), + dma_free_coherent(priv->bus.dev, 4 * RX_QUEUE_SIZE, + rxq->bd, rxq->bd_dma); + dma_free_coherent(priv->bus.dev, + sizeof(struct iwl_rb_status), rxq->rb_stts, rxq->rb_stts_dma); rxq->bd = NULL; rxq->rb_stts = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 8bd48f61a9f..f4e5edefd06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -834,8 +834,8 @@ drop_unlock_priv: static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, struct iwl_dma_ptr *ptr, size_t size) { - ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma, - GFP_KERNEL); + ptr->addr = dma_alloc_coherent(priv->bus.dev, size, + &ptr->dma, GFP_KERNEL); if (!ptr->addr) return -ENOMEM; ptr->size = size; @@ -848,7 +848,8 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, if (unlikely(!ptr->addr)) return; - dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma); + dma_free_coherent(priv->bus.dev, + ptr->size, ptr->addr, ptr->dma); memset(ptr, 0, sizeof(*ptr)); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1eeb4a75da0..0098245a62e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -937,22 +937,28 @@ static struct attribute_group iwl_attribute_group = { * ******************************************************************************/ -static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) +static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(&pci_dev->dev, desc->len, + dma_free_coherent(priv->bus.dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; } -static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img) +static void iwl_free_fw_img(struct iwl_priv *priv, struct fw_img *img) { - iwl_free_fw_desc(pci_dev, &img->code); - iwl_free_fw_desc(pci_dev, &img->data); + iwl_free_fw_desc(priv, &img->code); + iwl_free_fw_desc(priv, &img->data); } -static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, +static void iwl_dealloc_ucode(struct iwl_priv *priv) +{ + iwl_free_fw_img(priv, &priv->ucode_rt); + iwl_free_fw_img(priv, &priv->ucode_init); +} + +static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -960,21 +966,16 @@ static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len, + desc->v_addr = dma_alloc_coherent(priv->bus.dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; + desc->len = len; memcpy(desc->v_addr, data, len); return 0; } -static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) -{ - iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt); - iwl_free_fw_img(priv->pci_dev, &priv->ucode_init); -} - struct iwlagn_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; @@ -1019,8 +1020,8 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) priv->firmware_name); return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - &priv->pci_dev->dev, GFP_KERNEL, priv, - iwl_ucode_callback); + priv->bus.dev, + GFP_KERNEL, priv, iwl_ucode_callback); } struct iwlagn_firmware_pieces { @@ -1441,19 +1442,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code, + if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.code, pieces.inst, pieces.inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data, + if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.data, pieces.data, pieces.data_size)) goto err_pci_alloc; /* Initialization instructions and data */ if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code, + if (iwl_alloc_fw_desc(priv, &priv->ucode_init.code, pieces.init, pieces.init_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data, + if (iwl_alloc_fw_desc(priv, &priv->ucode_init.data, pieces.init_data, pieces.init_data_size)) goto err_pci_alloc; } @@ -1522,7 +1523,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (err) IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - err = sysfs_create_group(&priv->pci_dev->dev.kobj, + err = sysfs_create_group(&(priv->bus.dev->kobj), &iwl_attribute_group); if (err) { IWL_ERR(priv, "failed to create sysfs device attributes\n"); @@ -1543,10 +1544,10 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) err_pci_alloc: IWL_ERR(priv, "failed to allocate pci memory\n"); - iwl_dealloc_ucode_pci(priv); + iwl_dealloc_ucode(priv); out_unbind: complete(&priv->_agn.firmware_loading_complete); - device_release_driver(&priv->pci_dev->dev); + device_release_driver(priv->bus.dev); release_firmware(ucode_raw); } @@ -3507,10 +3508,11 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, priv->bus.bus_specific = bus_specific; priv->bus.ops = bus_ops; priv->bus.ops->set_drv_data(&priv->bus, priv); + priv->bus.dev = priv->bus.ops->get_dev(&priv->bus); /* At this point both hw and priv are allocated. */ - SET_IEEE80211_DEV(hw, &pdev->dev); + SET_IEEE80211_DEV(hw, priv->bus.dev); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); priv->cfg = cfg; @@ -3735,7 +3737,8 @@ void __devexit iwl_remove(struct iwl_priv * priv) IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); iwl_dbgfs_unregister(priv); - sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); + sysfs_remove_group(&priv->bus.dev->kobj, + &iwl_attribute_group); /* ieee80211_unregister_hw call wil cause iwl_mac_stop to * to be called and iwl_down since we are removing the device @@ -3765,7 +3768,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_synchronize_irq(priv); - iwl_dealloc_ucode_pci(priv); + iwl_dealloc_ucode(priv); if (priv->rxq.bd) iwlagn_rx_queue_free(priv, &priv->rxq); diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index c844b512e56..eb95d1a3748 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -32,10 +32,10 @@ struct iwl_priv; extern u32 iwl_debug_level; -#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a) -#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a) -#define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a) -#define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a) +#define IWL_ERR(p, f, a...) dev_err(p->bus.ops->get_dev(&p->bus), f, ## a) +#define IWL_WARN(p, f, a...) dev_warn(p->bus.ops->get_dev(&p->bus), f, ## a) +#define IWL_INFO(p, f, a...) dev_info(p->bus.ops->get_dev(&p->bus), f, ## a) +#define IWL_CRIT(p, f, a...) dev_crit(p->bus.ops->get_dev(&p->bus), f, ## a) #define iwl_print_hex_error(priv, p, len) \ do { \ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8865514226b..49e6c68f9b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1194,9 +1194,11 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations * @set_drv_data: set the priv pointer to the bus layer + * @get_dev: returns the device struct */ struct iwl_bus_ops { void (*set_drv_data)(struct iwl_bus *bus, void *priv); + struct device *(*get_dev)(const struct iwl_bus *bus); }; struct iwl_bus { @@ -1205,6 +1207,7 @@ struct iwl_bus { /* Common data to all buses */ struct iwl_priv *priv; /* driver's context */ + struct device *dev; struct iwl_bus_ops *ops; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 7ef2b23565d..ff08da09975 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -202,7 +202,8 @@ void iwl_leds_init(struct iwl_priv *priv) break; } - ret = led_classdev_register(&priv->pci_dev->dev, &priv->led); + ret = led_classdev_register(priv->bus.dev, + &priv->led); if (ret) { kfree(priv->led.name); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index ef9cb0813c6..00458fc2c40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -86,8 +86,14 @@ static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_priv) pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_priv); } +static struct device *iwl_pci_get_dev(const struct iwl_bus *bus) +{ + return &(IWL_BUS_GET_PCI_DEV(bus)->dev); +} + static struct iwl_bus_ops pci_ops = { .set_drv_data = iwl_pci_set_drv_data, + .get_dev = iwl_pci_get_dev, }; #define IWL_PCI_DEVICE(dev, subdev, cfg) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index b774517aa9f..3efa7066e98 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -182,7 +182,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q int iwl_rx_queue_alloc(struct iwl_priv *priv) { struct iwl_rx_queue *rxq = &priv->rxq; - struct device *dev = &priv->pci_dev->dev; + struct device *dev = priv->bus.dev; int i; spin_lock_init(&rxq->lock); @@ -213,7 +213,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) return 0; err_rb: - dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma); err_bd: return -ENOMEM; diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 6f626425144..c00aa5a1b8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -180,7 +180,7 @@ void iwl_testmode_init(struct iwl_priv *priv) static void iwl_trace_cleanup(struct iwl_priv *priv) { - struct device *dev = &priv->pci_dev->dev; + struct device *dev = priv->bus.dev; if (priv->testmode_trace.trace_enabled) { if (priv->testmode_trace.cpu_addr && @@ -484,7 +484,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) struct iwl_priv *priv = hw->priv; struct sk_buff *skb; int status = 0; - struct device *dev = &priv->pci_dev->dev; + struct device *dev = priv->bus.dev; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1084fe0e8a8..f982ac9b8ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -266,7 +266,7 @@ void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) { struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct device *dev = &priv->pci_dev->dev; + struct device *dev = priv->bus.dev; int i; iwl_tx_queue_unmap(priv, txq_id); @@ -332,7 +332,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) void iwl_cmd_queue_free(struct iwl_priv *priv) { struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; - struct device *dev = &priv->pci_dev->dev; + struct device *dev = priv->bus.dev; int i; iwl_cmd_queue_unmap(priv); @@ -434,7 +434,7 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, static int iwl_tx_queue_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq, u32 id) { - struct device *dev = &priv->pci_dev->dev; + struct device *dev = priv->bus.dev; size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; /* Driver private data, only for Tx (not command) queues, -- cgit v1.2.3-70-g09d2 From 084dd79172cb3aad11d2b7ee5628d57badca7c6e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 31 May 2011 09:07:00 +0300 Subject: iwlagn: move PCI related operations from probe and remove to PCI layer Since we have now a PCI layer, all the init and deinit code that is PCI related should move to there. Also move the IO functions: read8/read32/write32. They need hw_base which is killed from priv. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 87 ++++--------------------- drivers/net/wireless/iwlwifi/iwl-dev.h | 9 ++- drivers/net/wireless/iwlwifi/iwl-io.h | 6 +- drivers/net/wireless/iwlwifi/iwl-pci.c | 113 ++++++++++++++++++++++++++++++++- 4 files changed, 131 insertions(+), 84 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0098245a62e..72db1a9fab8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3486,7 +3486,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, int err = 0; struct iwl_priv *priv; struct ieee80211_hw *hw; - u16 pci_cmd, num_mac; + u16 num_mac; u32 hw_rev; /************************ @@ -3532,49 +3532,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); - /************************** - * 2. Initializing PCI bus - **************************/ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); - - if (pci_enable_device(pdev)) { - err = -ENODEV; - goto out_ieee80211_free_hw; - } - - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); - if (err) { - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - /* both attempts failed: */ - if (err) { - IWL_WARN(priv, "No suitable DMA available.\n"); - goto out_pci_disable_device; - } - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) - goto out_pci_disable_device; - - /*********************** - * 3. Read REV register - ***********************/ - priv->hw_base = pci_iomap(pdev, 0, 0); - if (!priv->hw_base) { - err = -ENODEV; - goto out_pci_release_regions; - } - - IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); - IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); /* these spin locks will be used in apm_ops.init and EEPROM access * we should init now @@ -3589,17 +3546,16 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, */ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + /*********************** + * 3. Read REV register + ***********************/ hw_rev = iwl_hw_detect(priv); IWL_INFO(priv, "Detected %s, REV=0x%X\n", priv->cfg->name, hw_rev); - /* We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state */ - pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - if (iwl_prepare_card_hw(priv)) { IWL_WARN(priv, "Failed, HW not ready\n"); - goto out_iounmap; + goto out_free_traffic_mem; } /***************** @@ -3609,7 +3565,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, err = iwl_eeprom_init(priv, hw_rev); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_iounmap; + goto out_free_traffic_mem; } err = iwl_eeprom_check_version(priv); if (err) @@ -3639,6 +3595,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, * 5. Setup HW constants ************************/ if (iwl_set_hw_params(priv)) { + err = -ENOENT; IWL_ERR(priv, "failed to set hw parameters\n"); goto out_free_eeprom; } @@ -3655,15 +3612,13 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, /******************** * 7. Setup services ********************/ - pci_enable_msi(priv->pci_dev); - iwl_alloc_isr_ict(priv); err = request_irq(priv->pci_dev->irq, iwl_isr_ict, IRQF_SHARED, DRV_NAME, priv); if (err) { IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); - goto out_disable_msi; + goto out_uninit_drv; } iwl_setup_deferred_work(priv); @@ -3671,16 +3626,9 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, iwl_testmode_init(priv); /********************************************* - * 8. Enable interrupts and read RFKILL state + * 8. Enable interrupts *********************************************/ - /* enable rfkill interrupt: hw bug w/a */ - pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); - if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { - pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); - } - iwl_enable_rfkill_int(priv); /* If platform's RF_KILL switch is NOT set to KILL */ @@ -3707,20 +3655,12 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, destroy_workqueue(priv->workqueue); priv->workqueue = NULL; free_irq(priv->pci_dev->irq, priv); - out_disable_msi: iwl_free_isr_ict(priv); - pci_disable_msi(priv->pci_dev); + out_uninit_drv: iwl_uninit_drv(priv); out_free_eeprom: iwl_eeprom_free(priv); - out_iounmap: - pci_iounmap(pdev, priv->hw_base); - out_pci_release_regions: - priv->bus.ops->set_drv_data(&priv->bus, NULL); - pci_release_regions(pdev); - out_pci_disable_device: - pci_disable_device(pdev); - out_ieee80211_free_hw: + out_free_traffic_mem: iwl_free_traffic_mem(priv); ieee80211_free_hw(priv->hw); out: @@ -3729,7 +3669,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, void __devexit iwl_remove(struct iwl_priv * priv) { - struct pci_dev *pdev = priv->pci_dev; unsigned long flags; wait_for_completion(&priv->_agn.firmware_loading_complete); @@ -3788,10 +3727,6 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_free_traffic_mem(priv); free_irq(priv->pci_dev->irq, priv); - pci_disable_msi(priv->pci_dev); - pci_iounmap(pdev, priv->hw_base); - pci_release_regions(pdev); - pci_disable_device(pdev); priv->bus.ops->set_drv_data(&priv->bus, NULL); iwl_uninit_drv(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 49e6c68f9b7..700e9f92129 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1195,10 +1195,16 @@ struct iwl_bus; * struct iwl_bus_ops - bus specific operations * @set_drv_data: set the priv pointer to the bus layer * @get_dev: returns the device struct + * @write8: write a byte to register at offset ofs + * @write32: write a dword to register at offset ofs + * @wread32: read a dword at register at offset ofs */ struct iwl_bus_ops { void (*set_drv_data)(struct iwl_bus *bus, void *priv); struct device *(*get_dev)(const struct iwl_bus *bus); + void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); + void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); + u32 (*read32)(struct iwl_bus *bus, u32 ofs); }; struct iwl_bus { @@ -1282,9 +1288,6 @@ struct iwl_priv { /* basic pci-network driver stuff */ struct pci_dev *pci_dev; - /* pci hardware address support */ - void __iomem *hw_base; - struct iwl_bus bus; /* bus specific data */ /* microcode/device supports multiple contexts */ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 869edc580ec..c56eae74c3c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -38,18 +38,18 @@ static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val) { trace_iwlwifi_dev_iowrite8(priv, ofs, val); - iowrite8(val, priv->hw_base + ofs); + priv->bus.ops->write8(&priv->bus, ofs, val); } static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) { trace_iwlwifi_dev_iowrite32(priv, ofs, val); - iowrite32(val, priv->hw_base + ofs); + priv->bus.ops->write32(&priv->bus, ofs, val); } static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs) { - u32 val = ioread32(priv->hw_base + ofs); + u32 val = priv->bus.ops->read32(&priv->bus, ofs); trace_iwlwifi_dev_ioread32(priv, ofs, val); return val; } diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 00458fc2c40..43de98efa3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -91,9 +91,28 @@ static struct device *iwl_pci_get_dev(const struct iwl_bus *bus) return &(IWL_BUS_GET_PCI_DEV(bus)->dev); } +static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) +{ + iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); +} + +static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val) +{ + iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); +} + +static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) +{ + u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); + return val; +} + static struct iwl_bus_ops pci_ops = { .set_drv_data = iwl_pci_set_drv_data, .get_dev = iwl_pci_get_dev, + .write8 = iwl_pci_write8, + .write32 = iwl_pci_write32, + .read32 = iwl_pci_read32, }; #define IWL_PCI_DEVICE(dev, subdev, cfg) \ @@ -296,6 +315,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_pci_bus *bus; + u8 rev_id; + u16 pci_cmd; int err; bus = kzalloc(sizeof(*bus), GFP_KERNEL); @@ -307,16 +328,103 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) bus->pci_dev = pdev; + /* W/A - seems to solve weird behavior. We need to remove this if we + * don't want to stay in L1 all the time. This wastes a lot of power */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_no_pci; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); + if (err) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + /* both attempts failed: */ + if (err) { + pr_err("No suitable DMA available.\n"); + goto out_pci_disable_device; + } + } + + err = pci_request_regions(pdev, DRV_NAME); + if (err) { + pr_err("pci_request_regions failed"); + goto out_pci_disable_device; + } + + bus->hw_base = pci_iomap(pdev, 0, 0); + if (!bus->hw_base) { + pr_err("pci_iomap failed"); + err = -ENODEV; + goto out_pci_release_regions; + } + + pr_info("pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + pr_info("pci_resource_base = %p\n", bus->hw_base); + + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); + pr_info("HW Revision ID = 0x%X\n", rev_id); + + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + + err = pci_enable_msi(pdev); + if (err) { + pr_err("pci_enable_msi failed"); + goto out_iounmap; + } + + /* TODO: Move this away, not needed if not MSI */ + /* enable rfkill interrupt: hw bug w/a */ + pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); + if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); + } + err = iwl_probe((void *) bus, &pci_ops, cfg); if (err) - goto out_no_pci; + goto out_disable_msi; return 0; +out_disable_msi: + pci_disable_msi(pdev); +out_iounmap: + pci_iounmap(pdev, bus->hw_base); +out_pci_release_regions: + pci_set_drvdata(pdev, NULL); + pci_release_regions(pdev); +out_pci_disable_device: + pci_disable_device(pdev); out_no_pci: kfree(bus); return err; } +static void iwl_pci_down(void *bus) +{ + struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus; + + pci_disable_msi(pci_bus->pci_dev); + pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base); + pci_release_regions(pci_bus->pci_dev); + pci_disable_device(pci_bus->pci_dev); + pci_set_drvdata(pci_bus->pci_dev, NULL); + + kfree(pci_bus); +} + static void __devexit iwl_pci_remove(struct pci_dev *pdev) { struct iwl_priv *priv = pci_get_drvdata(pdev); @@ -326,7 +434,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) return; iwl_remove(priv); - kfree(IWL_BUS_GET_PCI_BUS(&priv->bus)); + + iwl_pci_down(IWL_BUS_GET_PCI_BUS(&priv->bus)); } #ifdef CONFIG_PM -- cgit v1.2.3-70-g09d2 From 795414db8607a195541fe1a8f072021011b73386 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 18 Jun 2011 08:12:57 -0700 Subject: iwlagn: don't use the PCI wrappers for DMA operation Get a pointer to the struct device during probe and get the rid of all the PCI specific DMA wrappers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 12 ++++++------ drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 27 +++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-tx.c | 27 +++++++++++++-------------- 4 files changed, 36 insertions(+), 38 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 4c11edcb4e6..52da53997d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -639,9 +639,9 @@ void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) /* In the reset function, these buffers may have been allocated * to an SKB, so we need to unmap and free potential storage */ if (rxq->pool[i].page != NULL) { - pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; } @@ -913,9 +913,9 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority) BUG_ON(rxb->page); rxb->page = page; /* Get physical address of the RB */ - rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, + rxb->page_dma = dma_map_page(priv->bus.dev, page, 0, PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -958,9 +958,9 @@ void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) int i; for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { if (rxq->pool[i].page != NULL) { - pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index f4e5edefd06..d0ac090399e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -716,10 +716,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ - txcmd_phys = pci_map_single(priv->pci_dev, + txcmd_phys = dma_map_single(priv->bus.dev, &out_cmd->hdr, firstlen, - PCI_DMA_BIDIRECTIONAL); - if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys))) + DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(priv->bus.dev, txcmd_phys))) goto drop_unlock_sta; dma_unmap_addr_set(out_meta, mapping, txcmd_phys); dma_unmap_len_set(out_meta, len, firstlen); @@ -735,13 +735,13 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) * if any (802.11 null frames have no payload). */ secondlen = skb->len - hdr_len; if (secondlen > 0) { - phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, - secondlen, PCI_DMA_TODEVICE); - if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { - pci_unmap_single(priv->pci_dev, + phys_addr = dma_map_single(priv->bus.dev, skb->data + hdr_len, + secondlen, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) { + dma_unmap_single(priv->bus.dev, dma_unmap_addr(out_meta, mapping), dma_unmap_len(out_meta, len), - PCI_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); goto drop_unlock_sta; } } @@ -764,8 +764,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) offsetof(struct iwl_tx_cmd, scratch); /* take back ownership of DMA buffer to enable update */ - pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys, - firstlen, PCI_DMA_BIDIRECTIONAL); + dma_sync_single_for_cpu(priv->bus.dev, txcmd_phys, firstlen, + DMA_BIDIRECTIONAL); tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); @@ -780,8 +780,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwlagn_txq_update_byte_cnt_tbl(priv, txq, le16_to_cpu(tx_cmd->len)); - pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, - firstlen, PCI_DMA_BIDIRECTIONAL); + dma_sync_single_for_device(priv->bus.dev, txcmd_phys, firstlen, + DMA_BIDIRECTIONAL); trace_iwlwifi_dev_tx(priv, &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], @@ -848,8 +848,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, if (unlikely(!ptr->addr)) return; - dma_free_coherent(priv->bus.dev, - ptr->size, ptr->addr, ptr->dma); + dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma); memset(ptr, 0, sizeof(*ptr)); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 72db1a9fab8..eeb31bcfc74 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -495,9 +495,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) rxq->queue[i] = NULL; - pci_unmap_page(priv->pci_dev, rxb->page_dma, + dma_unmap_page(priv->bus.dev, rxb->page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); pkt = rxb_addr(rxb); len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; @@ -579,9 +579,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) * rx_free list for reuse later. */ spin_lock_irqsave(&rxq->lock, flags); if (rxb->page != NULL) { - rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, + rxb->page_dma = dma_map_page(priv->bus.dev, rxb->page, 0, PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; } else diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index f982ac9b8ba..fd8aee9972c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -128,7 +128,6 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, struct iwl_tfd *tfd) { - struct pci_dev *dev = priv->pci_dev; int i; int num_tbs; @@ -143,15 +142,15 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, /* Unmap tx_cmd */ if (num_tbs) - pci_unmap_single(dev, + dma_unmap_single(priv->bus.dev, dma_unmap_addr(meta, mapping), dma_unmap_len(meta, len), - PCI_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) - pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), - iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); + dma_unmap_single(priv->bus.dev, iwl_tfd_tb_get_addr(tfd, i), + iwl_tfd_tb_get_len(tfd, i), DMA_TO_DEVICE); } /** @@ -310,10 +309,10 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) i = get_cmd_index(q, q->read_ptr); if (txq->meta[i].flags & CMD_MAPPED) { - pci_unmap_single(priv->pci_dev, + dma_unmap_single(priv->bus.dev, dma_unmap_addr(&txq->meta[i], mapping), dma_unmap_len(&txq->meta[i], len), - PCI_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); txq->meta[i].flags = 0; } @@ -456,7 +455,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); if (!txq->tfds) { - IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); + IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz); goto error; } txq->q.id = id; @@ -677,9 +676,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, priv->cmd_queue); - phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, - copy_size, PCI_DMA_BIDIRECTIONAL); - if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { + phys_addr = dma_map_single(priv->bus.dev, &out_cmd->hdr, copy_size, + DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) { idx = -ENOMEM; goto out; } @@ -699,9 +698,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) continue; if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) continue; - phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i], - cmd->len[i], PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) { + phys_addr = dma_map_single(priv->bus.dev, (void *)cmd->data[i], + cmd->len[i], DMA_TO_DEVICE); + if (dma_mapping_error(priv->bus.dev, phys_addr)) { iwlagn_unmap_tfd(priv, out_meta, &txq->tfds[q->write_ptr]); idx = -ENOMEM; -- cgit v1.2.3-70-g09d2 From d57fa99d91bd6e8ca8217c115824b2732f4d3639 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 10 Jun 2011 11:23:36 -0700 Subject: iwlagn: move PCI power related functions to the PCI layer Continue to popule the PCI layer and the iwl_bus_ops with the power related stuff. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hw.h | 7 ----- drivers/net/wireless/iwlwifi/iwl-core.c | 24 +------------- drivers/net/wireless/iwlwifi/iwl-core.h | 14 --------- drivers/net/wireless/iwlwifi/iwl-dev.h | 5 +++ drivers/net/wireless/iwlwifi/iwl-pci.c | 52 +++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-power.c | 10 +++--- drivers/net/wireless/iwlwifi/iwl-power.h | 2 +- 7 files changed, 63 insertions(+), 51 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 7bd19f4e66d..0e5b842529c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -81,13 +81,6 @@ /* RSSI to dBm */ #define IWLAGN_RSSI_OFFSET 44 -/* PCI registers */ -#define PCI_CFG_RETRY_TIMEOUT 0x041 - -/* PCI register values */ -#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 -#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 - #define IWLAGN_DEFAULT_TX_RETRY 15 /* Limit range of txpower output target to be between these values */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4268a3f4141..360df33585e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -997,8 +997,6 @@ void iwl_apm_stop(struct iwl_priv *priv) int iwl_apm_init(struct iwl_priv *priv) { int ret = 0; - u16 lctl; - IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); /* @@ -1027,27 +1025,7 @@ int iwl_apm_init(struct iwl_priv *priv) iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - /* - * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition. - * Check if BIOS (or OS) enabled L1-ASPM on this device. - * If so (likely), disable L0S, so device moves directly L0->L1; - * costs negligible amount of power savings. - * If not (unlikely), enable L0S, so there is at least some - * power savings, even without L1. - */ - lctl = iwl_pcie_link_ctl(priv); - if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == - PCI_CFG_LINK_CTRL_VAL_L1_EN) { - /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); - } + priv->bus.ops->apm_config(&priv->bus); /* Configure analog phase-lock-loop before activating to D0A */ if (priv->cfg->base_params->pll_cfg_val) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 84032bbfefd..a09361dd62d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -470,20 +470,6 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); - -/***************************************************** - * PCI * - *****************************************************/ - -static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) -{ - int pos; - u16 pci_lnk_ctl; - pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP); - pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); - return pci_lnk_ctl; -} - void iwl_bg_watchdog(unsigned long data); u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 700e9f92129..797d4f3f879 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1193,6 +1193,9 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations + + * @get_pm_support: must returns true if the bus can go to sleep + * @apm_config: will be called during the config of the APM configuration * @set_drv_data: set the priv pointer to the bus layer * @get_dev: returns the device struct * @write8: write a byte to register at offset ofs @@ -1200,6 +1203,8 @@ struct iwl_bus; * @wread32: read a dword at register at offset ofs */ struct iwl_bus_ops { + bool (*get_pm_support)(struct iwl_bus *bus); + void (*apm_config)(struct iwl_bus *bus); void (*set_drv_data)(struct iwl_bus *bus, void *priv); struct device *(*get_dev)(const struct iwl_bus *bus); void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 43de98efa3e..d8c6ec8947c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -66,6 +66,12 @@ #include "iwl-pci.h" #include "iwl-agn.h" #include "iwl-core.h" +#include "iwl-io.h" + +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 +#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 +#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 struct iwl_pci_bus { /* basic pci-network driver stuff */ @@ -81,6 +87,50 @@ struct iwl_pci_bus { #define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) +static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) +{ + int pos; + u16 pci_lnk_ctl; + struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); + + pos = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); + pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); + return pci_lnk_ctl; +} + +static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) +{ + u16 lctl = iwl_pciexp_link_ctrl(bus); + + return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); +} + +static void iwl_pci_apm_config(struct iwl_bus *bus) +{ + /* + * HW bug W/A for instability in PCIe bus L0S->L1 transition. + * Check if BIOS (or OS) enabled L1-ASPM on this device. + * If so (likely), disable L0S, so device moves directly L0->L1; + * costs negligible amount of power savings. + * If not (unlikely), enable L0S, so there is at least some + * power savings, even without L1. + */ + u16 lctl = iwl_pciexp_link_ctrl(bus); + + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_set_bit(bus->priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(bus->priv, "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_clear_bit(bus->priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(bus->priv, "L1 Disabled; Enabling L0S\n"); + } +} + static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_priv) { pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_priv); @@ -108,6 +158,8 @@ static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) } static struct iwl_bus_ops pci_ops = { + .get_pm_support = iwl_pci_is_pm_supported, + .apm_config = iwl_pci_apm_config, .set_drv_data = iwl_pci_set_drv_data, .get_dev = iwl_pci_get_dev, .write8 = iwl_pci_write8, diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index a69b5512417..970c514623b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -245,7 +245,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, } } - if (priv->power_data.pci_pm) + if (priv->power_data.bus_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; else cmd->flags &= ~IWL_POWER_PCI_PM_MSK; @@ -260,7 +260,7 @@ static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv, { memset(cmd, 0, sizeof(*cmd)); - if (priv->power_data.pci_pm) + if (priv->power_data.bus_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); @@ -296,7 +296,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | IWL_POWER_FAST_PD; /* no use seeing frames for others */ - if (priv->power_data.pci_pm) + if (priv->power_data.bus_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; if (priv->cfg->base_params->shadow_reg_enable) @@ -425,9 +425,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { - u16 lctl = iwl_pcie_link_ctl(priv); - - priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); + priv->power_data.bus_pm = priv->bus.ops->get_pm_support(&priv->bus); priv->power_data.debug_sleep_level_override = -1; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 59635d784e2..5f7b720cf1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -43,7 +43,7 @@ struct iwl_power_mgr { struct iwl_powertable_cmd sleep_cmd; struct iwl_powertable_cmd sleep_cmd_next; int debug_sleep_level_override; - bool pci_pm; + bool bus_pm; }; int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, -- cgit v1.2.3-70-g09d2 From 19707bac16129ccebc398dbff9d2b44b17b24fea Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 10 Jun 2011 11:28:56 -0700 Subject: iwlagn: add a method to get the HW ID description as a string to iwl_bus_ops Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-pci.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 360df33585e..cde725326c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -209,10 +209,10 @@ int iwlcore_init_geos(struct iwl_priv *priv) if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) { + char buf[32]; + priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf)); IWL_INFO(priv, "Incorrectly detected BG card as ABG. " - "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n", - priv->pci_dev->device, - priv->pci_dev->subsystem_device); + "Please send your %s to maintainer.\n", buf); priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 797d4f3f879..1099944cc2b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1198,6 +1198,7 @@ struct iwl_bus; * @apm_config: will be called during the config of the APM configuration * @set_drv_data: set the priv pointer to the bus layer * @get_dev: returns the device struct + * @get_hw_id: prints the hw_id in the provided buffer * @write8: write a byte to register at offset ofs * @write32: write a dword to register at offset ofs * @wread32: read a dword at register at offset ofs @@ -1207,6 +1208,7 @@ struct iwl_bus_ops { void (*apm_config)(struct iwl_bus *bus); void (*set_drv_data)(struct iwl_bus *bus, void *priv); struct device *(*get_dev)(const struct iwl_bus *bus); + void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len); void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); u32 (*read32)(struct iwl_bus *bus, u32 ofs); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index d8c6ec8947c..adbc9621c3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -141,6 +141,15 @@ static struct device *iwl_pci_get_dev(const struct iwl_bus *bus) return &(IWL_BUS_GET_PCI_DEV(bus)->dev); } +static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], + int buf_len) +{ + struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); + + snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device, + pci_dev->subsystem_device); +} + static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) { iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); @@ -162,6 +171,7 @@ static struct iwl_bus_ops pci_ops = { .apm_config = iwl_pci_apm_config, .set_drv_data = iwl_pci_set_drv_data, .get_dev = iwl_pci_get_dev, + .get_hw_id = iwl_pci_get_hw_id, .write8 = iwl_pci_write8, .write32 = iwl_pci_write32, .read32 = iwl_pci_read32, -- cgit v1.2.3-70-g09d2 From 85aed7c48113dfcdc913008481c46346af0db69e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 31 May 2011 09:58:18 +0300 Subject: iwlagn: don't read the PCI_REVISION_ID from iwl-agn.c The PCI_REVISION_ID is read and printed in iwl_pci_probe anyway using pr_info Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index eeb31bcfc74..1ff8e4b3e96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3352,10 +3352,6 @@ struct ieee80211_ops iwlagn_hw_ops = { static u32 iwl_hw_detect(struct iwl_priv *priv) { - u8 rev_id; - - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); - IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); return iwl_read32(priv, CSR_HW_REV); } -- cgit v1.2.3-70-g09d2 From 08321c062f77e379c4a539f1522220b83ab1e84e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 10 Jun 2011 11:30:30 -0700 Subject: iwlagn: add a get_irq method to iwl_bus_ops and use it In order to remove a few more dereference to priv->pdev that will be killed [Asoon, there is now a method to get the IRQ number. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +++++---- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-pci.c | 6 ++++++ 4 files changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1ff8e4b3e96..e2b319f3c5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3610,10 +3610,11 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, ********************/ iwl_alloc_isr_ict(priv); - err = request_irq(priv->pci_dev->irq, iwl_isr_ict, + err = request_irq(priv->bus.ops->get_irq(&priv->bus), iwl_isr_ict, IRQF_SHARED, DRV_NAME, priv); if (err) { - IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); + IWL_ERR(priv, "Error allocating IRQ %d\n", + priv->bus.ops->get_irq(&priv->bus)); goto out_uninit_drv; } @@ -3650,7 +3651,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, out_destroy_workqueue: destroy_workqueue(priv->workqueue); priv->workqueue = NULL; - free_irq(priv->pci_dev->irq, priv); + free_irq(priv->bus.ops->get_irq(&priv->bus), priv); iwl_free_isr_ict(priv); out_uninit_drv: iwl_uninit_drv(priv); @@ -3722,7 +3723,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) priv->workqueue = NULL; iwl_free_traffic_mem(priv); - free_irq(priv->pci_dev->irq, priv); + free_irq(priv->bus.ops->get_irq(&priv->bus), priv); priv->bus.ops->set_drv_data(&priv->bus, NULL); iwl_uninit_drv(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 34638692799..848a6c3a56a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -125,7 +125,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data); static inline void iwl_synchronize_irq(struct iwl_priv *priv) { /* wait to make sure we flush pending tasklet*/ - synchronize_irq(priv->pci_dev->irq); + synchronize_irq(priv->bus.ops->get_irq(&priv->bus)); tasklet_kill(&priv->irq_tasklet); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1099944cc2b..f6b54c6d878 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1198,6 +1198,7 @@ struct iwl_bus; * @apm_config: will be called during the config of the APM configuration * @set_drv_data: set the priv pointer to the bus layer * @get_dev: returns the device struct + * @get_irq: returns the irq number * @get_hw_id: prints the hw_id in the provided buffer * @write8: write a byte to register at offset ofs * @write32: write a dword to register at offset ofs @@ -1208,6 +1209,7 @@ struct iwl_bus_ops { void (*apm_config)(struct iwl_bus *bus); void (*set_drv_data)(struct iwl_bus *bus, void *priv); struct device *(*get_dev)(const struct iwl_bus *bus); + unsigned int (*get_irq)(const struct iwl_bus *bus); void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len); void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index adbc9621c3e..7328fbff7f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -141,6 +141,11 @@ static struct device *iwl_pci_get_dev(const struct iwl_bus *bus) return &(IWL_BUS_GET_PCI_DEV(bus)->dev); } +static unsigned int iwl_pci_get_irq(const struct iwl_bus *bus) +{ + return IWL_BUS_GET_PCI_DEV(bus)->irq; +} + static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], int buf_len) { @@ -171,6 +176,7 @@ static struct iwl_bus_ops pci_ops = { .apm_config = iwl_pci_apm_config, .set_drv_data = iwl_pci_set_drv_data, .get_dev = iwl_pci_get_dev, + .get_irq = iwl_pci_get_irq, .get_hw_id = iwl_pci_get_hw_id, .write8 = iwl_pci_write8, .write32 = iwl_pci_write32, -- cgit v1.2.3-70-g09d2 From ea3aa93055508ae3e3a62f90580c24ec381dcbe2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 31 May 2011 10:07:00 +0300 Subject: iwlagn: finally kill the pointer to pci_dev from iwl-dev.h All pci related stuff is in iwl-pci.c. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ---- 2 files changed, 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e2b319f3c5f..17228f77d22 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -32,9 +32,6 @@ #include #include #include -/* TODO: remove include to PCI*.h when no PCI will be needed here */ -#include -#include #include #include #include @@ -3488,12 +3485,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, /************************ * 1. Allocating HW data ************************/ - /* TODO: remove this nasty hack when PCI encapsulation is done - * assumes that struct pci_dev * is at the very beginning of whatever - * is pointed by bus_specific */ - unsigned long *ppdev = bus_specific; - struct pci_dev *pdev = (struct pci_dev *) *ppdev; - hw = iwl_alloc_all(cfg); if (!hw) { err = -ENOMEM; @@ -3512,7 +3503,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); priv->cfg = cfg; - priv->pci_dev = pdev; priv->inta_mask = CSR_INI_SET_MASK; /* is antenna coupling more than 35dB ? */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f6b54c6d878..34f9d0f6702 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1293,10 +1293,6 @@ struct iwl_priv { spinlock_t reg_lock; /* protect hw register access */ struct mutex mutex; - /* TODO: remove this after PCI abstraction is done */ - /* basic pci-network driver stuff */ - struct pci_dev *pci_dev; - struct iwl_bus bus; /* bus specific data */ /* microcode/device supports multiple contexts */ -- cgit v1.2.3-70-g09d2 From bcd4fe2f9e378eb8d4d07e3be69e3b82d5e6d4fc Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 9 Jun 2011 02:55:54 -0700 Subject: iwlagn: waterfall the bus level if prepare card failed Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 17228f77d22..bec98bd67ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3540,6 +3540,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, priv->cfg->name, hw_rev); if (iwl_prepare_card_hw(priv)) { + err = -EIO; IWL_WARN(priv, "Failed, HW not ready\n"); goto out_free_traffic_mem; } -- cgit v1.2.3-70-g09d2 From 807caf261c5196b566964ccb9e12d3e25eee9c4a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 9 Jun 2011 02:55:55 -0700 Subject: iwlagn: fix misplaced bracket Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index bec98bd67ab..13828637385 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3488,7 +3488,9 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, hw = iwl_alloc_all(cfg); if (!hw) { err = -ENOMEM; - goto out; } + goto out; + } + priv = hw->priv; priv->bus.priv = priv; -- cgit v1.2.3-70-g09d2 From 4b55b07fc9e5eccfd204cad75509bf062d3c22a3 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 9 Jun 2011 05:48:36 -0700 Subject: iwlagn: warn about nested SYNC commands Since there is no protection around SYNC host command mechanism, at least WARN when collision happens between two SYNC host comamnds. I am not sure there is a real issue (beyond the HCMD_ACTIVE flag maintenance) with having two SYNC host commands at the same time, but at least now, we will know about it. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-hcmd.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 34f9d0f6702..2d13d8928e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1300,6 +1300,7 @@ struct iwl_priv { /* command queue number */ u8 cmd_queue; + u8 last_sync_cmd_id; /* max number of station keys */ u8 sta_key_max_num; diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 76f99662314..7cdb1ec73b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -181,7 +181,16 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); - set_bit(STATUS_HCMD_ACTIVE, &priv->status); + if (test_and_set_bit(STATUS_HCMD_ACTIVE, &priv->status)) { + IWL_ERR(priv, "STATUS_HCMD_ACTIVE already set while sending %s" + ". Previous SYNC cmdn is %s\n", + get_cmd_string(cmd->id), + get_cmd_string(priv->last_sync_cmd_id)); + WARN_ON(1); + } else { + priv->last_sync_cmd_id = cmd->id; + } + IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->id)); -- cgit v1.2.3-70-g09d2 From 705cd4513a2fc561d8a2d5853cffb102bf183d70 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 18 Jun 2011 08:21:12 -0700 Subject: iwlagn: store the irq number to iwl_bus just like dev Since the irq number is just an unsigned int, store it inside iwl_bus instead of calling the get_irq ops every time it is needed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 12 ++++++------ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 13828637385..1ac6c647535 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3496,6 +3496,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, priv->bus.priv = priv; priv->bus.bus_specific = bus_specific; priv->bus.ops = bus_ops; + priv->bus.irq = priv->bus.ops->get_irq(&priv->bus); priv->bus.ops->set_drv_data(&priv->bus, priv); priv->bus.dev = priv->bus.ops->get_dev(&priv->bus); @@ -3603,11 +3604,10 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, ********************/ iwl_alloc_isr_ict(priv); - err = request_irq(priv->bus.ops->get_irq(&priv->bus), iwl_isr_ict, - IRQF_SHARED, DRV_NAME, priv); + err = request_irq(priv->bus.irq, iwl_isr_ict, IRQF_SHARED, + DRV_NAME, priv); if (err) { - IWL_ERR(priv, "Error allocating IRQ %d\n", - priv->bus.ops->get_irq(&priv->bus)); + IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus.irq); goto out_uninit_drv; } @@ -3644,7 +3644,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, out_destroy_workqueue: destroy_workqueue(priv->workqueue); priv->workqueue = NULL; - free_irq(priv->bus.ops->get_irq(&priv->bus), priv); + free_irq(priv->bus.irq, priv); iwl_free_isr_ict(priv); out_uninit_drv: iwl_uninit_drv(priv); @@ -3716,7 +3716,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) priv->workqueue = NULL; iwl_free_traffic_mem(priv); - free_irq(priv->bus.ops->get_irq(&priv->bus), priv); + free_irq(priv->bus.irq, priv); priv->bus.ops->set_drv_data(&priv->bus, NULL); iwl_uninit_drv(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 848a6c3a56a..6d5584ae5eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -125,7 +125,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data); static inline void iwl_synchronize_irq(struct iwl_priv *priv) { /* wait to make sure we flush pending tasklet*/ - synchronize_irq(priv->bus.ops->get_irq(&priv->bus)); + synchronize_irq(priv->bus.irq); tasklet_kill(&priv->irq_tasklet); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2d13d8928e2..8ec04f20c96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1224,6 +1224,7 @@ struct iwl_bus { struct iwl_priv *priv; /* driver's context */ struct device *dev; struct iwl_bus_ops *ops; + unsigned int irq; }; struct iwl_priv { -- cgit v1.2.3-70-g09d2 From 0172b02926493863e2e3a35f1d7bf13e935e655c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 11 Jun 2011 10:00:05 -0700 Subject: iwlagn: add power_save module parameter Add power_save module parameter to enable power management if needed Default power management is disabled. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 +++++++++----- drivers/net/wireless/iwlwifi/iwl-core.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1ac6c647535..b719628b4fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2545,11 +2545,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; - /* - * For now, disable PS by default because it affects - * RX performance significantly. - */ - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + if (iwlagn_mod_params.power_save) + hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; + else + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; /* we create the 802.11 header and a zero-length SSID element */ @@ -3827,6 +3826,11 @@ module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO); MODULE_PARM_DESC(led_mode, "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)"); +module_param_named(power_save, iwlagn_mod_params.power_save, + bool, S_IRUGO); +MODULE_PARM_DESC(power_save, + "enable WiFi power management (default: disable)"); + /* * For now, keep using power level 1 instead of automatically * adjusting ... diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a09361dd62d..6238ac62802 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -163,6 +163,7 @@ struct iwl_mod_params { bool bt_coex_active; /* def: true = enable bt coex */ int led_mode; /* def: 0 = system default */ bool no_sleep_autoadjust; /* def: true = disable autoadjust */ + bool power_save; /* def: false = disable power save */ }; /* -- cgit v1.2.3-70-g09d2 From f7538168915271083070a60ebb10def11fce0cb0 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 11 Jun 2011 10:00:06 -0700 Subject: iwlagn: Add power_level module parameter Add power_level module parameter to set the default power save level. Power save level has range from 1 - 5, default power save level is 1. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-power.c | 12 +++++++++--- 4 files changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 52da53997d4..efdab6506ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -624,6 +624,7 @@ struct iwl_mod_params iwlagn_mod_params = { .plcp_check = true, .bt_coex_active = true, .no_sleep_autoadjust = true, + .power_level = IWL_POWER_INDEX_1, /* the rest are 0 by default */ }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b719628b4fc..77ceb8deff7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3831,6 +3831,11 @@ module_param_named(power_save, iwlagn_mod_params.power_save, MODULE_PARM_DESC(power_save, "enable WiFi power management (default: disable)"); +module_param_named(power_level, iwlagn_mod_params.power_level, + int, S_IRUGO); +MODULE_PARM_DESC(power_level, + "default power save level (range from 1 - 5, default: 1)"); + /* * For now, keep using power level 1 instead of automatically * adjusting ... diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6238ac62802..adf9f9b2efb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -164,6 +164,7 @@ struct iwl_mod_params { int led_mode; /* def: 0 = system default */ bool no_sleep_autoadjust; /* def: true = disable autoadjust */ bool power_save; /* def: false = disable power save */ + int power_level; /* def: 1 = power level */ }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 970c514623b..565e57e48be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -358,9 +358,15 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, iwl_static_sleep_cmd(priv, cmd, priv->power_data.debug_sleep_level_override, dtimper); - else if (iwlagn_mod_params.no_sleep_autoadjust) - iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper); - else + else if (iwlagn_mod_params.no_sleep_autoadjust) { + if (iwlagn_mod_params.power_level > IWL_POWER_INDEX_1 && + iwlagn_mod_params.power_level <= IWL_POWER_INDEX_5) + iwl_static_sleep_cmd(priv, cmd, + iwlagn_mod_params.power_level, dtimper); + else + iwl_static_sleep_cmd(priv, cmd, + IWL_POWER_INDEX_1, dtimper); + } else iwl_power_fill_sleep_cmd(priv, cmd, priv->hw->conf.dynamic_ps_timeout, priv->hw->conf.max_sleep_period); -- cgit v1.2.3-70-g09d2 From e1910cb3190907334788c1887f8f61913208d0f3 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 13 Jun 2011 15:34:25 -0700 Subject: iwlagn: add offset define for subsystem id Add offset define for subsystem id in EEPROM Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 19058a6fac4..c1a17f9eaf3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -268,6 +268,7 @@ extern const u8 iwl_eeprom_band_1[14]; /* General */ #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ +#define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ -- cgit v1.2.3-70-g09d2 From 916b337310969dd5eef35be0988a6bf768c138f9 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 14 Jun 2011 13:00:07 -0700 Subject: iwlagn: code alignment Code alignment, no functional changes. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 406eb2ff5d9..56a22de847d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -80,10 +80,10 @@ static void iwl2000_nic_config(struct iwl_priv *priv) /* write radio config values to register */ if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); /* set CSR_HW_CONFIG_REG for uCode use */ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, -- cgit v1.2.3-70-g09d2 From 86cb3b4e08a106594ee79c94dec9c7ca289cf999 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 14 Jun 2011 15:23:39 -0700 Subject: iwlagn: merge duplicate code into single function Same operation needed by multiple devices, move to single function. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 16 +--------------- drivers/net/wireless/iwlwifi/iwl-5000.c | 17 ++--------------- drivers/net/wireless/iwlwifi/iwl-6000.c | 16 +--------------- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 25 +++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 + 5 files changed, 30 insertions(+), 45 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 56a22de847d..1c1330035ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -74,21 +74,7 @@ static void iwl2000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 2000 series */ static void iwl2000_nic_config(struct iwl_priv *priv) { - u16 radio_cfg; - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + iwl_rf_config(priv); if (priv->cfg->iq_invert) iwl_set_bit(priv, CSR_GP_DRIVER_REG, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 06fe9aded1e..937a8f12afa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -64,23 +64,10 @@ static void iwl5000_nic_config(struct iwl_priv *priv) { unsigned long flags; - u16 radio_cfg; - spin_lock_irqsave(&priv->lock, flags); - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + iwl_rf_config(priv); - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX) - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + spin_lock_irqsave(&priv->lock, flags); /* W/A : NIC is stuck in a reset state after Early PCIe power off * (PCIe power is lost before PERST# is asserted), diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c66bbc6c004..3fcc0925d54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -95,21 +95,7 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { - u16 radio_cfg; - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + iwl_rf_config(priv); /* no locking required for register write */ if (priv->cfg->pa_type == IWL_PA_INTERNAL) { diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 47a56bc1cd1..768d0ee276f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -834,3 +834,28 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, return NULL; } + +void iwl_rf_config(struct iwl_priv *priv) +{ + u16 radio_cfg; + + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", + EEPROM_RF_CFG_TYPE_MSK(radio_cfg), + EEPROM_RF_CFG_STEP_MSK(radio_cfg), + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + } else + WARN_ON(1); + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index c1a17f9eaf3..c6f370f21ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -310,5 +310,6 @@ void iwl_free_channel_map(struct iwl_priv *priv); const struct iwl_channel_info *iwl_get_channel_info( const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); +void iwl_rf_config(struct iwl_priv *priv); #endif /* __iwl_eeprom_h__ */ -- cgit v1.2.3-70-g09d2 From 89434421d86a69af1868b65c5adbb3abda5af54f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 14 Jun 2011 15:23:40 -0700 Subject: iwlagn: remove incorrect define Remove unused and incorrect EEPROM define Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index c6f370f21ee..804f910c651 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -275,7 +275,6 @@ extern const u8 iwl_eeprom_band_1[14]; #define EEPROM_VERSION (2*0x44) /* 2 bytes */ #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ -#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ -- cgit v1.2.3-70-g09d2 From a0087a3619e1b137e7dbc91a1b2b5f15c0382412 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 03:31:40 +0000 Subject: fec: fix race in transmit time stamping. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/fec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 965fe90e1c2..7ae3f281420 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -324,10 +324,10 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) fep->cur_tx = bdp; - spin_unlock_irqrestore(&fep->hw_lock, flags); - skb_tx_timestamp(skb); + spin_unlock_irqrestore(&fep->hw_lock, flags); + return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From d515b450bfd50d355c5b3230685b997faeee5c49 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 03:31:41 +0000 Subject: tg3: fix race in transmit time stamping. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ca6687a9422..97cd02d0802 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6119,11 +6119,11 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) entry = NEXT_TX(tnapi->tx_prod); } + skb_tx_timestamp(skb); + /* Packets are ready, update Tx producer idx local and on card. */ tw32_tx_mbox(tnapi->prodmbox, entry); - skb_tx_timestamp(skb); - tnapi->tx_prod = entry; if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) { netif_tx_stop_queue(txq); -- cgit v1.2.3-70-g09d2 From 2aa8f4c9d0f88ae7eacac424d8816de225cfe2aa Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 03:31:42 +0000 Subject: r6040: fix race in transmit time stamping. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/r6040.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 5ee5f8f932f..00f06e9a779 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -836,6 +836,9 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb, descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE)); descptr->status = DSC_OWNER_MAC; + + skb_tx_timestamp(skb); + /* Trigger the MAC to check the TX descriptor */ iowrite16(0x01, ioaddr + MTPR); lp->tx_insert_ptr = descptr->vndescp; @@ -846,8 +849,6 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb, spin_unlock_irqrestore(&lp->lock, flags); - skb_tx_timestamp(skb); - return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From 52f64faeb0fdcd49f14586beab83eabc9170b6a1 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 03:31:43 +0000 Subject: stmmac: fix race in transmit time stamping. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 5b85f4ca200..d4adc806f6f 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1079,10 +1079,10 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_bytes += skb->len; - priv->hw->dma->enable_dma_transmission(priv->ioaddr); - skb_tx_timestamp(skb); + priv->hw->dma->enable_dma_transmission(priv->ioaddr); + return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From 6241207253b940048ffb6ba483a248813261ce6a Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 03:31:44 +0000 Subject: smsc9420: fix race in transmit time stamping. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/smsc9420.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 5555102bb96..459726f5475 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -1031,12 +1031,12 @@ static netdev_tx_t smsc9420_hard_start_xmit(struct sk_buff *skb, pd->tx_ring[index].status = TDES0_OWN_; wmb(); + skb_tx_timestamp(skb); + /* kick the DMA */ smsc9420_reg_write(pd, TX_POLL_DEMAND, 1); smsc9420_pci_flush_write(pd); - skb_tx_timestamp(skb); - return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From 5bf0c1913498e55f1bf4c56fef6dacf2feb049bb Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 03:31:45 +0000 Subject: davinci_emac: fix race in transmit time stamping. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/davinci_emac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index f5688ff58a4..55c8245b0cd 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1083,6 +1083,8 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) goto fail_tx; } + skb_tx_timestamp(skb); + ret_code = cpdma_chan_submit(priv->txchan, skb, skb->data, skb->len, GFP_KERNEL); if (unlikely(ret_code != 0)) { @@ -1090,7 +1092,6 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) dev_err(emac_dev, "DaVinci EMAC: desc submit failed"); goto fail_tx; } - skb_tx_timestamp(skb); return NETDEV_TX_OK; -- cgit v1.2.3-70-g09d2 From cf05c700cf6dd6f28bd95586d3040f809fd365f5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 19 Jun 2011 22:48:34 -0700 Subject: veth: fix 64bit stats on 32bit arches Using 64bit stats on 32bit arches must use a synchronization or readers can get transient values. Fixes bug introduced in commit 6311cc44a2 (veth: convert to 64 bit statistics) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/veth.c | 55 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 8730d649463..4b6db3b6c5d 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -24,12 +25,13 @@ #define MAX_MTU 65535 /* Max L3 MTU (arbitrary) */ struct veth_net_stats { - u64 rx_packets; - u64 tx_packets; - u64 rx_bytes; - u64 tx_bytes; - u64 tx_dropped; - u64 rx_dropped; + u64 rx_packets; + u64 tx_packets; + u64 rx_bytes; + u64 tx_bytes; + u64 rx_dropped; + u64 tx_dropped; + struct u64_stats_sync syncp; }; struct veth_priv { @@ -137,21 +139,29 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS) goto rx_drop; + u64_stats_update_begin(&stats->syncp); stats->tx_bytes += length; stats->tx_packets++; + u64_stats_update_end(&stats->syncp); + u64_stats_update_begin(&rcv_stats->syncp); rcv_stats->rx_bytes += length; rcv_stats->rx_packets++; + u64_stats_update_end(&rcv_stats->syncp); return NETDEV_TX_OK; tx_drop: kfree_skb(skb); + u64_stats_update_begin(&stats->syncp); stats->tx_dropped++; + u64_stats_update_end(&stats->syncp); return NETDEV_TX_OK; rx_drop: + u64_stats_update_begin(&rcv_stats->syncp); rcv_stats->rx_dropped++; + u64_stats_update_end(&rcv_stats->syncp); return NETDEV_TX_OK; } @@ -162,21 +172,30 @@ rx_drop: static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *tot) { - struct veth_priv *priv; + struct veth_priv *priv = netdev_priv(dev); int cpu; - struct veth_net_stats *stats; - - priv = netdev_priv(dev); for_each_possible_cpu(cpu) { - stats = per_cpu_ptr(priv->stats, cpu); - - tot->rx_packets += stats->rx_packets; - tot->tx_packets += stats->tx_packets; - tot->rx_bytes += stats->rx_bytes; - tot->tx_bytes += stats->tx_bytes; - tot->tx_dropped += stats->tx_dropped; - tot->rx_dropped += stats->rx_dropped; + struct veth_net_stats *stats = per_cpu_ptr(priv->stats, cpu); + u64 rx_packets, rx_bytes, rx_dropped; + u64 tx_packets, tx_bytes, tx_dropped; + unsigned int start; + + do { + start = u64_stats_fetch_begin_bh(&stats->syncp); + rx_packets = stats->rx_packets; + tx_packets = stats->tx_packets; + rx_bytes = stats->rx_bytes; + tx_bytes = stats->tx_bytes; + rx_dropped = stats->rx_dropped; + tx_dropped = stats->tx_dropped; + } while (u64_stats_fetch_retry_bh(&stats->syncp, start)); + tot->rx_packets += rx_packets; + tot->tx_packets += tx_packets; + tot->rx_bytes += rx_bytes; + tot->tx_bytes += tx_bytes; + tot->rx_dropped += rx_dropped; + tot->tx_dropped += tx_dropped; } return tot; -- cgit v1.2.3-70-g09d2 From 2055403ded0b16b8fdb7d6f188dccdc9ca35d7d5 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 14 Jun 2011 01:34:38 +0300 Subject: iwlegacy: fix stop/wake queue hacks The hacks break once mac80211-compat.h is taken into use. Fix it by adding an ifdef check. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-helpers.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-helpers.h b/drivers/net/wireless/iwlegacy/iwl-helpers.h index a6effdae63f..5cf23eaecbb 100644 --- a/drivers/net/wireless/iwlegacy/iwl-helpers.h +++ b/drivers/net/wireless/iwlegacy/iwl-helpers.h @@ -132,7 +132,16 @@ static inline void iwl_legacy_stop_queue(struct iwl_priv *priv, ieee80211_stop_queue(priv->hw, ac); } +#ifdef ieee80211_stop_queue +#undef ieee80211_stop_queue +#endif + #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue + +#ifdef ieee80211_wake_queue +#undef ieee80211_wake_queue +#endif + #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) -- cgit v1.2.3-70-g09d2 From 47751b0fbff55f5f65d1a4d24ca10acd90259fc1 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 14 Jun 2011 01:34:50 +0300 Subject: iwlwifi: fix stop/wake queue hacks The hacks break once mac80211-compat.h is taken into use. Fix it by adding an ifdef check. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-helpers.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 41207a3645b..9d91552d13c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -120,7 +120,16 @@ static inline void iwl_wake_any_queue(struct iwl_priv *priv, } } +#ifdef ieee80211_stop_queue +#undef ieee80211_stop_queue +#endif + #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue + +#ifdef ieee80211_wake_queue +#undef ieee80211_wake_queue +#endif + #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue static inline void iwl_disable_interrupts(struct iwl_priv *priv) -- cgit v1.2.3-70-g09d2 From 9a0669681c2d94fa198a82d108918def55a7cd70 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 14 Jun 2011 01:34:57 +0300 Subject: zd1211rw: include mac80211.h from zd_chip.h zd_chip.h contains one function with a pointer to ieee80211_hw but doesn't include mac80211.h. As a temporary solution include mac80211.h to avoid a warning. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 4be7c3b5b26..117c4123943 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -21,6 +21,8 @@ #ifndef _ZD_CHIP_H #define _ZD_CHIP_H +#include + #include "zd_rf.h" #include "zd_usb.h" -- cgit v1.2.3-70-g09d2 From 0521ecf335ce36394a3403fdd48aa87a0352c7d6 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 14 Jun 2011 01:35:04 +0300 Subject: rtlwifi: include mac80211.h from core.h core.h references ieee80211_ops but doesn't include mac80211.h, which issues a warning once mac80211-compat.h is taken into use. Acked-by: Larry Finger Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 4b247db2861..f02824a3b74 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -30,6 +30,8 @@ #ifndef __RTL_CORE_H__ #define __RTL_CORE_H__ +#include + #define RTL_SUPPORTED_FILTERS \ (FIF_PROMISC_IN_BSS | \ FIF_ALLMULTI | FIF_CONTROL | \ -- cgit v1.2.3-70-g09d2 From 81dc67601a49d1bfcfa85f644b14a013fc59e0ef Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 17 Jun 2011 11:07:32 +0530 Subject: ath9k: Fix a corner case failure in sending PAPRD frames in HT40 when the AP is configured with HT40/2.4GHz and when PAPRD is enabled in station we have PAPRD training frames never sent out because of the following failure "PAPRD target power delta out of range". This consistently happens in channel 10,11 in Over The Air testing and rarely in channel 6 under wired setup. the reason behind this issue is all the HT40 rates target power are 0 when we operate in channel 10/11 at 2.4GHz Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index ff8150e46f0..2e370c668d4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -1461,7 +1461,7 @@ static const struct ar9300_eeprom ar9300_h112 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -2616,7 +2616,7 @@ static const struct ar9300_eeprom ar9300_h116 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, -- cgit v1.2.3-70-g09d2 From 0e44d48cbb010db492a27302b247049d5d43e065 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 17 Jun 2011 14:08:42 +0530 Subject: ath9k_hw: make sure PAPRD training is properly done checking the status of PAPRD_AGC2_POWER(Log(ADC_power) measured after last gain-change in dB) field suggests whether the PAPRD is completely/properly done. This is an additional check apart from polling for PAPRD done bit being set. Susinder suggests that the ideal power range value should be 0xf0 to 0xfe. With AR9382 we do have the values in this range. to have a common check for all platforms we take agc2_power should be atleast greater than 0xe0 Cc: susinder@qca.qualcomm.com Cc: senthilb@qca.qualcomm.com Cc: kmuthusa@qca.qualcomm.com Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 21 ++++++++++++++++++++- drivers/net/wireless/ath/ath9k/hw.h | 5 +++-- 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2e7f0f2567e..fc9c08f513c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -785,7 +785,26 @@ EXPORT_SYMBOL(ar9003_paprd_init_table); bool ar9003_paprd_is_done(struct ath_hw *ah) { - return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, + int paprd_done, agc2_pwr; + paprd_done = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); + + if (paprd_done == 0x1) { + agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR); + + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "AGC2_PWR = 0x%x training done = 0x%x\n", + agc2_pwr, paprd_done); + /* + * agc2_pwr range should not be less than 'IDEAL_AGC2_PWR_CHANGE' + * when the training is completely done, otherwise retraining is + * done to make sure the value is in ideal range + */ + if (agc2_pwr <= PAPRD_IDEAL_AGC2_PWR_RANGE) + paprd_done = 0; + } + + return !!paprd_done; } EXPORT_SYMBOL(ar9003_paprd_is_done); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6a6fb543983..66d2225b95f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -157,8 +157,9 @@ #define ATH9K_HW_RX_HP_QDEPTH 16 #define ATH9K_HW_RX_LP_QDEPTH 128 -#define PAPRD_GAIN_TABLE_ENTRIES 32 -#define PAPRD_TABLE_SZ 24 +#define PAPRD_GAIN_TABLE_ENTRIES 32 +#define PAPRD_TABLE_SZ 24 +#define PAPRD_IDEAL_AGC2_PWR_RANGE 0xe0 enum ath_hw_txq_subtype { ATH_TXQ_AC_BE = 0, -- cgit v1.2.3-70-g09d2 From 0e8d1602b223efcd4eaaa799314f5d7ad1742035 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 17 Jun 2011 16:41:30 -0400 Subject: ath5k: free sc->ah in ath5k_deinit_softc Nothing else is freeing it, and this mirrors the error handling path already in ath5k_init_softc. https://bugzilla.kernel.org/show_bug.cgi?id=37592 Signed-off-by: John W. Linville Reported-by: Tsyvarev Andrey --- drivers/net/wireless/ath/ath5k/base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3e70b1418a4..a6623ddfdef 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2960,6 +2960,7 @@ ath5k_deinit_softc(struct ath5k_softc *sc) * state and potentially want to use them. */ ath5k_hw_deinit(sc->ah); + kfree(sc->ah); free_irq(sc->irq, sc); } -- cgit v1.2.3-70-g09d2 From 536e5189ffdf17047f129f4730d947ab11a8526b Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 17 Jun 2011 17:59:02 -0400 Subject: ath5k: add missing ieee80211_free_hw() on unload in AHB code Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index ea998278155..c38e9e84899 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -219,6 +219,7 @@ static int ath_ahb_remove(struct platform_device *pdev) ath5k_deinit_softc(sc); platform_set_drvdata(pdev, NULL); + ieee80211_free_hw(hw); return 0; } -- cgit v1.2.3-70-g09d2 From 9c0504403725ca77153a0bdad2f3bef0a05e32f0 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 20 Jun 2011 10:44:58 +0900 Subject: rtlwifi: Fix typo in variable name offchan_deley should be offchan_delay Signed-off-by: Mike McCormack Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 4 ++-- drivers/net/wireless/rtlwifi/pci.c | 2 +- drivers/net/wireless/rtlwifi/wifi.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 605514bdd24..3313ce6ffaa 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -335,8 +335,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) * before going offchannel, or dis-association or delete BA will * happen by AP */ - if (rtlpriv->mac80211.offchan_deley) { - rtlpriv->mac80211.offchan_deley = false; + if (rtlpriv->mac80211.offchan_delay) { + rtlpriv->mac80211.offchan_delay = false; mdelay(50); } rtlphy->current_channel = wide_chan; diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index cb4e5e80c9c..ad39af462f8 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -581,7 +581,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) fc = rtl_get_fc(skb); if (ieee80211_is_nullfunc(fc)) { if (ieee80211_has_pm(fc)) { - rtlpriv->mac80211.offchan_deley = true; + rtlpriv->mac80211.offchan_delay = true; rtlpriv->psc.state_inap = 1; } else { rtlpriv->psc.state_inap = 0; diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index fcf2c9f5437..c54cda5ce22 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -938,7 +938,7 @@ struct rtl_mac { int n_channels; int n_bitrates; - bool offchan_deley; + bool offchan_delay; /*filters */ u32 rx_conf; -- cgit v1.2.3-70-g09d2 From 4b9d8d67b44aae18e1c4b71281f5cfc0f2105cf6 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 20 Jun 2011 10:46:05 +0900 Subject: rtlwifi: rtl8192cu: Remove unused parameter rtl_ps_set_rf_state's protect_or_not parameter is not set to true anywhere, except for commented out code. It enables some legacy locking code, which is no longer used, so delete the parameter and the old locking code. Signed-off-by: Mike McCormack Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/ps.c | 63 ++--------------------------- drivers/net/wireless/rtlwifi/ps.h | 3 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 3 +- 3 files changed, 7 insertions(+), 62 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index d14c13d0217..3eb039a0528 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -79,53 +79,12 @@ EXPORT_SYMBOL(rtl_ps_disable_nic); bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, enum rf_pwrstate state_toset, - u32 changesource, bool protect_or_not) + u32 changesource) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool actionallowed = false; - u16 rfwait_cnt = 0; - /*protect_or_not = true; */ - - if (protect_or_not) - goto no_protect; - - /* - *Only one thread can change - *the RF state at one time, and others - *should wait to be executed. - */ - while (true) { - spin_lock(&rtlpriv->locks.rf_ps_lock); - if (ppsc->rfchange_inprogress) { - spin_unlock(&rtlpriv->locks.rf_ps_lock); - - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("RF Change in progress!" - "Wait to set..state_toset(%d).\n", - state_toset)); - - /* Set RF after the previous action is done. */ - while (ppsc->rfchange_inprogress) { - rfwait_cnt++; - mdelay(1); - - /* - *Wait too long, return false to avoid - *to be stuck here. - */ - if (rfwait_cnt > 100) - return false; - } - } else { - ppsc->rfchange_inprogress = true; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - break; - } - } - -no_protect: switch (state_toset) { case ERFON: ppsc->rfoff_reason &= (~changesource); @@ -167,12 +126,6 @@ no_protect: if (actionallowed) rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); - if (!protect_or_not) { - spin_lock(&rtlpriv->locks.rf_ps_lock); - ppsc->rfchange_inprogress = false; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - } - return actionallowed; } EXPORT_SYMBOL(rtl_ps_set_rf_state); @@ -195,8 +148,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) } } - rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, - RF_CHANGE_BY_IPS, false); + rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, RF_CHANGE_BY_IPS); if (ppsc->inactive_pwrstate == ERFOFF && rtlhal->interface == INTF_PCI) { @@ -587,7 +539,7 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) } spin_lock(&rtlpriv->locks.lps_lock); - rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); + rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); spin_unlock(&rtlpriv->locks.lps_lock); } @@ -621,15 +573,8 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) if (rtlpriv->link_info.busytraffic) return; - spin_lock(&rtlpriv->locks.rf_ps_lock); - if (rtlpriv->psc.rfchange_inprogress) { - spin_unlock(&rtlpriv->locks.rf_ps_lock); - return; - } - spin_unlock(&rtlpriv->locks.rf_ps_lock); - spin_lock(&rtlpriv->locks.lps_lock); - rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); + rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); spin_unlock(&rtlpriv->locks.lps_lock); if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index e3bf8984037..84628e6041c 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h @@ -33,8 +33,7 @@ #define MAX_SW_LPS_SLEEP_INTV 5 bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, - enum rf_pwrstate state_toset, u32 changesource, - bool protect_or_not); + enum rf_pwrstate state_toset, u32 changesource); bool rtl_ps_enable_nic(struct ieee80211_hw *hw); bool rtl_ps_disable_nic(struct ieee80211_hw *hw); void rtl_ips_nic_off(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 5fab47b2218..9ed5e245e94 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -994,7 +994,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT; rtlpriv->psc.rfpwr_state = ERFON; - rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason, true); + /* FIXME: check spinlocks if this block is uncommented */ + rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason); } else { /* gpio radio on/off is out of adapter start */ if (rtlpriv->psc.hwradiooff == false) { -- cgit v1.2.3-70-g09d2 From e10542c447abf7c840931ff12f7d0dee976ca2ea Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 20 Jun 2011 10:47:51 +0900 Subject: rtlwifi: rtl8192{c,ce,cu,se}: Remove comparisons of booleans with true These are a potential source of confusion, as most C code treats all non-zero values as true. Signed-off-by: Mike McCormack Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 2 +- drivers/net/wireless/rtlwifi/core.c | 4 ++-- drivers/net/wireless/rtlwifi/efuse.c | 8 ++++---- drivers/net/wireless/rtlwifi/ps.c | 2 +- drivers/net/wireless/rtlwifi/rc.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 10 +++++----- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 6 +++--- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 8 ++++---- drivers/net/wireless/rtlwifi/rtl8192cu/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 6 +++--- drivers/net/wireless/rtlwifi/rtl8192se/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 6 +++--- 20 files changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index fb5e43bd7c3..bc13533a541 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -523,7 +523,7 @@ static void _rtl_query_shortgi(struct ieee80211_hw *hw, mac->opmode == NL80211_IFTYPE_ADHOC) bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; - if ((bw_40 == true) && sgi_40) + if (bw_40 && sgi_40) tcb_desc->use_shortgi = true; else if ((bw_40 == false) && sgi_20) tcb_desc->use_shortgi = true; diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 3313ce6ffaa..03ce69660b2 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -443,11 +443,11 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, sta_entry->wireless_mode = WIRELESS_MODE_G; if (sta->supp_rates[0] <= 0xf) sta_entry->wireless_mode = WIRELESS_MODE_B; - if (sta->ht_cap.ht_supported == true) + if (sta->ht_cap.ht_supported) sta_entry->wireless_mode = WIRELESS_MODE_N_24G; } else if (rtlhal->current_bandtype == BAND_ON_5G) { sta_entry->wireless_mode = WIRELESS_MODE_A; - if (sta->ht_cap.ht_supported == true) + if (sta->ht_cap.ht_supported) sta_entry->wireless_mode = WIRELESS_MODE_N_24G; } diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 0b562322f13..3fc21f60bb0 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -382,7 +382,7 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) } } - if (wordchanged == true) + if (wordchanged) hdr_num++; } @@ -453,7 +453,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) base = offset * 8; for (i = 0; i < 8; i++) { - if (first_pg == true) { + if (first_pg) { word_en &= ~(BIT(i / 2)); @@ -505,7 +505,7 @@ void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - if (rtlefuse->autoload_failflag == true) + if (rtlefuse->autoload_failflag) memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); else @@ -690,7 +690,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } } - if (dataempty == true) { + if (dataempty) { *readstate = PG_STATE_DATA; } else { *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 3eb039a0528..a693feffbe7 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -90,7 +90,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, ppsc->rfoff_reason &= (~changesource); if ((changesource == RF_CHANGE_BY_HW) && - (ppsc->hwradiooff == true)) { + (ppsc->hwradiooff)) { ppsc->hwradiooff = false; } diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 30da68a7778..539df66dce0 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -200,7 +200,7 @@ static void rtl_tx_status(void *ppriv, if (sta) { /* Check if aggregation has to be enabled for this tid */ sta_entry = (struct rtl_sta_info *) sta->drv_priv; - if ((sta->ht_cap.ht_supported == true) && + if ((sta->ht_cap.ht_supported) && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { if (ieee80211_is_data_qos(fc)) { u8 tid = rtl_get_tid(skb); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 57d52e914f1..a00774e7090 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -474,7 +474,7 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) { struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - if (mac->act_scanning == true) + if (mac->act_scanning) return; if (mac->link_state >= MAC80211_LINKED) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 944f55e9d31..bc6ae9dcf94 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -488,7 +488,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_CORRECT_TSF:{ u8 btype_ibss = ((u8 *) (val))[0]; - if (btype_ibss == true) + if (btype_ibss) _rtl92ce_stop_tx_beacon(hw); _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); @@ -500,7 +500,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); - if (btype_ibss == true) + if (btype_ibss) _rtl92ce_resume_tx_beacon(hw); break; @@ -1121,7 +1121,7 @@ void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (check_bssid == true) { + if (check_bssid) { reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (®_rcr)); @@ -1585,7 +1585,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag = false; } - if (rtlefuse->autoload_failflag == true) + if (rtlefuse->autoload_failflag) return; for (i = 0; i < 6; i += 2) { @@ -1994,7 +1994,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; - if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { + if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("GPIOChangeRF - HW Radio ON, RF ON\n")); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 9dd1ed7b642..28a1a707d09 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -84,7 +84,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (pcipriv->ledctl.led_opendrain == true) + if (pcipriv->ledctl.led_opendrain) rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(1) | BIT(5) | BIT(6))); else diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 90d0f2cf3b2..d3b01e6023b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -76,7 +76,7 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, if (rtlefuse->eeprom_regulatory != 0) turbo_scanoff = true; - if (mac->act_scanning == true) { + if (mac->act_scanning) { tx_agc[RF90_PATH_A] = 0x3f3f3f3f; tx_agc[RF90_PATH_B] = 0x3f3f3f3f; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index be375214ad9..230bbe900d8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -678,7 +678,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, GET_RX_DESC_PAGGR(pdesc)); rx_status->mactime = GET_RX_DESC_TSFL(pdesc); - if (phystatus == true) { + if (phystatus) { p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + stats->rx_bufshift); @@ -927,7 +927,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) { - if (istx == true) { + if (istx) { switch (desc_name) { case HW_DESC_OWN: wmb(); @@ -968,7 +968,7 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) { u32 ret = 0; - if (istx == true) { + if (istx) { switch (desc_name) { case HW_DESC_OWN: ret = GET_TX_DESC_OWN(p_desc); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 52e2af58c1e..2b34764fbf7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -520,7 +520,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); rtlefuse->autoload_failflag = false; } - if (rtlefuse->autoload_failflag == true) + if (rtlefuse->autoload_failflag) return; for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; @@ -1594,7 +1594,7 @@ static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, default: break; } - if (filterout_non_associated_bssid == true) { + if (filterout_non_associated_bssid) { if (IS_NORMAL_CHIP(rtlhal->version)) { switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: @@ -2155,7 +2155,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_CORRECT_TSF:{ u8 btype_ibss = ((u8 *) (val))[0]; - if (btype_ibss == true) + if (btype_ibss) _rtl92cu_stop_tx_beacon(hw); _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & @@ -2163,7 +2163,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_dword(rtlpriv, REG_TSFTR + 4, (u32)((mac->tsf >> 32) & 0xffffffff)); _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); - if (btype_ibss == true) + if (btype_ibss) _rtl92cu_resume_tx_beacon(hw); break; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 332c74348a6..2ff9d8314e7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -82,7 +82,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (usbpriv->ledctl.led_opendrain == true) + if (usbpriv->ledctl.led_opendrain) rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(1) | BIT(5) | BIT(6))); else diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index c7576ec4744..1e851aae58d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -82,7 +82,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, (rtlefuse->external_pa)) turbo_scanoff = true; } - if (mac->act_scanning == true) { + if (mac->act_scanning) { tx_agc[RF90_PATH_A] = 0x3f3f3f3f; tx_agc[RF90_PATH_B] = 0x3f3f3f3f; if (turbo_scanoff) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 3a92ba3c4a1..906e7aa55bc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -342,7 +342,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, (u8)GET_RX_DESC_RX_MCS(pdesc), (bool)GET_RX_DESC_PAGGR(pdesc)); rx_status->mactime = GET_RX_DESC_TSFL(pdesc); - if (phystatus == true) { + if (phystatus) { p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, p_drvinfo); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 609c7ec7e66..4203a8531ca 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -452,7 +452,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (digtable.backoff_enable_flag == true) + if (digtable.backoff_enable_flag) rtl92s_backoff_enable_flag(hw); else digtable.backoff_val = DM_DIG_BACKOFF; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 9ed5e245e94..13da7b3c020 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1106,7 +1106,7 @@ void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (check_bssid == true) { + if (check_bssid) { reg_rcr |= (RCR_CBSSID); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); } else if (check_bssid == false) { @@ -1652,7 +1652,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag = false; } - if (rtlefuse->autoload_failflag == true) + if (rtlefuse->autoload_failflag) return; _rtl8192se_get_IC_Inferiority(hw); @@ -2302,7 +2302,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) rfpwr_toset = _rtl92se_rf_onoff_detect(hw); - if ((ppsc->hwradiooff == true) && (rfpwr_toset == ERFON)) { + if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("RFKILL-HW Radio ON, RF ON\n")); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index 6d4f6661668..e3fe7c90ebf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -90,7 +90,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (pcipriv->ledctl.led_opendrain == true) + if (pcipriv->ledctl.led_opendrain) rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1))); else rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 7ee2daccd7d..81a5aa4370c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -1416,7 +1416,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_HIGH_PWR_ENABLE: if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || - (rtlpriv->dm.dynamic_txpower_enable == true)) + rtlpriv->dm.dynamic_txpower_enable) break; /* CCA threshold */ @@ -1608,7 +1608,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) fw_cmdmap &= ~FW_DIG_ENABLE_CTL; if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || - (rtlpriv->dm.dynamic_txpower_enable == true)) + rtlpriv->dm.dynamic_txpower_enable) fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; if ((digtable.dig_ext_port_stage == diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 1d3a4833039..c6e3a4ca42f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -410,7 +410,7 @@ void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel) (rtlefuse->eeprom_regulatory != 0))) dont_inc_cck_or_turboscanoff = true; - if (mac->act_scanning == true) { + if (mac->act_scanning) { txagc = 0x3f; if (dont_inc_cck_or_turboscanoff) txagc = pwrlevel; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index d509cf6a1e4..cffe30851f7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -661,7 +661,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc); - if (phystatus == true) { + if (phystatus) { p_drvinfo = (struct rx_fwinfo *)(skb->data + stats->rx_bufshift); _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc, @@ -900,7 +900,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) { - if (istx == true) { + if (istx) { switch (desc_name) { case HW_DESC_OWN: wmb(); @@ -941,7 +941,7 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) { u32 ret = 0; - if (istx == true) { + if (istx) { switch (desc_name) { case HW_DESC_OWN: ret = GET_TX_DESC_OWN(desc); -- cgit v1.2.3-70-g09d2 From 1b9c4134c126aa8ae00a57672d4a4eaecc436b54 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 20 Jun 2011 12:51:22 -0700 Subject: myri_sbus: remove driver Remove the myri_sbus driver. Why? * There is no possibility of ethernet mode on this adapter, so it's Myrinet only. * It won't inter-op with modern versions of Myrinet, and thus can only work with legacy adapters. * There are no in-kernel Linux drivers for the PCI version of this adapter, so it only can work on ~15 year old Sun hardware. It's long in the tooth, let's take it to the knackers. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/Kconfig | 9 - drivers/net/Makefile | 1 - drivers/net/myri_sbus.c | 1187 ----------------------------------------------- drivers/net/myri_sbus.h | 311 ------------- 4 files changed, 1508 deletions(-) delete mode 100644 drivers/net/myri_sbus.c delete mode 100644 drivers/net/myri_sbus.h (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 399cf4b28ae..f5919c28a4b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2196,15 +2196,6 @@ config IGBVF source "drivers/net/ixp2000/Kconfig" -config MYRI_SBUS - tristate "MyriCOM Gigabit Ethernet support" - depends on SBUS - help - This driver supports MyriCOM Sbus gigabit Ethernet cards. - - To compile this driver as a module, choose M here: the module - will be called myri_sbus. This is recommended. - config NS83820 tristate "National Semiconductor DP83820 support" depends on PCI diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 800684104b1..86f6c8d0840 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -59,7 +59,6 @@ obj-$(CONFIG_HAPPYMEAL) += sunhme.o obj-$(CONFIG_SUNLANCE) += sunlance.o obj-$(CONFIG_SUNQE) += sunqe.o obj-$(CONFIG_SUNBMAC) += sunbmac.o -obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o obj-$(CONFIG_CASSINI) += cassini.o obj-$(CONFIG_SUNVNET) += sunvnet.o diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c deleted file mode 100644 index 53aeea4b536..00000000000 --- a/drivers/net/myri_sbus.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* myri_sbus.c: MyriCOM MyriNET SBUS card driver. - * - * Copyright (C) 1996, 1999, 2006, 2008 David S. Miller (davem@davemloft.net) - */ - -static char version[] = - "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "myri_sbus.h" - -/* #define DEBUG_DETECT */ -/* #define DEBUG_IRQ */ -/* #define DEBUG_TRANSMIT */ -/* #define DEBUG_RECEIVE */ -/* #define DEBUG_HEADER */ - -#ifdef DEBUG_DETECT -#define DET(x) printk x -#else -#define DET(x) -#endif - -#ifdef DEBUG_IRQ -#define DIRQ(x) printk x -#else -#define DIRQ(x) -#endif - -#ifdef DEBUG_TRANSMIT -#define DTX(x) printk x -#else -#define DTX(x) -#endif - -#ifdef DEBUG_RECEIVE -#define DRX(x) printk x -#else -#define DRX(x) -#endif - -#ifdef DEBUG_HEADER -#define DHDR(x) printk x -#else -#define DHDR(x) -#endif - -/* Firmware name */ -#define FWNAME "myricom/lanai.bin" - -static void myri_reset_off(void __iomem *lp, void __iomem *cregs) -{ - /* Clear IRQ mask. */ - sbus_writel(0, lp + LANAI_EIMASK); - - /* Turn RESET function off. */ - sbus_writel(CONTROL_ROFF, cregs + MYRICTRL_CTRL); -} - -static void myri_reset_on(void __iomem *cregs) -{ - /* Enable RESET function. */ - sbus_writel(CONTROL_RON, cregs + MYRICTRL_CTRL); - - /* Disable IRQ's. */ - sbus_writel(CONTROL_DIRQ, cregs + MYRICTRL_CTRL); -} - -static void myri_disable_irq(void __iomem *lp, void __iomem *cregs) -{ - sbus_writel(CONTROL_DIRQ, cregs + MYRICTRL_CTRL); - sbus_writel(0, lp + LANAI_EIMASK); - sbus_writel(ISTAT_HOST, lp + LANAI_ISTAT); -} - -static void myri_enable_irq(void __iomem *lp, void __iomem *cregs) -{ - sbus_writel(CONTROL_EIRQ, cregs + MYRICTRL_CTRL); - sbus_writel(ISTAT_HOST, lp + LANAI_EIMASK); -} - -static inline void bang_the_chip(struct myri_eth *mp) -{ - struct myri_shmem __iomem *shmem = mp->shmem; - void __iomem *cregs = mp->cregs; - - sbus_writel(1, &shmem->send); - sbus_writel(CONTROL_WON, cregs + MYRICTRL_CTRL); -} - -static int myri_do_handshake(struct myri_eth *mp) -{ - struct myri_shmem __iomem *shmem = mp->shmem; - void __iomem *cregs = mp->cregs; - struct myri_channel __iomem *chan = &shmem->channel; - int tick = 0; - - DET(("myri_do_handshake: ")); - if (sbus_readl(&chan->state) == STATE_READY) { - DET(("Already STATE_READY, failed.\n")); - return -1; /* We're hosed... */ - } - - myri_disable_irq(mp->lregs, cregs); - - while (tick++ < 25) { - u32 softstate; - - /* Wake it up. */ - DET(("shakedown, CONTROL_WON, ")); - sbus_writel(1, &shmem->shakedown); - sbus_writel(CONTROL_WON, cregs + MYRICTRL_CTRL); - - softstate = sbus_readl(&chan->state); - DET(("chanstate[%08x] ", softstate)); - if (softstate == STATE_READY) { - DET(("wakeup successful, ")); - break; - } - - if (softstate != STATE_WFN) { - DET(("not WFN setting that, ")); - sbus_writel(STATE_WFN, &chan->state); - } - - udelay(20); - } - - myri_enable_irq(mp->lregs, cregs); - - if (tick > 25) { - DET(("25 ticks we lose, failure.\n")); - return -1; - } - DET(("success\n")); - return 0; -} - -static int __devinit myri_load_lanai(struct myri_eth *mp) -{ - const struct firmware *fw; - struct net_device *dev = mp->dev; - struct myri_shmem __iomem *shmem = mp->shmem; - void __iomem *rptr; - int i, lanai4_data_size; - - myri_disable_irq(mp->lregs, mp->cregs); - myri_reset_on(mp->cregs); - - rptr = mp->lanai; - for (i = 0; i < mp->eeprom.ramsz; i++) - sbus_writeb(0, rptr + i); - - if (mp->eeprom.cpuvers >= CPUVERS_3_0) - sbus_writel(mp->eeprom.cval, mp->lregs + LANAI_CVAL); - - i = request_firmware(&fw, FWNAME, &mp->myri_op->dev); - if (i) { - printk(KERN_ERR "Failed to load image \"%s\" err %d\n", - FWNAME, i); - return i; - } - if (fw->size < 2) { - printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", - fw->size, FWNAME); - release_firmware(fw); - return -EINVAL; - } - lanai4_data_size = fw->data[0] << 8 | fw->data[1]; - - /* Load executable code. */ - for (i = 2; i < fw->size; i++) - sbus_writeb(fw->data[i], rptr++); - - /* Load data segment. */ - for (i = 0; i < lanai4_data_size; i++) - sbus_writeb(0, rptr++); - - /* Set device address. */ - sbus_writeb(0, &shmem->addr[0]); - sbus_writeb(0, &shmem->addr[1]); - for (i = 0; i < 6; i++) - sbus_writeb(dev->dev_addr[i], - &shmem->addr[i + 2]); - - /* Set SBUS bursts and interrupt mask. */ - sbus_writel(((mp->myri_bursts & 0xf8) >> 3), &shmem->burst); - sbus_writel(SHMEM_IMASK_RX, &shmem->imask); - - /* Release the LANAI. */ - myri_disable_irq(mp->lregs, mp->cregs); - myri_reset_off(mp->lregs, mp->cregs); - myri_disable_irq(mp->lregs, mp->cregs); - - /* Wait for the reset to complete. */ - for (i = 0; i < 5000; i++) { - if (sbus_readl(&shmem->channel.state) != STATE_READY) - break; - else - udelay(10); - } - - if (i == 5000) - printk(KERN_ERR "myricom: Chip would not reset after firmware load.\n"); - - i = myri_do_handshake(mp); - if (i) - printk(KERN_ERR "myricom: Handshake with LANAI failed.\n"); - - if (mp->eeprom.cpuvers == CPUVERS_4_0) - sbus_writel(0, mp->lregs + LANAI_VERS); - - release_firmware(fw); - return i; -} - -static void myri_clean_rings(struct myri_eth *mp) -{ - struct sendq __iomem *sq = mp->sq; - struct recvq __iomem *rq = mp->rq; - int i; - - sbus_writel(0, &rq->tail); - sbus_writel(0, &rq->head); - for (i = 0; i < (RX_RING_SIZE+1); i++) { - if (mp->rx_skbs[i] != NULL) { - struct myri_rxd __iomem *rxd = &rq->myri_rxd[i]; - u32 dma_addr; - - dma_addr = sbus_readl(&rxd->myri_scatters[0].addr); - dma_unmap_single(&mp->myri_op->dev, dma_addr, - RX_ALLOC_SIZE, DMA_FROM_DEVICE); - dev_kfree_skb(mp->rx_skbs[i]); - mp->rx_skbs[i] = NULL; - } - } - - mp->tx_old = 0; - sbus_writel(0, &sq->tail); - sbus_writel(0, &sq->head); - for (i = 0; i < TX_RING_SIZE; i++) { - if (mp->tx_skbs[i] != NULL) { - struct sk_buff *skb = mp->tx_skbs[i]; - struct myri_txd __iomem *txd = &sq->myri_txd[i]; - u32 dma_addr; - - dma_addr = sbus_readl(&txd->myri_gathers[0].addr); - dma_unmap_single(&mp->myri_op->dev, dma_addr, - (skb->len + 3) & ~3, - DMA_TO_DEVICE); - dev_kfree_skb(mp->tx_skbs[i]); - mp->tx_skbs[i] = NULL; - } - } -} - -static void myri_init_rings(struct myri_eth *mp, int from_irq) -{ - struct recvq __iomem *rq = mp->rq; - struct myri_rxd __iomem *rxd = &rq->myri_rxd[0]; - struct net_device *dev = mp->dev; - gfp_t gfp_flags = GFP_KERNEL; - int i; - - if (from_irq || in_interrupt()) - gfp_flags = GFP_ATOMIC; - - myri_clean_rings(mp); - for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = myri_alloc_skb(RX_ALLOC_SIZE, gfp_flags); - u32 dma_addr; - - if (!skb) - continue; - mp->rx_skbs[i] = skb; - skb->dev = dev; - skb_put(skb, RX_ALLOC_SIZE); - - dma_addr = dma_map_single(&mp->myri_op->dev, - skb->data, RX_ALLOC_SIZE, - DMA_FROM_DEVICE); - sbus_writel(dma_addr, &rxd[i].myri_scatters[0].addr); - sbus_writel(RX_ALLOC_SIZE, &rxd[i].myri_scatters[0].len); - sbus_writel(i, &rxd[i].ctx); - sbus_writel(1, &rxd[i].num_sg); - } - sbus_writel(0, &rq->head); - sbus_writel(RX_RING_SIZE, &rq->tail); -} - -static int myri_init(struct myri_eth *mp, int from_irq) -{ - myri_init_rings(mp, from_irq); - return 0; -} - -static void myri_is_not_so_happy(struct myri_eth *mp) -{ -} - -#ifdef DEBUG_HEADER -static void dump_ehdr(struct ethhdr *ehdr) -{ - printk("ehdr[h_dst(%pM)" - "h_source(%pM)" - "h_proto(%04x)]\n", - ehdr->h_dest, ehdr->h_source, ehdr->h_proto); -} - -static void dump_ehdr_and_myripad(unsigned char *stuff) -{ - struct ethhdr *ehdr = (struct ethhdr *) (stuff + 2); - - printk("pad[%02x:%02x]", stuff[0], stuff[1]); - dump_ehdr(ehdr); -} -#endif - -static void myri_tx(struct myri_eth *mp, struct net_device *dev) -{ - struct sendq __iomem *sq= mp->sq; - int entry = mp->tx_old; - int limit = sbus_readl(&sq->head); - - DTX(("entry[%d] limit[%d] ", entry, limit)); - if (entry == limit) - return; - while (entry != limit) { - struct sk_buff *skb = mp->tx_skbs[entry]; - u32 dma_addr; - - DTX(("SKB[%d] ", entry)); - dma_addr = sbus_readl(&sq->myri_txd[entry].myri_gathers[0].addr); - dma_unmap_single(&mp->myri_op->dev, dma_addr, - skb->len, DMA_TO_DEVICE); - dev_kfree_skb(skb); - mp->tx_skbs[entry] = NULL; - dev->stats.tx_packets++; - entry = NEXT_TX(entry); - } - mp->tx_old = entry; -} - -/* Determine the packet's protocol ID. The rule here is that we - * assume 802.3 if the type field is short enough to be a length. - * This is normal practice and works for any 'now in use' protocol. - */ -static __be16 myri_type_trans(struct sk_buff *skb, struct net_device *dev) -{ - struct ethhdr *eth; - unsigned char *rawp; - - skb_set_mac_header(skb, MYRI_PAD_LEN); - skb_pull(skb, dev->hard_header_len); - eth = eth_hdr(skb); - -#ifdef DEBUG_HEADER - DHDR(("myri_type_trans: ")); - dump_ehdr(eth); -#endif - if (*eth->h_dest & 1) { - if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN)==0) - skb->pkt_type = PACKET_BROADCAST; - else - skb->pkt_type = PACKET_MULTICAST; - } else if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) { - if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) - skb->pkt_type = PACKET_OTHERHOST; - } - - if (ntohs(eth->h_proto) >= 1536) - return eth->h_proto; - - rawp = skb->data; - - /* This is a magic hack to spot IPX packets. Older Novell breaks - * the protocol design and runs IPX over 802.3 without an 802.2 LLC - * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This - * won't work for fault tolerant netware but does for the rest. - */ - if (*(unsigned short *)rawp == 0xFFFF) - return htons(ETH_P_802_3); - - /* Real 802.2 LLC */ - return htons(ETH_P_802_2); -} - -static void myri_rx(struct myri_eth *mp, struct net_device *dev) -{ - struct recvq __iomem *rq = mp->rq; - struct recvq __iomem *rqa = mp->rqack; - int entry = sbus_readl(&rqa->head); - int limit = sbus_readl(&rqa->tail); - int drops; - - DRX(("entry[%d] limit[%d] ", entry, limit)); - if (entry == limit) - return; - drops = 0; - DRX(("\n")); - while (entry != limit) { - struct myri_rxd __iomem *rxdack = &rqa->myri_rxd[entry]; - u32 csum = sbus_readl(&rxdack->csum); - int len = sbus_readl(&rxdack->myri_scatters[0].len); - int index = sbus_readl(&rxdack->ctx); - struct myri_rxd __iomem *rxd = &rq->myri_rxd[sbus_readl(&rq->tail)]; - struct sk_buff *skb = mp->rx_skbs[index]; - - /* Ack it. */ - sbus_writel(NEXT_RX(entry), &rqa->head); - - /* Check for errors. */ - DRX(("rxd[%d]: %p len[%d] csum[%08x] ", entry, rxd, len, csum)); - dma_sync_single_for_cpu(&mp->myri_op->dev, - sbus_readl(&rxd->myri_scatters[0].addr), - RX_ALLOC_SIZE, DMA_FROM_DEVICE); - if (len < (ETH_HLEN + MYRI_PAD_LEN) || (skb->data[0] != MYRI_PAD_LEN)) { - DRX(("ERROR[")); - dev->stats.rx_errors++; - if (len < (ETH_HLEN + MYRI_PAD_LEN)) { - DRX(("BAD_LENGTH] ")); - dev->stats.rx_length_errors++; - } else { - DRX(("NO_PADDING] ")); - dev->stats.rx_frame_errors++; - } - - /* Return it to the LANAI. */ - drop_it: - drops++; - DRX(("DROP ")); - dev->stats.rx_dropped++; - dma_sync_single_for_device(&mp->myri_op->dev, - sbus_readl(&rxd->myri_scatters[0].addr), - RX_ALLOC_SIZE, - DMA_FROM_DEVICE); - sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len); - sbus_writel(index, &rxd->ctx); - sbus_writel(1, &rxd->num_sg); - sbus_writel(NEXT_RX(sbus_readl(&rq->tail)), &rq->tail); - goto next; - } - - DRX(("len[%d] ", len)); - if (len > RX_COPY_THRESHOLD) { - struct sk_buff *new_skb; - u32 dma_addr; - - DRX(("BIGBUFF ")); - new_skb = myri_alloc_skb(RX_ALLOC_SIZE, GFP_ATOMIC); - if (new_skb == NULL) { - DRX(("skb_alloc(FAILED) ")); - goto drop_it; - } - dma_unmap_single(&mp->myri_op->dev, - sbus_readl(&rxd->myri_scatters[0].addr), - RX_ALLOC_SIZE, - DMA_FROM_DEVICE); - mp->rx_skbs[index] = new_skb; - new_skb->dev = dev; - skb_put(new_skb, RX_ALLOC_SIZE); - dma_addr = dma_map_single(&mp->myri_op->dev, - new_skb->data, - RX_ALLOC_SIZE, - DMA_FROM_DEVICE); - sbus_writel(dma_addr, &rxd->myri_scatters[0].addr); - sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len); - sbus_writel(index, &rxd->ctx); - sbus_writel(1, &rxd->num_sg); - sbus_writel(NEXT_RX(sbus_readl(&rq->tail)), &rq->tail); - - /* Trim the original skb for the netif. */ - DRX(("trim(%d) ", len)); - skb_trim(skb, len); - } else { - struct sk_buff *copy_skb = dev_alloc_skb(len); - - DRX(("SMALLBUFF ")); - if (copy_skb == NULL) { - DRX(("dev_alloc_skb(FAILED) ")); - goto drop_it; - } - /* DMA sync already done above. */ - copy_skb->dev = dev; - DRX(("resv_and_put ")); - skb_put(copy_skb, len); - skb_copy_from_linear_data(skb, copy_skb->data, len); - - /* Reuse original ring buffer. */ - DRX(("reuse ")); - dma_sync_single_for_device(&mp->myri_op->dev, - sbus_readl(&rxd->myri_scatters[0].addr), - RX_ALLOC_SIZE, - DMA_FROM_DEVICE); - sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len); - sbus_writel(index, &rxd->ctx); - sbus_writel(1, &rxd->num_sg); - sbus_writel(NEXT_RX(sbus_readl(&rq->tail)), &rq->tail); - - skb = copy_skb; - } - - /* Just like the happy meal we get checksums from this card. */ - skb->csum = csum; - skb->ip_summed = CHECKSUM_UNNECESSARY; /* XXX */ - - skb->protocol = myri_type_trans(skb, dev); - DRX(("prot[%04x] netif_rx ", skb->protocol)); - netif_rx(skb); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += len; - next: - DRX(("NEXT\n")); - entry = NEXT_RX(entry); - } -} - -static irqreturn_t myri_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct myri_eth *mp = netdev_priv(dev); - void __iomem *lregs = mp->lregs; - struct myri_channel __iomem *chan = &mp->shmem->channel; - unsigned long flags; - u32 status; - int handled = 0; - - spin_lock_irqsave(&mp->irq_lock, flags); - - status = sbus_readl(lregs + LANAI_ISTAT); - DIRQ(("myri_interrupt: status[%08x] ", status)); - if (status & ISTAT_HOST) { - u32 softstate; - - handled = 1; - DIRQ(("IRQ_DISAB ")); - myri_disable_irq(lregs, mp->cregs); - softstate = sbus_readl(&chan->state); - DIRQ(("state[%08x] ", softstate)); - if (softstate != STATE_READY) { - DIRQ(("myri_not_so_happy ")); - myri_is_not_so_happy(mp); - } - DIRQ(("\nmyri_rx: ")); - myri_rx(mp, dev); - DIRQ(("\nistat=ISTAT_HOST ")); - sbus_writel(ISTAT_HOST, lregs + LANAI_ISTAT); - DIRQ(("IRQ_ENAB ")); - myri_enable_irq(lregs, mp->cregs); - } - DIRQ(("\n")); - - spin_unlock_irqrestore(&mp->irq_lock, flags); - - return IRQ_RETVAL(handled); -} - -static int myri_open(struct net_device *dev) -{ - struct myri_eth *mp = netdev_priv(dev); - - return myri_init(mp, in_interrupt()); -} - -static int myri_close(struct net_device *dev) -{ - struct myri_eth *mp = netdev_priv(dev); - - myri_clean_rings(mp); - return 0; -} - -static void myri_tx_timeout(struct net_device *dev) -{ - struct myri_eth *mp = netdev_priv(dev); - - printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name); - - dev->stats.tx_errors++; - myri_init(mp, 0); - netif_wake_queue(dev); -} - -static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct myri_eth *mp = netdev_priv(dev); - struct sendq __iomem *sq = mp->sq; - struct myri_txd __iomem *txd; - unsigned long flags; - unsigned int head, tail; - int len, entry; - u32 dma_addr; - - DTX(("myri_start_xmit: ")); - - myri_tx(mp, dev); - - netif_stop_queue(dev); - - /* This is just to prevent multiple PIO reads for TX_BUFFS_AVAIL. */ - head = sbus_readl(&sq->head); - tail = sbus_readl(&sq->tail); - - if (!TX_BUFFS_AVAIL(head, tail)) { - DTX(("no buffs available, returning 1\n")); - return NETDEV_TX_BUSY; - } - - spin_lock_irqsave(&mp->irq_lock, flags); - - DHDR(("xmit[skbdata(%p)]\n", skb->data)); -#ifdef DEBUG_HEADER - dump_ehdr_and_myripad(((unsigned char *) skb->data)); -#endif - - /* XXX Maybe this can go as well. */ - len = skb->len; - if (len & 3) { - DTX(("len&3 ")); - len = (len + 4) & (~3); - } - - entry = sbus_readl(&sq->tail); - - txd = &sq->myri_txd[entry]; - mp->tx_skbs[entry] = skb; - - /* Must do this before we sbus map it. */ - if (skb->data[MYRI_PAD_LEN] & 0x1) { - sbus_writew(0xffff, &txd->addr[0]); - sbus_writew(0xffff, &txd->addr[1]); - sbus_writew(0xffff, &txd->addr[2]); - sbus_writew(0xffff, &txd->addr[3]); - } else { - sbus_writew(0xffff, &txd->addr[0]); - sbus_writew((skb->data[0] << 8) | skb->data[1], &txd->addr[1]); - sbus_writew((skb->data[2] << 8) | skb->data[3], &txd->addr[2]); - sbus_writew((skb->data[4] << 8) | skb->data[5], &txd->addr[3]); - } - - dma_addr = dma_map_single(&mp->myri_op->dev, skb->data, - len, DMA_TO_DEVICE); - sbus_writel(dma_addr, &txd->myri_gathers[0].addr); - sbus_writel(len, &txd->myri_gathers[0].len); - sbus_writel(1, &txd->num_sg); - sbus_writel(KERNEL_CHANNEL, &txd->chan); - sbus_writel(len, &txd->len); - sbus_writel((u32)-1, &txd->csum_off); - sbus_writel(0, &txd->csum_field); - - sbus_writel(NEXT_TX(entry), &sq->tail); - DTX(("BangTheChip ")); - bang_the_chip(mp); - - DTX(("tbusy=0, returning 0\n")); - netif_start_queue(dev); - spin_unlock_irqrestore(&mp->irq_lock, flags); - return NETDEV_TX_OK; -} - -/* Create the MyriNet MAC header for an arbitrary protocol layer - * - * saddr=NULL means use device source address - * daddr=NULL means leave destination address (eg unresolved arp) - */ -static int myri_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, const void *daddr, - const void *saddr, unsigned len) -{ - struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); - unsigned char *pad = (unsigned char *) skb_push(skb, MYRI_PAD_LEN); - -#ifdef DEBUG_HEADER - DHDR(("myri_header: pad[%02x,%02x] ", pad[0], pad[1])); - dump_ehdr(eth); -#endif - - /* Set the MyriNET padding identifier. */ - pad[0] = MYRI_PAD_LEN; - pad[1] = 0xab; - - /* Set the protocol type. For a packet of type ETH_P_802_3/2 we put the - * length in here instead. - */ - if (type != ETH_P_802_3 && type != ETH_P_802_2) - eth->h_proto = htons(type); - else - eth->h_proto = htons(len); - - /* Set the source hardware address. */ - if (saddr) - memcpy(eth->h_source, saddr, dev->addr_len); - else - memcpy(eth->h_source, dev->dev_addr, dev->addr_len); - - /* Anyway, the loopback-device should never use this function... */ - if (dev->flags & IFF_LOOPBACK) { - int i; - for (i = 0; i < dev->addr_len; i++) - eth->h_dest[i] = 0; - return dev->hard_header_len; - } - - if (daddr) { - memcpy(eth->h_dest, daddr, dev->addr_len); - return dev->hard_header_len; - } - return -dev->hard_header_len; -} - -/* Rebuild the MyriNet MAC header. This is called after an ARP - * (or in future other address resolution) has completed on this - * sk_buff. We now let ARP fill in the other fields. - */ -static int myri_rebuild_header(struct sk_buff *skb) -{ - unsigned char *pad = (unsigned char *) skb->data; - struct ethhdr *eth = (struct ethhdr *) (pad + MYRI_PAD_LEN); - struct net_device *dev = skb->dev; - -#ifdef DEBUG_HEADER - DHDR(("myri_rebuild_header: pad[%02x,%02x] ", pad[0], pad[1])); - dump_ehdr(eth); -#endif - - /* Refill MyriNet padding identifiers, this is just being anal. */ - pad[0] = MYRI_PAD_LEN; - pad[1] = 0xab; - - switch (eth->h_proto) - { -#ifdef CONFIG_INET - case cpu_to_be16(ETH_P_IP): - return arp_find(eth->h_dest, skb); -#endif - - default: - printk(KERN_DEBUG - "%s: unable to resolve type %X addresses.\n", - dev->name, (int)eth->h_proto); - - memcpy(eth->h_source, dev->dev_addr, dev->addr_len); - return 0; - break; - } - - return 0; -} - -static int myri_header_cache(const struct neighbour *neigh, struct hh_cache *hh) -{ - unsigned short type = hh->hh_type; - unsigned char *pad; - struct ethhdr *eth; - const struct net_device *dev = neigh->dev; - - pad = ((unsigned char *) hh->hh_data) + - HH_DATA_OFF(sizeof(*eth) + MYRI_PAD_LEN); - eth = (struct ethhdr *) (pad + MYRI_PAD_LEN); - - if (type == htons(ETH_P_802_3)) - return -1; - - /* Refill MyriNet padding identifiers, this is just being anal. */ - pad[0] = MYRI_PAD_LEN; - pad[1] = 0xab; - - eth->h_proto = type; - memcpy(eth->h_source, dev->dev_addr, dev->addr_len); - memcpy(eth->h_dest, neigh->ha, dev->addr_len); - hh->hh_len = 16; - return 0; -} - - -/* Called by Address Resolution module to notify changes in address. */ -void myri_header_cache_update(struct hh_cache *hh, - const struct net_device *dev, - const unsigned char * haddr) -{ - memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)), - haddr, dev->addr_len); -} - -static int myri_change_mtu(struct net_device *dev, int new_mtu) -{ - if ((new_mtu < (ETH_HLEN + MYRI_PAD_LEN)) || (new_mtu > MYRINET_MTU)) - return -EINVAL; - dev->mtu = new_mtu; - return 0; -} - -static void myri_set_multicast(struct net_device *dev) -{ - /* Do nothing, all MyriCOM nodes transmit multicast frames - * as broadcast packets... - */ -} - -static inline void set_boardid_from_idprom(struct myri_eth *mp, int num) -{ - mp->eeprom.id[0] = 0; - mp->eeprom.id[1] = idprom->id_machtype; - mp->eeprom.id[2] = (idprom->id_sernum >> 16) & 0xff; - mp->eeprom.id[3] = (idprom->id_sernum >> 8) & 0xff; - mp->eeprom.id[4] = (idprom->id_sernum >> 0) & 0xff; - mp->eeprom.id[5] = num; -} - -static inline void determine_reg_space_size(struct myri_eth *mp) -{ - switch(mp->eeprom.cpuvers) { - case CPUVERS_2_3: - case CPUVERS_3_0: - case CPUVERS_3_1: - case CPUVERS_3_2: - mp->reg_size = (3 * 128 * 1024) + 4096; - break; - - case CPUVERS_4_0: - case CPUVERS_4_1: - mp->reg_size = ((4096<<1) + mp->eeprom.ramsz); - break; - - case CPUVERS_4_2: - case CPUVERS_5_0: - default: - printk("myricom: AIEEE weird cpu version %04x assuming pre4.0\n", - mp->eeprom.cpuvers); - mp->reg_size = (3 * 128 * 1024) + 4096; - } -} - -#ifdef DEBUG_DETECT -static void dump_eeprom(struct myri_eth *mp) -{ - printk("EEPROM: clockval[%08x] cpuvers[%04x] " - "id[%02x,%02x,%02x,%02x,%02x,%02x]\n", - mp->eeprom.cval, mp->eeprom.cpuvers, - mp->eeprom.id[0], mp->eeprom.id[1], mp->eeprom.id[2], - mp->eeprom.id[3], mp->eeprom.id[4], mp->eeprom.id[5]); - printk("EEPROM: ramsz[%08x]\n", mp->eeprom.ramsz); - printk("EEPROM: fvers[%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", - mp->eeprom.fvers[0], mp->eeprom.fvers[1], mp->eeprom.fvers[2], - mp->eeprom.fvers[3], mp->eeprom.fvers[4], mp->eeprom.fvers[5], - mp->eeprom.fvers[6], mp->eeprom.fvers[7]); - printk("EEPROM: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", - mp->eeprom.fvers[8], mp->eeprom.fvers[9], mp->eeprom.fvers[10], - mp->eeprom.fvers[11], mp->eeprom.fvers[12], mp->eeprom.fvers[13], - mp->eeprom.fvers[14], mp->eeprom.fvers[15]); - printk("EEPROM: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", - mp->eeprom.fvers[16], mp->eeprom.fvers[17], mp->eeprom.fvers[18], - mp->eeprom.fvers[19], mp->eeprom.fvers[20], mp->eeprom.fvers[21], - mp->eeprom.fvers[22], mp->eeprom.fvers[23]); - printk("EEPROM: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x]\n", - mp->eeprom.fvers[24], mp->eeprom.fvers[25], mp->eeprom.fvers[26], - mp->eeprom.fvers[27], mp->eeprom.fvers[28], mp->eeprom.fvers[29], - mp->eeprom.fvers[30], mp->eeprom.fvers[31]); - printk("EEPROM: mvers[%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", - mp->eeprom.mvers[0], mp->eeprom.mvers[1], mp->eeprom.mvers[2], - mp->eeprom.mvers[3], mp->eeprom.mvers[4], mp->eeprom.mvers[5], - mp->eeprom.mvers[6], mp->eeprom.mvers[7]); - printk("EEPROM: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x]\n", - mp->eeprom.mvers[8], mp->eeprom.mvers[9], mp->eeprom.mvers[10], - mp->eeprom.mvers[11], mp->eeprom.mvers[12], mp->eeprom.mvers[13], - mp->eeprom.mvers[14], mp->eeprom.mvers[15]); - printk("EEPROM: dlval[%04x] brd_type[%04x] bus_type[%04x] prod_code[%04x]\n", - mp->eeprom.dlval, mp->eeprom.brd_type, mp->eeprom.bus_type, - mp->eeprom.prod_code); - printk("EEPROM: serial_num[%08x]\n", mp->eeprom.serial_num); -} -#endif - -static const struct header_ops myri_header_ops = { - .create = myri_header, - .rebuild = myri_rebuild_header, - .cache = myri_header_cache, - .cache_update = myri_header_cache_update, -}; - -static const struct net_device_ops myri_ops = { - .ndo_open = myri_open, - .ndo_stop = myri_close, - .ndo_start_xmit = myri_start_xmit, - .ndo_set_multicast_list = myri_set_multicast, - .ndo_tx_timeout = myri_tx_timeout, - .ndo_change_mtu = myri_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -static int __devinit myri_sbus_probe(struct platform_device *op) -{ - struct device_node *dp = op->dev.of_node; - static unsigned version_printed; - struct net_device *dev; - struct myri_eth *mp; - const void *prop; - static int num; - int i, len; - - DET(("myri_ether_init(%p,%d):\n", op, num)); - dev = alloc_etherdev(sizeof(struct myri_eth)); - if (!dev) - return -ENOMEM; - - if (version_printed++ == 0) - printk(version); - - SET_NETDEV_DEV(dev, &op->dev); - - mp = netdev_priv(dev); - spin_lock_init(&mp->irq_lock); - mp->myri_op = op; - - /* Clean out skb arrays. */ - for (i = 0; i < (RX_RING_SIZE + 1); i++) - mp->rx_skbs[i] = NULL; - - for (i = 0; i < TX_RING_SIZE; i++) - mp->tx_skbs[i] = NULL; - - /* First check for EEPROM information. */ - prop = of_get_property(dp, "myrinet-eeprom-info", &len); - - if (prop) - memcpy(&mp->eeprom, prop, sizeof(struct myri_eeprom)); - if (!prop) { - /* No eeprom property, must cook up the values ourselves. */ - DET(("No EEPROM: ")); - mp->eeprom.bus_type = BUS_TYPE_SBUS; - mp->eeprom.cpuvers = - of_getintprop_default(dp, "cpu_version", 0); - mp->eeprom.cval = - of_getintprop_default(dp, "clock_value", 0); - mp->eeprom.ramsz = of_getintprop_default(dp, "sram_size", 0); - if (!mp->eeprom.cpuvers) - mp->eeprom.cpuvers = CPUVERS_2_3; - if (mp->eeprom.cpuvers < CPUVERS_3_0) - mp->eeprom.cval = 0; - if (!mp->eeprom.ramsz) - mp->eeprom.ramsz = (128 * 1024); - - prop = of_get_property(dp, "myrinet-board-id", &len); - if (prop) - memcpy(&mp->eeprom.id[0], prop, 6); - else - set_boardid_from_idprom(mp, num); - - prop = of_get_property(dp, "fpga_version", &len); - if (prop) - memcpy(&mp->eeprom.fvers[0], prop, 32); - else - memset(&mp->eeprom.fvers[0], 0, 32); - - if (mp->eeprom.cpuvers == CPUVERS_4_1) { - if (mp->eeprom.ramsz == (128 * 1024)) - mp->eeprom.ramsz = (256 * 1024); - if ((mp->eeprom.cval == 0x40414041) || - (mp->eeprom.cval == 0x90449044)) - mp->eeprom.cval = 0x50e450e4; - } - } -#ifdef DEBUG_DETECT - dump_eeprom(mp); -#endif - - for (i = 0; i < 6; i++) - dev->dev_addr[i] = mp->eeprom.id[i]; - - determine_reg_space_size(mp); - - /* Map in the MyriCOM register/localram set. */ - if (mp->eeprom.cpuvers < CPUVERS_4_0) { - /* XXX Makes no sense, if control reg is non-existent this - * XXX driver cannot function at all... maybe pre-4.0 is - * XXX only a valid version for PCI cards? Ask feldy... - */ - DET(("Mapping regs for cpuvers < CPUVERS_4_0\n")); - mp->regs = of_ioremap(&op->resource[0], 0, - mp->reg_size, "MyriCOM Regs"); - if (!mp->regs) { - printk("MyriCOM: Cannot map MyriCOM registers.\n"); - goto err; - } - mp->lanai = mp->regs + (256 * 1024); - mp->lregs = mp->lanai + (0x10000 * 2); - } else { - DET(("Mapping regs for cpuvers >= CPUVERS_4_0\n")); - mp->cregs = of_ioremap(&op->resource[0], 0, - PAGE_SIZE, "MyriCOM Control Regs"); - mp->lregs = of_ioremap(&op->resource[0], (256 * 1024), - PAGE_SIZE, "MyriCOM LANAI Regs"); - mp->lanai = of_ioremap(&op->resource[0], (512 * 1024), - mp->eeprom.ramsz, "MyriCOM SRAM"); - } - DET(("Registers mapped: cregs[%p] lregs[%p] lanai[%p]\n", - mp->cregs, mp->lregs, mp->lanai)); - - if (mp->eeprom.cpuvers >= CPUVERS_4_0) - mp->shmem_base = 0xf000; - else - mp->shmem_base = 0x8000; - - DET(("Shared memory base is %04x, ", mp->shmem_base)); - - mp->shmem = (struct myri_shmem __iomem *) - (mp->lanai + (mp->shmem_base * 2)); - DET(("shmem mapped at %p\n", mp->shmem)); - - mp->rqack = &mp->shmem->channel.recvqa; - mp->rq = &mp->shmem->channel.recvq; - mp->sq = &mp->shmem->channel.sendq; - - /* Reset the board. */ - DET(("Resetting LANAI\n")); - myri_reset_off(mp->lregs, mp->cregs); - myri_reset_on(mp->cregs); - - /* Turn IRQ's off. */ - myri_disable_irq(mp->lregs, mp->cregs); - - /* Reset once more. */ - myri_reset_on(mp->cregs); - - /* Get the supported DVMA burst sizes from our SBUS. */ - mp->myri_bursts = of_getintprop_default(dp->parent, - "burst-sizes", 0x00); - if (!sbus_can_burst64()) - mp->myri_bursts &= ~(DMA_BURST64); - - DET(("MYRI bursts %02x\n", mp->myri_bursts)); - - /* Encode SBUS interrupt level in second control register. */ - i = of_getintprop_default(dp, "interrupts", 0); - if (i == 0) - i = 4; - DET(("prom_getint(interrupts)==%d, irqlvl set to %04x\n", - i, (1 << i))); - - sbus_writel((1 << i), mp->cregs + MYRICTRL_IRQLVL); - - mp->dev = dev; - dev->watchdog_timeo = 5*HZ; - dev->irq = op->archdata.irqs[0]; - dev->netdev_ops = &myri_ops; - - /* Register interrupt handler now. */ - DET(("Requesting MYRIcom IRQ line.\n")); - if (request_irq(dev->irq, myri_interrupt, - IRQF_SHARED, "MyriCOM Ethernet", (void *) dev)) { - printk("MyriCOM: Cannot register interrupt handler.\n"); - goto err; - } - - dev->mtu = MYRINET_MTU; - dev->header_ops = &myri_header_ops; - - dev->hard_header_len = (ETH_HLEN + MYRI_PAD_LEN); - - /* Load code onto the LANai. */ - DET(("Loading LANAI firmware\n")); - if (myri_load_lanai(mp)) { - printk(KERN_ERR "MyriCOM: Cannot Load LANAI firmware.\n"); - goto err_free_irq; - } - - if (register_netdev(dev)) { - printk("MyriCOM: Cannot register device.\n"); - goto err_free_irq; - } - - dev_set_drvdata(&op->dev, mp); - - num++; - - printk("%s: MyriCOM MyriNET Ethernet %pM\n", - dev->name, dev->dev_addr); - - return 0; - -err_free_irq: - free_irq(dev->irq, dev); -err: - /* This will also free the co-allocated private data*/ - free_netdev(dev); - return -ENODEV; -} - -static int __devexit myri_sbus_remove(struct platform_device *op) -{ - struct myri_eth *mp = dev_get_drvdata(&op->dev); - struct net_device *net_dev = mp->dev; - - unregister_netdev(net_dev); - - free_irq(net_dev->irq, net_dev); - - if (mp->eeprom.cpuvers < CPUVERS_4_0) { - of_iounmap(&op->resource[0], mp->regs, mp->reg_size); - } else { - of_iounmap(&op->resource[0], mp->cregs, PAGE_SIZE); - of_iounmap(&op->resource[0], mp->lregs, (256 * 1024)); - of_iounmap(&op->resource[0], mp->lanai, (512 * 1024)); - } - - free_netdev(net_dev); - - dev_set_drvdata(&op->dev, NULL); - - return 0; -} - -static const struct of_device_id myri_sbus_match[] = { - { - .name = "MYRICOM,mlanai", - }, - { - .name = "myri", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, myri_sbus_match); - -static struct platform_driver myri_sbus_driver = { - .driver = { - .name = "myri", - .owner = THIS_MODULE, - .of_match_table = myri_sbus_match, - }, - .probe = myri_sbus_probe, - .remove = __devexit_p(myri_sbus_remove), -}; - -static int __init myri_sbus_init(void) -{ - return platform_driver_register(&myri_sbus_driver); -} - -static void __exit myri_sbus_exit(void) -{ - platform_driver_unregister(&myri_sbus_driver); -} - -module_init(myri_sbus_init); -module_exit(myri_sbus_exit); - -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(FWNAME); diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h deleted file mode 100644 index 80a2fa5cf75..00000000000 --- a/drivers/net/myri_sbus.h +++ /dev/null @@ -1,311 +0,0 @@ -/* myri_sbus.h: Defines for MyriCOM MyriNET SBUS card driver. - * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef _MYRI_SBUS_H -#define _MYRI_SBUS_H - -/* LANAI Registers */ -#define LANAI_IPF0 0x00UL /* Context zero state registers.*/ -#define LANAI_CUR0 0x04UL -#define LANAI_PREV0 0x08UL -#define LANAI_DATA0 0x0cUL -#define LANAI_DPF0 0x10UL -#define LANAI_IPF1 0x14UL /* Context one state registers. */ -#define LANAI_CUR1 0x18UL -#define LANAI_PREV1 0x1cUL -#define LANAI_DATA1 0x20UL -#define LANAI_DPF1 0x24UL -#define LANAI_ISTAT 0x28UL /* Interrupt status. */ -#define LANAI_EIMASK 0x2cUL /* External IRQ mask. */ -#define LANAI_ITIMER 0x30UL /* IRQ timer. */ -#define LANAI_RTC 0x34UL /* Real Time Clock */ -#define LANAI_CSUM 0x38UL /* Checksum. */ -#define LANAI_DMAXADDR 0x3cUL /* SBUS DMA external address. */ -#define LANAI_DMALADDR 0x40UL /* SBUS DMA local address. */ -#define LANAI_DMACTR 0x44UL /* SBUS DMA counter. */ -#define LANAI_RXDMAPTR 0x48UL /* Receive DMA pointer. */ -#define LANAI_RXDMALIM 0x4cUL /* Receive DMA limit. */ -#define LANAI_TXDMAPTR 0x50UL /* Transmit DMA pointer. */ -#define LANAI_TXDMALIM 0x54UL /* Transmit DMA limit. */ -#define LANAI_TXDMALIMT 0x58UL /* Transmit DMA limit w/tail. */ - /* 0x5cUL, reserved */ -#define LANAI_RBYTE 0x60UL /* Receive byte. */ - /* 0x64-->0x6c, reserved */ -#define LANAI_RHALF 0x70UL /* Receive half-word. */ - /* 0x72UL, reserved */ -#define LANAI_RWORD 0x74UL /* Receive word. */ -#define LANAI_SALIGN 0x78UL /* Send align. */ -#define LANAI_SBYTE 0x7cUL /* SingleSend send-byte. */ -#define LANAI_SHALF 0x80UL /* SingleSend send-halfword. */ -#define LANAI_SWORD 0x84UL /* SingleSend send-word. */ -#define LANAI_SSENDT 0x88UL /* SingleSend special. */ -#define LANAI_DMADIR 0x8cUL /* DMA direction. */ -#define LANAI_DMASTAT 0x90UL /* DMA status. */ -#define LANAI_TIMEO 0x94UL /* Timeout register. */ -#define LANAI_MYRINET 0x98UL /* XXX MAGIC myricom thing */ -#define LANAI_HWDEBUG 0x9cUL /* Hardware debugging reg. */ -#define LANAI_LEDS 0xa0UL /* LED control. */ -#define LANAI_VERS 0xa4UL /* Version register. */ -#define LANAI_LINKON 0xa8UL /* Link activation reg. */ - /* 0xac-->0x104, reserved */ -#define LANAI_CVAL 0x108UL /* Clock value register. */ -#define LANAI_REG_SIZE 0x10cUL - -/* Interrupt status bits. */ -#define ISTAT_DEBUG 0x80000000 -#define ISTAT_HOST 0x40000000 -#define ISTAT_LAN7 0x00800000 -#define ISTAT_LAN6 0x00400000 -#define ISTAT_LAN5 0x00200000 -#define ISTAT_LAN4 0x00100000 -#define ISTAT_LAN3 0x00080000 -#define ISTAT_LAN2 0x00040000 -#define ISTAT_LAN1 0x00020000 -#define ISTAT_LAN0 0x00010000 -#define ISTAT_WRDY 0x00008000 -#define ISTAT_HRDY 0x00004000 -#define ISTAT_SRDY 0x00002000 -#define ISTAT_LINK 0x00001000 -#define ISTAT_FRES 0x00000800 -#define ISTAT_NRES 0x00000800 -#define ISTAT_WAKE 0x00000400 -#define ISTAT_OB2 0x00000200 -#define ISTAT_OB1 0x00000100 -#define ISTAT_TAIL 0x00000080 -#define ISTAT_WDOG 0x00000040 -#define ISTAT_TIME 0x00000020 -#define ISTAT_DMA 0x00000010 -#define ISTAT_SEND 0x00000008 -#define ISTAT_BUF 0x00000004 -#define ISTAT_RECV 0x00000002 -#define ISTAT_BRDY 0x00000001 - -/* MYRI Registers */ -#define MYRI_RESETOFF 0x00UL -#define MYRI_RESETON 0x04UL -#define MYRI_IRQOFF 0x08UL -#define MYRI_IRQON 0x0cUL -#define MYRI_WAKEUPOFF 0x10UL -#define MYRI_WAKEUPON 0x14UL -#define MYRI_IRQREAD 0x18UL - /* 0x1c-->0x3ffc, reserved */ -#define MYRI_LOCALMEM 0x4000UL -#define MYRI_REG_SIZE 0x25000UL - -/* Shared memory interrupt mask. */ -#define SHMEM_IMASK_RX 0x00000002 -#define SHMEM_IMASK_TX 0x00000001 - -/* Just to make things readable. */ -#define KERNEL_CHANNEL 0 - -/* The size of this must be >= 129 bytes. */ -struct myri_eeprom { - unsigned int cval; - unsigned short cpuvers; - unsigned char id[6]; - unsigned int ramsz; - unsigned char fvers[32]; - unsigned char mvers[16]; - unsigned short dlval; - unsigned short brd_type; - unsigned short bus_type; - unsigned short prod_code; - unsigned int serial_num; - unsigned short _reserved[24]; - unsigned int _unused[2]; -}; - -/* EEPROM bus types, only SBUS is valid in this driver. */ -#define BUS_TYPE_SBUS 1 - -/* EEPROM CPU revisions. */ -#define CPUVERS_2_3 0x0203 -#define CPUVERS_3_0 0x0300 -#define CPUVERS_3_1 0x0301 -#define CPUVERS_3_2 0x0302 -#define CPUVERS_4_0 0x0400 -#define CPUVERS_4_1 0x0401 -#define CPUVERS_4_2 0x0402 -#define CPUVERS_5_0 0x0500 - -/* MYRI Control Registers */ -#define MYRICTRL_CTRL 0x00UL -#define MYRICTRL_IRQLVL 0x02UL -#define MYRICTRL_REG_SIZE 0x04UL - -/* Global control register defines. */ -#define CONTROL_ROFF 0x8000 /* Reset OFF. */ -#define CONTROL_RON 0x4000 /* Reset ON. */ -#define CONTROL_EIRQ 0x2000 /* Enable IRQ's. */ -#define CONTROL_DIRQ 0x1000 /* Disable IRQ's. */ -#define CONTROL_WON 0x0800 /* Wake-up ON. */ - -#define MYRI_SCATTER_ENTRIES 8 -#define MYRI_GATHER_ENTRIES 16 - -struct myri_sglist { - u32 addr; - u32 len; -}; - -struct myri_rxd { - struct myri_sglist myri_scatters[MYRI_SCATTER_ENTRIES]; /* DMA scatter list.*/ - u32 csum; /* HW computed checksum. */ - u32 ctx; - u32 num_sg; /* Total scatter entries. */ -}; - -struct myri_txd { - struct myri_sglist myri_gathers[MYRI_GATHER_ENTRIES]; /* DMA scatter list. */ - u32 num_sg; /* Total scatter entries. */ - u16 addr[4]; /* XXX address */ - u32 chan; - u32 len; /* Total length of packet. */ - u32 csum_off; /* Where data to csum is. */ - u32 csum_field; /* Where csum goes in pkt. */ -}; - -#define MYRINET_MTU 8432 -#define RX_ALLOC_SIZE 8448 -#define MYRI_PAD_LEN 2 -#define RX_COPY_THRESHOLD 256 - -/* These numbers are cast in stone, new firmware is needed if - * you want to change them. - */ -#define TX_RING_MAXSIZE 16 -#define RX_RING_MAXSIZE 16 - -#define TX_RING_SIZE 16 -#define RX_RING_SIZE 16 - -/* GRRR... */ -static __inline__ int NEXT_RX(int num) -{ - /* XXX >=??? */ - if(++num > RX_RING_SIZE) - num = 0; - return num; -} - -static __inline__ int PREV_RX(int num) -{ - if(--num < 0) - num = RX_RING_SIZE; - return num; -} - -#define NEXT_TX(num) (((num) + 1) & (TX_RING_SIZE - 1)) -#define PREV_TX(num) (((num) - 1) & (TX_RING_SIZE - 1)) - -#define TX_BUFFS_AVAIL(head, tail) \ - ((head) <= (tail) ? \ - (head) + (TX_RING_SIZE - 1) - (tail) : \ - (head) - (tail) - 1) - -struct sendq { - u32 tail; - u32 head; - u32 hdebug; - u32 mdebug; - struct myri_txd myri_txd[TX_RING_MAXSIZE]; -}; - -struct recvq { - u32 head; - u32 tail; - u32 hdebug; - u32 mdebug; - struct myri_rxd myri_rxd[RX_RING_MAXSIZE + 1]; -}; - -#define MYRI_MLIST_SIZE 8 - -struct mclist { - u32 maxlen; - u32 len; - u32 cache; - struct pair { - u8 addr[8]; - u32 val; - } mc_pairs[MYRI_MLIST_SIZE]; - u8 bcast_addr[8]; -}; - -struct myri_channel { - u32 state; /* State of the channel. */ - u32 busy; /* Channel is busy. */ - struct sendq sendq; /* Device tx queue. */ - struct recvq recvq; /* Device rx queue. */ - struct recvq recvqa; /* Device rx queue acked. */ - u32 rbytes; /* Receive bytes. */ - u32 sbytes; /* Send bytes. */ - u32 rmsgs; /* Receive messages. */ - u32 smsgs; /* Send messages. */ - struct mclist mclist; /* Device multicast list. */ -}; - -/* Values for per-channel state. */ -#define STATE_WFH 0 /* Waiting for HOST. */ -#define STATE_WFN 1 /* Waiting for NET. */ -#define STATE_READY 2 /* Ready. */ - -struct myri_shmem { - u8 addr[8]; /* Board's address. */ - u32 nchan; /* Number of channels. */ - u32 burst; /* SBUS dma burst enable. */ - u32 shakedown; /* DarkkkkStarrr Crashesss... */ - u32 send; /* Send wanted. */ - u32 imask; /* Interrupt enable mask. */ - u32 mlevel; /* Map level. */ - u32 debug[4]; /* Misc. debug areas. */ - struct myri_channel channel; /* Only one channel on a host. */ -}; - -struct myri_eth { - /* These are frequently accessed, keep together - * to obtain good cache hit rates. - */ - spinlock_t irq_lock; - struct myri_shmem __iomem *shmem; /* Shared data structures. */ - void __iomem *cregs; /* Control register space. */ - struct recvq __iomem *rqack; /* Where we ack rx's. */ - struct recvq __iomem *rq; /* Where we put buffers. */ - struct sendq __iomem *sq; /* Where we stuff tx's. */ - struct net_device *dev; /* Linux/NET dev struct. */ - int tx_old; /* To speed up tx cleaning. */ - void __iomem *lregs; /* Quick ptr to LANAI regs. */ - struct sk_buff *rx_skbs[RX_RING_SIZE+1];/* RX skb's */ - struct sk_buff *tx_skbs[TX_RING_SIZE]; /* TX skb's */ - - /* These are less frequently accessed. */ - void __iomem *regs; /* MyriCOM register space. */ - void __iomem *lanai; /* View 2 of register space. */ - unsigned int myri_bursts; /* SBUS bursts. */ - struct myri_eeprom eeprom; /* Local copy of EEPROM. */ - unsigned int reg_size; /* Size of register space. */ - unsigned int shmem_base; /* Offset to shared ram. */ - struct platform_device *myri_op; /* Our OF device struct. */ -}; - -/* We use this to acquire receive skb's that we can DMA directly into. */ -#define ALIGNED_RX_SKB_ADDR(addr) \ - ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr)) -static inline struct sk_buff *myri_alloc_skb(unsigned int length, gfp_t gfp_flags) -{ - struct sk_buff *skb; - - skb = alloc_skb(length + 64, gfp_flags); - if(skb) { - int offset = ALIGNED_RX_SKB_ADDR(skb->data); - - if(offset) - skb_reserve(skb, offset); - } - return skb; -} - -#endif /* !(_MYRI_SBUS_H) */ -- cgit v1.2.3-70-g09d2 From 306ff6eb8e9c18bcafb8ca5be4be3c78dfe45475 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 19 Jun 2011 20:07:46 +0000 Subject: myricom: remove stats_lock stats_lock is non useless, lets remove it. Also, ndo_get_stats64() doesnt have to clear the stats, caller takes care of this. Note: folding 32bit fields in 64bit one is problematic when one of 32bit values wraps : SNMP reader will see a ~2^32 back change in a 64bit value. A future patch should fix this. Signed-off-by: Eric Dumazet CC: Stephen Hemminger CC: Andrew Gallatin CC: Brice Goglin Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 04e10f4d679..3e89a842fc5 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -210,7 +210,6 @@ struct myri10ge_priv { int big_bytes; int max_intr_slots; struct net_device *dev; - spinlock_t stats_lock; u8 __iomem *sram; int sram_size; unsigned long board_span; @@ -1837,6 +1836,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, int i; /* force stats update */ + memset(&link_stats, 0, sizeof(link_stats)); (void)myri10ge_get_stats(netdev, &link_stats); for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) data[i] = ((u64 *)&link_stats)[i]; @@ -2981,12 +2981,10 @@ drop: static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) { - struct myri10ge_priv *mgp = netdev_priv(dev); - struct myri10ge_slice_netstats *slice_stats; + const struct myri10ge_priv *mgp = netdev_priv(dev); + const struct myri10ge_slice_netstats *slice_stats; int i; - spin_lock(&mgp->stats_lock); - memset(stats, 0, sizeof(*stats)); for (i = 0; i < mgp->num_slices; i++) { slice_stats = &mgp->ss[i].stats; stats->rx_packets += slice_stats->rx_packets; @@ -2996,7 +2994,6 @@ static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, stats->rx_dropped += slice_stats->rx_dropped; stats->tx_dropped += slice_stats->tx_dropped; } - spin_unlock(&mgp->stats_lock); return stats; } @@ -3966,7 +3963,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, (unsigned long)mgp); - spin_lock_init(&mgp->stats_lock); SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops); INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog); status = register_netdev(netdev); -- cgit v1.2.3-70-g09d2 From d76b7e2faaabae4805ae7ebf31ad64a33268f44f Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:24 +0000 Subject: lib8390: enable transmit and receive time stamping. This patch enables software (and phy device) time stamping. This file is included by drivers/net/ax88796.c, which is based on phylib. So, this patch makes hardware time stamping in the PHY possible. Compile tested only. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/lib8390.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index 17b75e5f1b0..70eb2077bd2 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -410,7 +410,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, spin_unlock(&ei_local->page_lock); enable_irq_lockdep_irqrestore(dev->irq, &flags); - + skb_tx_timestamp(skb); dev_kfree_skb (skb); dev->stats.tx_bytes += send_length; @@ -758,7 +758,8 @@ static void ei_receive(struct net_device *dev) skb_put(skb, pkt_len); /* Make room */ ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); + if (!skb_defer_rx_timestamp(skb)) + netif_rx(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += pkt_len; if (pkt_stat & ENRSR_PHY) -- cgit v1.2.3-70-g09d2 From 570773c5801cc6c322534d6b1d1551e23664103e Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:25 +0000 Subject: emaclite: enable transmit and receive time stamping. This patch enables software (and phy device) time stamping. Since this MAC uses phylib, adding the hooks make hardware time stamping in the phy possible. Compile tested only. Cc: John Linn Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/xilinx_emaclite.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 9cb4cdc2859..039d976ba31 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -648,7 +648,8 @@ static void xemaclite_rx_handler(struct net_device *dev) dev->stats.rx_packets++; dev->stats.rx_bytes += len; - netif_rx(skb); /* Send the packet upstream */ + if (!skb_defer_rx_timestamp(skb)) + netif_rx(skb); /* Send the packet upstream */ } /** @@ -1030,15 +1031,19 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) spin_lock_irqsave(&lp->reset_lock, flags); if (xemaclite_send_data(lp, (u8 *) new_skb->data, len) != 0) { /* If the Emaclite Tx buffer is busy, stop the Tx queue and - * defer the skb for transmission at a later point when the + * defer the skb for transmission during the ISR, after the * current transmission is complete */ netif_stop_queue(dev); lp->deferred_skb = new_skb; + /* Take the time stamp now, since we can't do this in an ISR. */ + skb_tx_timestamp(new_skb); spin_unlock_irqrestore(&lp->reset_lock, flags); return 0; } spin_unlock_irqrestore(&lp->reset_lock, flags); + skb_tx_timestamp(new_skb); + dev->stats.tx_bytes += len; dev_kfree_skb(new_skb); -- cgit v1.2.3-70-g09d2 From 93e0ed158c15b3d3d76125de6364f8f95528c25a Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:26 +0000 Subject: ll_temac: enable transmit and receive time stamping. This patch enables software (and phy device) time stamping. Since this MAC is based on phylib, adding the hooks makes hardware time stamping in the phy possible. Compile tested only. Cc: Grant Likely Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/ll_temac_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index e7b8afec73a..e3f19255af2 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -728,6 +728,8 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (lp->tx_bd_tail >= TX_BD_NUM) lp->tx_bd_tail = 0; + skb_tx_timestamp(skb); + /* Kick off the transfer */ lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ @@ -773,7 +775,8 @@ static void ll_temac_recv(struct net_device *ndev) skb->ip_summed = CHECKSUM_COMPLETE; } - netif_rx(skb); + if (!skb_defer_rx_timestamp(skb)) + netif_rx(skb); ndev->stats.rx_packets++; ndev->stats.rx_bytes += length; -- cgit v1.2.3-70-g09d2 From d6cf07327e691e8f7c0f08af69d0dd3887aa1e4f Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:27 +0000 Subject: fec_mpc52xx: enable transmit and receive time stamping. This patch enables software (and phy device) time stamping. Software time stamping using the SO_TIMESTAMPING API was tested and found to be working on the LITE5200B board. Cc: Grant Likely Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/fec_mpc52xx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index eba0f696a51..cecc3b1eb48 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -336,6 +336,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev) bd->skb_pa = dma_map_single(dev->dev.parent, skb->data, skb->len, DMA_TO_DEVICE); + skb_tx_timestamp(skb); bcom_submit_next_buffer(priv->tx_dmatsk, skb); spin_unlock_irqrestore(&priv->lock, flags); @@ -435,7 +436,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) length = status & BCOM_FEC_RX_BD_LEN_MASK; skb_put(rskb, length - 4); /* length without CRC32 */ rskb->protocol = eth_type_trans(rskb, dev); - netif_rx(rskb); + if (!skb_defer_rx_timestamp(skb)) + netif_rx(rskb); spin_lock(&priv->lock); } -- cgit v1.2.3-70-g09d2 From e072092fc7a89178736530f51a4daaa3155cf44b Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:28 +0000 Subject: macb: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping Compile tested only. Cc: Nicolas Ferre Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/macb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 818f0b8c277..dcf6011b136 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -670,6 +670,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) entry = NEXT_TX(entry); bp->tx_head = entry; + skb_tx_timestamp(skb); + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); if (TX_BUFFS_AVAIL(bp) < 1) -- cgit v1.2.3-70-g09d2 From e309721159c05c36f10a973bef03388dadb102b0 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:29 +0000 Subject: fs_enet: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping. Compile tested only. Cc: Pantelis Antoniou Cc: Vitaly Bordug Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 21abb5c01a5..329ef231a09 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -697,6 +697,8 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) sc |= BD_ENET_TX_PAD; CBDS_SC(bdp, sc); + skb_tx_timestamp(skb); + (*fep->ops->tx_kickstart)(dev); spin_unlock_irqrestore(&fep->tx_lock, flags); -- cgit v1.2.3-70-g09d2 From 8c0069ae3a85eeedbbf955e380e822756f7a9d2f Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:30 +0000 Subject: smsc911x: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping. Compile tested only. Cc: Steve Glendinning Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 054597625d5..b9016a30cdc 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1474,6 +1474,7 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz); freespace -= (skb->len + 32); + skb_tx_timestamp(skb); dev_kfree_skb(skb); if (unlikely(smsc911x_tx_get_txstatcount(pdata) >= 30)) -- cgit v1.2.3-70-g09d2 From 1f6e44a6dc21a5d2abb068063acbbf64f8cee548 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:31 +0000 Subject: pxa168_eth: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping Compile tested only. Cc: Sachin Sanap Cc: Zhangfei Gao Cc: Philip Rakity Cc: Mark Brown Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/pxa168_eth.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 89f7540d90f..e224740c6e2 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -1267,6 +1267,9 @@ static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) pep->tx_skb[tx_index] = skb; desc->byte_cnt = length; desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); + + skb_tx_timestamp(skb); + wmb(); desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC | TX_ZERO_PADDING | TX_LAST_DESC | TX_EN_INT; -- cgit v1.2.3-70-g09d2 From d13d6bffb418a660c06a5a12afcf7e7081489548 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 19 Jun 2011 21:51:33 +0000 Subject: ucc_geth: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping. Compile tested only. Cc: Shlomi Gridish Cc: Li Yang Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/ucc_geth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index ef041057d9d..3127700f348 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3165,6 +3165,8 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) ugeth->txBd[txQ] = bd; + skb_tx_timestamp(skb); + if (ugeth->p_scheduler) { ugeth->cpucount[txQ]++; /* Indicate to QE that there are more Tx bds ready for -- cgit v1.2.3-70-g09d2 From 4aa3a715551c93eda32d79bd52042ce500bd5383 Mon Sep 17 00:00:00 2001 From: Sebastian Poehn Date: Mon, 20 Jun 2011 13:57:59 -0700 Subject: gianfar v5: implement nfc This patch adds all missing functionalities for nfc except GRXFH. There is so much code because hardware has not a TCAM. Further hardware rule space is very limited. So I had to extensively use optimization features. Both reasons lead to the necessity to hold all online flows in a linked-list. Change-log: # Some suggestions by Joe Perches applied (thanks!) # Shorted some logs # Use memcmp() for comparing Signed-off-by: Sebastian Poehn Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 10 +- drivers/net/gianfar.h | 53 +++ drivers/net/gianfar_ethtool.c | 930 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 989 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 0c748328ca7..def7f7efc80 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -657,6 +657,11 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) priv->num_rx_queues = num_rx_qs; priv->num_grps = 0x0; + /* Init Rx queue filer rule set linked list*/ + INIT_LIST_HEAD(&priv->rx_list.list); + priv->rx_list.count = 0; + mutex_init(&priv->rx_queue_access); + model = of_get_property(np, "model", NULL); for (i = 0; i < MAXGROUPS; i++) @@ -1150,9 +1155,8 @@ static int gfar_probe(struct platform_device *ofdev) priv->rx_queue[i]->rxic = DEFAULT_RXIC; } - /* enable filer if using multiple RX queues*/ - if(priv->num_rx_queues > 1) - priv->rx_filer_enable = 1; + /* always enable rx filer*/ + priv->rx_filer_enable = 1; /* Enable most messages by default */ priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index fc86f519544..a4e690a9aeb 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -47,6 +47,16 @@ #include #include +struct ethtool_flow_spec_container { + struct ethtool_rx_flow_spec fs; + struct list_head list; +}; + +struct ethtool_rx_list { + struct list_head list; + unsigned int count; +}; + /* The maximum number of packets to be handled in one call of gfar_poll */ #define GFAR_DEV_WEIGHT 64 @@ -168,6 +178,7 @@ extern const char gfar_driver_version[]; #define MACCFG2_LENGTHCHECK 0x00000010 #define MACCFG2_MPEN 0x00000008 +#define ECNTRL_FIFM 0x00008000 #define ECNTRL_INIT_SETTINGS 0x00001000 #define ECNTRL_TBI_MODE 0x00000020 #define ECNTRL_REDUCED_MODE 0x00000010 @@ -271,6 +282,7 @@ extern const char gfar_driver_version[]; #define RCTRL_TUCSEN 0x00000100 #define RCTRL_PRSDEP_MASK 0x000000c0 #define RCTRL_PRSDEP_INIT 0x000000c0 +#define RCTRL_PRSFM 0x00000020 #define RCTRL_PROM 0x00000008 #define RCTRL_EMEN 0x00000002 #define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \ @@ -1066,6 +1078,9 @@ struct gfar_private { struct vlan_group *vlgrp; + /* RX queue filer rule set*/ + struct ethtool_rx_list rx_list; + struct mutex rx_queue_access; /* Hash registers and their width */ u32 __iomem *hash_regs[16]; @@ -1140,6 +1155,16 @@ static inline void gfar_write_filer(struct gfar_private *priv, gfar_write(®s->rqfpr, fpr); } +static inline void gfar_read_filer(struct gfar_private *priv, + unsigned int far, unsigned int *fcr, unsigned int *fpr) +{ + struct gfar __iomem *regs = priv->gfargrp[0].regs; + + gfar_write(®s->rqfar, far); + *fcr = gfar_read(®s->rqfcr); + *fpr = gfar_read(®s->rqfpr); +} + extern void lock_rx_qs(struct gfar_private *priv); extern void lock_tx_qs(struct gfar_private *priv); extern void unlock_rx_qs(struct gfar_private *priv); @@ -1157,4 +1182,32 @@ int gfar_set_features(struct net_device *dev, u32 features); extern const struct ethtool_ops gfar_ethtool_ops; +#define MAX_FILER_CACHE_IDX (2*(MAX_FILER_IDX)) + +#define RQFCR_PID_PRI_MASK 0xFFFFFFF8 +#define RQFCR_PID_L4P_MASK 0xFFFFFF00 +#define RQFCR_PID_VID_MASK 0xFFFFF000 +#define RQFCR_PID_PORT_MASK 0xFFFF0000 +#define RQFCR_PID_MAC_MASK 0xFF000000 + +struct gfar_mask_entry { + unsigned int mask; /* The mask value which is valid form start to end */ + unsigned int start; + unsigned int end; + unsigned int block; /* Same block values indicate depended entries */ +}; + +/* Represents a receive filer table entry */ +struct gfar_filer_entry { + u32 ctrl; + u32 prop; +}; + + +/* The 20 additional entries are a shadow for one extra element */ +struct filer_table { + u32 index; + struct gfar_filer_entry fe[MAX_FILER_CACHE_IDX + 20]; +}; + #endif /* __GIANFAR_H */ diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 92d7ac09c87..05103362beb 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "gianfar.h" @@ -770,19 +771,945 @@ static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *c return 0; } +static int gfar_check_filer_hardware(struct gfar_private *priv) +{ + struct gfar __iomem *regs = NULL; + u32 i; + + regs = priv->gfargrp[0].regs; + + /* Check if we are in FIFO mode */ + i = gfar_read(®s->ecntrl); + i &= ECNTRL_FIFM; + if (i == ECNTRL_FIFM) { + netdev_notice(priv->ndev, "Interface in FIFO mode\n"); + i = gfar_read(®s->rctrl); + i &= RCTRL_PRSDEP_MASK | RCTRL_PRSFM; + if (i == (RCTRL_PRSDEP_MASK | RCTRL_PRSFM)) { + netdev_info(priv->ndev, + "Receive Queue Filtering enabled\n"); + } else { + netdev_warn(priv->ndev, + "Receive Queue Filtering disabled\n"); + return -EOPNOTSUPP; + } + } + /* Or in standard mode */ + else { + i = gfar_read(®s->rctrl); + i &= RCTRL_PRSDEP_MASK; + if (i == RCTRL_PRSDEP_MASK) { + netdev_info(priv->ndev, + "Receive Queue Filtering enabled\n"); + } else { + netdev_warn(priv->ndev, + "Receive Queue Filtering disabled\n"); + return -EOPNOTSUPP; + } + } + + /* Sets the properties for arbitrary filer rule + * to the first 4 Layer 4 Bytes */ + regs->rbifx = 0xC0C1C2C3; + return 0; +} + +static int gfar_comp_asc(const void *a, const void *b) +{ + return memcmp(a, b, 4); +} + +static int gfar_comp_desc(const void *a, const void *b) +{ + return -memcmp(a, b, 4); +} + +static void gfar_swap(void *a, void *b, int size) +{ + u32 *_a = a; + u32 *_b = b; + + swap(_a[0], _b[0]); + swap(_a[1], _b[1]); + swap(_a[2], _b[2]); + swap(_a[3], _b[3]); +} + +/* Write a mask to filer cache */ +static void gfar_set_mask(u32 mask, struct filer_table *tab) +{ + tab->fe[tab->index].ctrl = RQFCR_AND | RQFCR_PID_MASK | RQFCR_CMP_EXACT; + tab->fe[tab->index].prop = mask; + tab->index++; +} + +/* Sets parse bits (e.g. IP or TCP) */ +static void gfar_set_parse_bits(u32 value, u32 mask, struct filer_table *tab) +{ + gfar_set_mask(mask, tab); + tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE + | RQFCR_AND; + tab->fe[tab->index].prop = value; + tab->index++; +} + +static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, + struct filer_table *tab) +{ + gfar_set_mask(mask, tab); + tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_AND | flag; + tab->fe[tab->index].prop = value; + tab->index++; +} + +/* + * For setting a tuple of value and mask of type flag + * Example: + * IP-Src = 10.0.0.0/255.0.0.0 + * value: 0x0A000000 mask: FF000000 flag: RQFPR_IPV4 + * + * Ethtool gives us a value=0 and mask=~0 for don't care a tuple + * For a don't care mask it gives us a 0 + * + * The check if don't care and the mask adjustment if mask=0 is done for VLAN + * and MAC stuff on an upper level (due to missing information on this level). + * For these guys we can discard them if they are value=0 and mask=0. + * + * Further the all masks are one-padded for better hardware efficiency. + */ +static void gfar_set_attribute(u32 value, u32 mask, u32 flag, + struct filer_table *tab) +{ + switch (flag) { + /* 3bit */ + case RQFCR_PID_PRI: + if (!(value | mask)) + return; + mask |= RQFCR_PID_PRI_MASK; + break; + /* 8bit */ + case RQFCR_PID_L4P: + case RQFCR_PID_TOS: + if (!~(mask | RQFCR_PID_L4P_MASK)) + return; + if (!mask) + mask = ~0; + else + mask |= RQFCR_PID_L4P_MASK; + break; + /* 12bit */ + case RQFCR_PID_VID: + if (!(value | mask)) + return; + mask |= RQFCR_PID_VID_MASK; + break; + /* 16bit */ + case RQFCR_PID_DPT: + case RQFCR_PID_SPT: + case RQFCR_PID_ETY: + if (!~(mask | RQFCR_PID_PORT_MASK)) + return; + if (!mask) + mask = ~0; + else + mask |= RQFCR_PID_PORT_MASK; + break; + /* 24bit */ + case RQFCR_PID_DAH: + case RQFCR_PID_DAL: + case RQFCR_PID_SAH: + case RQFCR_PID_SAL: + if (!(value | mask)) + return; + mask |= RQFCR_PID_MAC_MASK; + break; + /* for all real 32bit masks */ + default: + if (!~mask) + return; + if (!mask) + mask = ~0; + break; + } + gfar_set_general_attribute(value, mask, flag, tab); +} + +/* Translates value and mask for UDP, TCP or SCTP */ +static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value, + struct ethtool_tcpip4_spec *mask, struct filer_table *tab) +{ + gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); + gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); + gfar_set_attribute(value->pdst, mask->pdst, RQFCR_PID_DPT, tab); + gfar_set_attribute(value->psrc, mask->psrc, RQFCR_PID_SPT, tab); + gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab); +} + +/* Translates value and mask for RAW-IP4 */ +static void gfar_set_user_ip(struct ethtool_usrip4_spec *value, + struct ethtool_usrip4_spec *mask, struct filer_table *tab) +{ + gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); + gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); + gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab); + gfar_set_attribute(value->proto, mask->proto, RQFCR_PID_L4P, tab); + gfar_set_attribute(value->l4_4_bytes, mask->l4_4_bytes, RQFCR_PID_ARB, + tab); + +} + +/* Translates value and mask for ETHER spec */ +static void gfar_set_ether(struct ethhdr *value, struct ethhdr *mask, + struct filer_table *tab) +{ + u32 upper_temp_mask = 0; + u32 lower_temp_mask = 0; + /* Source address */ + if (!is_broadcast_ether_addr(mask->h_source)) { + + if (is_zero_ether_addr(mask->h_source)) { + upper_temp_mask = 0xFFFFFFFF; + lower_temp_mask = 0xFFFFFFFF; + } else { + upper_temp_mask = mask->h_source[0] << 16 + | mask->h_source[1] << 8 + | mask->h_source[2]; + lower_temp_mask = mask->h_source[3] << 16 + | mask->h_source[4] << 8 + | mask->h_source[5]; + } + /* Upper 24bit */ + gfar_set_attribute( + value->h_source[0] << 16 | value->h_source[1] + << 8 | value->h_source[2], + upper_temp_mask, RQFCR_PID_SAH, tab); + /* And the same for the lower part */ + gfar_set_attribute( + value->h_source[3] << 16 | value->h_source[4] + << 8 | value->h_source[5], + lower_temp_mask, RQFCR_PID_SAL, tab); + } + /* Destination address */ + if (!is_broadcast_ether_addr(mask->h_dest)) { + + /* Special for destination is limited broadcast */ + if ((is_broadcast_ether_addr(value->h_dest) + && is_zero_ether_addr(mask->h_dest))) { + gfar_set_parse_bits(RQFPR_EBC, RQFPR_EBC, tab); + } else { + + if (is_zero_ether_addr(mask->h_dest)) { + upper_temp_mask = 0xFFFFFFFF; + lower_temp_mask = 0xFFFFFFFF; + } else { + upper_temp_mask = mask->h_dest[0] << 16 + | mask->h_dest[1] << 8 + | mask->h_dest[2]; + lower_temp_mask = mask->h_dest[3] << 16 + | mask->h_dest[4] << 8 + | mask->h_dest[5]; + } + + /* Upper 24bit */ + gfar_set_attribute( + value->h_dest[0] << 16 + | value->h_dest[1] << 8 + | value->h_dest[2], + upper_temp_mask, RQFCR_PID_DAH, tab); + /* And the same for the lower part */ + gfar_set_attribute( + value->h_dest[3] << 16 + | value->h_dest[4] << 8 + | value->h_dest[5], + lower_temp_mask, RQFCR_PID_DAL, tab); + } + } + + gfar_set_attribute(value->h_proto, mask->h_proto, RQFCR_PID_ETY, tab); + +} + +/* Convert a rule to binary filter format of gianfar */ +static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, + struct filer_table *tab) +{ + u32 vlan = 0, vlan_mask = 0; + u32 id = 0, id_mask = 0; + u32 cfi = 0, cfi_mask = 0; + u32 prio = 0, prio_mask = 0; + + u32 old_index = tab->index; + + /* Check if vlan is wanted */ + if ((rule->flow_type & FLOW_EXT) && (rule->m_ext.vlan_tci != 0xFFFF)) { + if (!rule->m_ext.vlan_tci) + rule->m_ext.vlan_tci = 0xFFFF; + + vlan = RQFPR_VLN; + vlan_mask = RQFPR_VLN; + + /* Separate the fields */ + id = rule->h_ext.vlan_tci & 0xFFF; + id_mask = rule->m_ext.vlan_tci & 0xFFF; + cfi = (rule->h_ext.vlan_tci >> 12) & 1; + cfi_mask = (rule->m_ext.vlan_tci >> 12) & 1; + prio = (rule->h_ext.vlan_tci >> 13) & 0x7; + prio_mask = (rule->m_ext.vlan_tci >> 13) & 0x7; + + if (cfi == 1 && cfi_mask == 1) { + vlan |= RQFPR_CFI; + vlan_mask |= RQFPR_CFI; + } else if (cfi == 0 && cfi_mask == 1) { + vlan_mask |= RQFPR_CFI; + } + } + + switch (rule->flow_type & ~FLOW_EXT) { + case TCP_V4_FLOW: + gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_TCP | vlan, + RQFPR_IPV4 | RQFPR_TCP | vlan_mask, tab); + gfar_set_basic_ip(&rule->h_u.tcp_ip4_spec, + &rule->m_u.tcp_ip4_spec, tab); + break; + case UDP_V4_FLOW: + gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_UDP | vlan, + RQFPR_IPV4 | RQFPR_UDP | vlan_mask, tab); + gfar_set_basic_ip(&rule->h_u.udp_ip4_spec, + &rule->m_u.udp_ip4_spec, tab); + break; + case SCTP_V4_FLOW: + gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, + tab); + gfar_set_attribute(132, 0, RQFCR_PID_L4P, tab); + gfar_set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u, + (struct ethtool_tcpip4_spec *) &rule->m_u, tab); + break; + case IP_USER_FLOW: + gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, + tab); + gfar_set_user_ip((struct ethtool_usrip4_spec *) &rule->h_u, + (struct ethtool_usrip4_spec *) &rule->m_u, tab); + break; + case ETHER_FLOW: + if (vlan) + gfar_set_parse_bits(vlan, vlan_mask, tab); + gfar_set_ether((struct ethhdr *) &rule->h_u, + (struct ethhdr *) &rule->m_u, tab); + break; + default: + return -1; + } + + /* Set the vlan attributes in the end */ + if (vlan) { + gfar_set_attribute(id, id_mask, RQFCR_PID_VID, tab); + gfar_set_attribute(prio, prio_mask, RQFCR_PID_PRI, tab); + } + + /* If there has been nothing written till now, it must be a default */ + if (tab->index == old_index) { + gfar_set_mask(0xFFFFFFFF, tab); + tab->fe[tab->index].ctrl = 0x20; + tab->fe[tab->index].prop = 0x0; + tab->index++; + } + + /* Remove last AND */ + tab->fe[tab->index - 1].ctrl &= (~RQFCR_AND); + + /* Specify which queue to use or to drop */ + if (rule->ring_cookie == RX_CLS_FLOW_DISC) + tab->fe[tab->index - 1].ctrl |= RQFCR_RJE; + else + tab->fe[tab->index - 1].ctrl |= (rule->ring_cookie << 10); + + /* Only big enough entries can be clustered */ + if (tab->index > (old_index + 2)) { + tab->fe[old_index + 1].ctrl |= RQFCR_CLE; + tab->fe[tab->index - 1].ctrl |= RQFCR_CLE; + } + + /* In rare cases the cache can be full while there is free space in hw */ + if (tab->index > MAX_FILER_CACHE_IDX - 1) + return -EBUSY; + + return 0; +} + +/* Copy size filer entries */ +static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0], + struct gfar_filer_entry src[0], s32 size) +{ + while (size > 0) { + size--; + dst[size].ctrl = src[size].ctrl; + dst[size].prop = src[size].prop; + } +} + +/* Delete the contents of the filer-table between start and end + * and collapse them */ +static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab) +{ + int length; + if (end > MAX_FILER_CACHE_IDX || end < begin) + return -EINVAL; + + end++; + length = end - begin; + + /* Copy */ + while (end < tab->index) { + tab->fe[begin].ctrl = tab->fe[end].ctrl; + tab->fe[begin++].prop = tab->fe[end++].prop; + + } + /* Fill up with don't cares */ + while (begin < tab->index) { + tab->fe[begin].ctrl = 0x60; + tab->fe[begin].prop = 0xFFFFFFFF; + begin++; + } + + tab->index -= length; + return 0; +} + +/* Make space on the wanted location */ +static int gfar_expand_filer_entries(u32 begin, u32 length, + struct filer_table *tab) +{ + if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX || begin + > MAX_FILER_CACHE_IDX) + return -EINVAL; + + gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]), + tab->index - length + 1); + + tab->index += length; + return 0; +} + +static int gfar_get_next_cluster_start(int start, struct filer_table *tab) +{ + for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { + if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) + == (RQFCR_AND | RQFCR_CLE)) + return start; + } + return -1; +} + +static int gfar_get_next_cluster_end(int start, struct filer_table *tab) +{ + for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { + if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) + == (RQFCR_CLE)) + return start; + } + return -1; +} + +/* + * Uses hardwares clustering option to reduce + * the number of filer table entries + */ +static void gfar_cluster_filer(struct filer_table *tab) +{ + s32 i = -1, j, iend, jend; + + while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) { + j = i; + while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) { + /* + * The cluster entries self and the previous one + * (a mask) must be identical! + */ + if (tab->fe[i].ctrl != tab->fe[j].ctrl) + break; + if (tab->fe[i].prop != tab->fe[j].prop) + break; + if (tab->fe[i - 1].ctrl != tab->fe[j - 1].ctrl) + break; + if (tab->fe[i - 1].prop != tab->fe[j - 1].prop) + break; + iend = gfar_get_next_cluster_end(i, tab); + jend = gfar_get_next_cluster_end(j, tab); + if (jend == -1 || iend == -1) + break; + /* + * First we make some free space, where our cluster + * element should be. Then we copy it there and finally + * delete in from its old location. + */ + + if (gfar_expand_filer_entries(iend, (jend - j), tab) + == -EINVAL) + break; + + gfar_copy_filer_entries(&(tab->fe[iend + 1]), + &(tab->fe[jend + 1]), jend - j); + + if (gfar_trim_filer_entries(jend - 1, + jend + (jend - j), tab) == -EINVAL) + return; + + /* Mask out cluster bit */ + tab->fe[iend].ctrl &= ~(RQFCR_CLE); + } + } +} + +/* Swaps the 0xFF80 masked bits of a1<>a2 and b1<>b2 */ +static void gfar_swap_ff80_bits(struct gfar_filer_entry *a1, + struct gfar_filer_entry *a2, struct gfar_filer_entry *b1, + struct gfar_filer_entry *b2) +{ + u32 temp[4]; + temp[0] = a1->ctrl & 0xFF80; + temp[1] = a2->ctrl & 0xFF80; + temp[2] = b1->ctrl & 0xFF80; + temp[3] = b2->ctrl & 0xFF80; + + a1->ctrl &= ~0xFF80; + a2->ctrl &= ~0xFF80; + b1->ctrl &= ~0xFF80; + b2->ctrl &= ~0xFF80; + + a1->ctrl |= temp[1]; + a2->ctrl |= temp[0]; + b1->ctrl |= temp[3]; + b2->ctrl |= temp[2]; +} + +/* + * Generate a list consisting of masks values with their start and + * end of validity and block as indicator for parts belonging + * together (glued by ANDs) in mask_table + */ +static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, + struct filer_table *tab) +{ + u32 i, and_index = 0, block_index = 1; + + for (i = 0; i < tab->index; i++) { + + /* LSByte of control = 0 sets a mask */ + if (!(tab->fe[i].ctrl & 0xF)) { + mask_table[and_index].mask = tab->fe[i].prop; + mask_table[and_index].start = i; + mask_table[and_index].block = block_index; + if (and_index >= 1) + mask_table[and_index - 1].end = i - 1; + and_index++; + } + /* cluster starts will be separated because they should + * hold their position */ + if (tab->fe[i].ctrl & RQFCR_CLE) + block_index++; + /* A not set AND indicates the end of a depended block */ + if (!(tab->fe[i].ctrl & RQFCR_AND)) + block_index++; + + } + + mask_table[and_index - 1].end = i - 1; + + return and_index; +} + +/* + * Sorts the entries of mask_table by the values of the masks. + * Important: The 0xFF80 flags of the first and last entry of a + * block must hold their position (which queue, CLusterEnable, ReJEct, + * AND) + */ +static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, + struct filer_table *temp_table, u32 and_index) +{ + /* Pointer to compare function (_asc or _desc) */ + int (*gfar_comp)(const void *, const void *); + + u32 i, size = 0, start = 0, prev = 1; + u32 old_first, old_last, new_first, new_last; + + gfar_comp = &gfar_comp_desc; + + for (i = 0; i < and_index; i++) { + + if (prev != mask_table[i].block) { + old_first = mask_table[start].start + 1; + old_last = mask_table[i - 1].end; + sort(mask_table + start, size, + sizeof(struct gfar_mask_entry), + gfar_comp, &gfar_swap); + + /* Toggle order for every block. This makes the + * thing more efficient! */ + if (gfar_comp == gfar_comp_desc) + gfar_comp = &gfar_comp_asc; + else + gfar_comp = &gfar_comp_desc; + + new_first = mask_table[start].start + 1; + new_last = mask_table[i - 1].end; + + gfar_swap_ff80_bits(&temp_table->fe[new_first], + &temp_table->fe[old_first], + &temp_table->fe[new_last], + &temp_table->fe[old_last]); + + start = i; + size = 0; + } + size++; + prev = mask_table[i].block; + } + +} + +/* + * Reduces the number of masks needed in the filer table to save entries + * This is done by sorting the masks of a depended block. A depended block is + * identified by gluing ANDs or CLE. The sorting order toggles after every + * block. Of course entries in scope of a mask must change their location with + * it. + */ +static int gfar_optimize_filer_masks(struct filer_table *tab) +{ + struct filer_table *temp_table; + struct gfar_mask_entry *mask_table; + + u32 and_index = 0, previous_mask = 0, i = 0, j = 0, size = 0; + s32 ret = 0; + + /* We need a copy of the filer table because + * we want to change its order */ + temp_table = kmalloc(sizeof(*temp_table), GFP_KERNEL); + if (temp_table == NULL) + return -ENOMEM; + memcpy(temp_table, tab, sizeof(*temp_table)); + + mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1, + sizeof(struct gfar_mask_entry), GFP_KERNEL); + + if (mask_table == NULL) { + ret = -ENOMEM; + goto end; + } + + and_index = gfar_generate_mask_table(mask_table, tab); + + gfar_sort_mask_table(mask_table, temp_table, and_index); + + /* Now we can copy the data from our duplicated filer table to + * the real one in the order the mask table says */ + for (i = 0; i < and_index; i++) { + size = mask_table[i].end - mask_table[i].start + 1; + gfar_copy_filer_entries(&(tab->fe[j]), + &(temp_table->fe[mask_table[i].start]), size); + j += size; + } + + /* And finally we just have to check for duplicated masks and drop the + * second ones */ + for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) { + if (tab->fe[i].ctrl == 0x80) { + previous_mask = i++; + break; + } + } + for (; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) { + if (tab->fe[i].ctrl == 0x80) { + if (tab->fe[i].prop == tab->fe[previous_mask].prop) { + /* Two identical ones found! + * So drop the second one! */ + gfar_trim_filer_entries(i, i, tab); + } else + /* Not identical! */ + previous_mask = i; + } + } + + kfree(mask_table); +end: kfree(temp_table); + return ret; +} + +/* Write the bit-pattern from software's buffer to hardware registers */ +static int gfar_write_filer_table(struct gfar_private *priv, + struct filer_table *tab) +{ + u32 i = 0; + if (tab->index > MAX_FILER_IDX - 1) + return -EBUSY; + + /* Avoid inconsistent filer table to be processed */ + lock_rx_qs(priv); + + /* Fill regular entries */ + for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl); i++) + gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop); + /* Fill the rest with fall-troughs */ + for (; i < MAX_FILER_IDX - 1; i++) + gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF); + /* Last entry must be default accept + * because that's what people expect */ + gfar_write_filer(priv, i, 0x20, 0x0); + + unlock_rx_qs(priv); + + return 0; +} + +static int gfar_check_capability(struct ethtool_rx_flow_spec *flow, + struct gfar_private *priv) +{ + + if (flow->flow_type & FLOW_EXT) { + if (~flow->m_ext.data[0] || ~flow->m_ext.data[1]) + netdev_warn(priv->ndev, + "User-specific data not supported!\n"); + if (~flow->m_ext.vlan_etype) + netdev_warn(priv->ndev, + "VLAN-etype not supported!\n"); + } + if (flow->flow_type == IP_USER_FLOW) + if (flow->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4) + netdev_warn(priv->ndev, + "IP-Version differing from IPv4 not supported!\n"); + + return 0; +} + +static int gfar_process_filer_changes(struct gfar_private *priv) +{ + struct ethtool_flow_spec_container *j; + struct filer_table *tab; + s32 i = 0; + s32 ret = 0; + + /* So index is set to zero, too! */ + tab = kzalloc(sizeof(*tab), GFP_KERNEL); + if (tab == NULL) + return -ENOMEM; + + /* Now convert the existing filer data from flow_spec into + * filer tables binary format */ + list_for_each_entry(j, &priv->rx_list.list, list) { + ret = gfar_convert_to_filer(&j->fs, tab); + if (ret == -EBUSY) { + netdev_err(priv->ndev, "Rule not added: No free space!\n"); + goto end; + } + if (ret == -1) { + netdev_err(priv->ndev, "Rule not added: Unsupported Flow-type!\n"); + goto end; + } + } + + i = tab->index; + + /* Optimizations to save entries */ + gfar_cluster_filer(tab); + gfar_optimize_filer_masks(tab); + + pr_debug("\n\tSummary:\n" + "\tData on hardware: %d\n" + "\tCompression rate: %d%%\n", + tab->index, 100 - (100 * tab->index) / i); + + /* Write everything to hardware */ + ret = gfar_write_filer_table(priv, tab); + if (ret == -EBUSY) { + netdev_err(priv->ndev, "Rule not added: No free space!\n"); + goto end; + } + +end: kfree(tab); + return ret; +} + +static void gfar_invert_masks(struct ethtool_rx_flow_spec *flow) +{ + u32 i = 0; + + for (i = 0; i < sizeof(flow->m_u); i++) + flow->m_u.hdata[i] ^= 0xFF; + + flow->m_ext.vlan_etype ^= 0xFFFF; + flow->m_ext.vlan_tci ^= 0xFFFF; + flow->m_ext.data[0] ^= ~0; + flow->m_ext.data[1] ^= ~0; +} + +static int gfar_add_cls(struct gfar_private *priv, + struct ethtool_rx_flow_spec *flow) +{ + struct ethtool_flow_spec_container *temp, *comp; + int ret = 0; + + temp = kmalloc(sizeof(*temp), GFP_KERNEL); + if (temp == NULL) + return -ENOMEM; + memcpy(&temp->fs, flow, sizeof(temp->fs)); + + gfar_invert_masks(&temp->fs); + ret = gfar_check_capability(&temp->fs, priv); + if (ret) + goto clean_mem; + /* Link in the new element at the right @location */ + if (list_empty(&priv->rx_list.list)) { + ret = gfar_check_filer_hardware(priv); + if (ret != 0) + goto clean_mem; + list_add(&temp->list, &priv->rx_list.list); + goto process; + } else { + + list_for_each_entry(comp, &priv->rx_list.list, list) { + if (comp->fs.location > flow->location) { + list_add_tail(&temp->list, &comp->list); + goto process; + } + if (comp->fs.location == flow->location) { + netdev_err(priv->ndev, + "Rule not added: ID %d not free!\n", + flow->location); + ret = -EBUSY; + goto clean_mem; + } + } + list_add_tail(&temp->list, &priv->rx_list.list); + } + +process: + ret = gfar_process_filer_changes(priv); + if (ret) + goto clean_list; + priv->rx_list.count++; + return ret; + +clean_list: + list_del(&temp->list); +clean_mem: + kfree(temp); + return ret; +} + +static int gfar_del_cls(struct gfar_private *priv, u32 loc) +{ + struct ethtool_flow_spec_container *comp; + u32 ret = -EINVAL; + + if (list_empty(&priv->rx_list.list)) + return ret; + + list_for_each_entry(comp, &priv->rx_list.list, list) { + if (comp->fs.location == loc) { + list_del(&comp->list); + kfree(comp); + priv->rx_list.count--; + gfar_process_filer_changes(priv); + ret = 0; + break; + } + } + + return ret; + +} + +static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd) +{ + struct ethtool_flow_spec_container *comp; + u32 ret = -EINVAL; + + list_for_each_entry(comp, &priv->rx_list.list, list) { + if (comp->fs.location == cmd->fs.location) { + memcpy(&cmd->fs, &comp->fs, sizeof(cmd->fs)); + gfar_invert_masks(&cmd->fs); + ret = 0; + break; + } + } + + return ret; +} + +static int gfar_get_cls_all(struct gfar_private *priv, + struct ethtool_rxnfc *cmd, u32 *rule_locs) +{ + struct ethtool_flow_spec_container *comp; + u32 i = 0; + + list_for_each_entry(comp, &priv->rx_list.list, list) { + if (i <= cmd->rule_cnt) { + rule_locs[i] = comp->fs.location; + i++; + } + } + + cmd->data = MAX_FILER_IDX; + + return 0; +} + static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) { struct gfar_private *priv = netdev_priv(dev); int ret = 0; - switch(cmd->cmd) { + mutex_lock(&priv->rx_queue_access); + + switch (cmd->cmd) { case ETHTOOL_SRXFH: ret = gfar_set_hash_opts(priv, cmd); break; + case ETHTOOL_SRXCLSRLINS: + if (cmd->fs.ring_cookie != RX_CLS_FLOW_DISC && + cmd->fs.ring_cookie >= priv->num_rx_queues) { + ret = -EINVAL; + break; + } + ret = gfar_add_cls(priv, &cmd->fs); + break; + case ETHTOOL_SRXCLSRLDEL: + ret = gfar_del_cls(priv, cmd->fs.location); + break; default: ret = -EINVAL; } + mutex_unlock(&priv->rx_queue_access); + + return ret; +} + +static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + void *rule_locs) +{ + struct gfar_private *priv = netdev_priv(dev); + int ret = 0; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = priv->num_rx_queues; + break; + case ETHTOOL_GRXCLSRLCNT: + cmd->rule_cnt = priv->rx_list.count; + break; + case ETHTOOL_GRXCLSRULE: + ret = gfar_get_cls(priv, cmd); + break; + case ETHTOOL_GRXCLSRLALL: + ret = gfar_get_cls_all(priv, cmd, (u32 *) rule_locs); + break; + default: + ret = -EINVAL; + break; + } + return ret; } @@ -807,4 +1734,5 @@ const struct ethtool_ops gfar_ethtool_ops = { .set_wol = gfar_set_wol, #endif .set_rxnfc = gfar_set_nfc, + .get_rxnfc = gfar_get_nfc, }; -- cgit v1.2.3-70-g09d2 From e97d3207c5e697e3d86cc67483f9cdcce16cc0bf Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Wed, 8 Jun 2011 08:36:42 +0000 Subject: e1000: convert to ndo_fix_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Private rx_csum flags are now duplicate of netdev->features & NETIF_F_RXCSUM. Removing this needs deeper surgery. Things noticed: - RX csum disabled by default - HW VLAN acceleration probably can be toggled, but it's left as is - the resets on RX csum offload change can probably be avoided - there is A LOT of copy-and-pasted code here Signed-off-by: Michał Mirosław Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000/e1000_ethtool.c | 69 --------------------------------------- drivers/net/e1000/e1000_main.c | 30 ++++++++++++++--- 2 files changed, 26 insertions(+), 73 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index ec0fa426cce..c5f0f04219f 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -290,69 +290,6 @@ static int e1000_set_pauseparam(struct net_device *netdev, return retval; } -static u32 e1000_get_rx_csum(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - return adapter->rx_csum; -} - -static int e1000_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - adapter->rx_csum = data; - - if (netif_running(netdev)) - e1000_reinit_locked(adapter); - else - e1000_reset(adapter); - return 0; -} - -static u32 e1000_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_HW_CSUM) != 0; -} - -static int e1000_set_tx_csum(struct net_device *netdev, u32 data) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_hw *hw = &adapter->hw; - - if (hw->mac_type < e1000_82543) { - if (!data) - return -EINVAL; - return 0; - } - - if (data) - netdev->features |= NETIF_F_HW_CSUM; - else - netdev->features &= ~NETIF_F_HW_CSUM; - - return 0; -} - -static int e1000_set_tso(struct net_device *netdev, u32 data) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_hw *hw = &adapter->hw; - - if ((hw->mac_type < e1000_82544) || - (hw->mac_type == e1000_82547)) - return data ? -EINVAL : 0; - - if (data) - netdev->features |= NETIF_F_TSO; - else - netdev->features &= ~NETIF_F_TSO; - - netdev->features &= ~NETIF_F_TSO6; - - e_info(probe, "TSO is %s\n", data ? "Enabled" : "Disabled"); - adapter->tso_force = true; - return 0; -} - static u32 e1000_get_msglevel(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); @@ -1905,12 +1842,6 @@ static const struct ethtool_ops e1000_ethtool_ops = { .set_ringparam = e1000_set_ringparam, .get_pauseparam = e1000_get_pauseparam, .set_pauseparam = e1000_set_pauseparam, - .get_rx_csum = e1000_get_rx_csum, - .set_rx_csum = e1000_set_rx_csum, - .get_tx_csum = e1000_get_tx_csum, - .set_tx_csum = e1000_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = e1000_set_tso, .self_test = e1000_diag_test, .get_strings = e1000_get_strings, .set_phys_id = e1000_set_phys_id, diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 76e8af00d86..188d99ae908 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -797,6 +797,24 @@ static int e1000_is_need_ioport(struct pci_dev *pdev) } } +static int e1000_set_features(struct net_device *netdev, u32 features) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + u32 changed = features ^ netdev->features; + + if (!(changed & NETIF_F_RXCSUM)) + return 0; + + adapter->rx_csum = !!(features & NETIF_F_RXCSUM); + + if (netif_running(netdev)) + e1000_reinit_locked(adapter); + else + e1000_reset(adapter); + + return 0; +} + static const struct net_device_ops e1000_netdev_ops = { .ndo_open = e1000_open, .ndo_stop = e1000_close, @@ -815,6 +833,7 @@ static const struct net_device_ops e1000_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = e1000_netpoll, #endif + .ndo_set_features = e1000_set_features, }; /** @@ -1016,16 +1035,19 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } if (hw->mac_type >= e1000_82543) { - netdev->features = NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_TX | + netdev->hw_features = NETIF_F_SG | + NETIF_F_HW_CSUM; + netdev->features = NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; } if ((hw->mac_type >= e1000_82544) && (hw->mac_type != e1000_82547)) - netdev->features |= NETIF_F_TSO; + netdev->hw_features |= NETIF_F_TSO; + + netdev->features |= netdev->hw_features; + netdev->hw_features |= NETIF_F_RXCSUM; if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; -- cgit v1.2.3-70-g09d2 From ac52caa31e0a135a8940a66de763751760820f37 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Wed, 8 Jun 2011 08:38:01 +0000 Subject: igb: convert to ndo_fix_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Private rx_csum flags are now duplicate of netdev->features & NETIF_F_RXCSUM. Removing this needs deeper surgery. Things noticed: - HW VLAN acceleration probably can be toggled, but it's left as is - the resets on RX csum offload change can probably be avoided - there is A LOT of copy-and-pasted code here Signed-off-by: Michał Mirosław Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_ethtool.c | 67 ------------------------------------------- drivers/net/igb/igb_main.c | 33 ++++++++++++++++----- 2 files changed, 26 insertions(+), 74 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index fdc895e5a3f..1862c97508e 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -318,65 +318,6 @@ static int igb_set_pauseparam(struct net_device *netdev, return retval; } -static u32 igb_get_rx_csum(struct net_device *netdev) -{ - struct igb_adapter *adapter = netdev_priv(netdev); - return !!(adapter->rx_ring[0]->flags & IGB_RING_FLAG_RX_CSUM); -} - -static int igb_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct igb_adapter *adapter = netdev_priv(netdev); - int i; - - for (i = 0; i < adapter->num_rx_queues; i++) { - if (data) - adapter->rx_ring[i]->flags |= IGB_RING_FLAG_RX_CSUM; - else - adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM; - } - - return 0; -} - -static u32 igb_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_IP_CSUM) != 0; -} - -static int igb_set_tx_csum(struct net_device *netdev, u32 data) -{ - struct igb_adapter *adapter = netdev_priv(netdev); - - if (data) { - netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - if (adapter->hw.mac.type >= e1000_82576) - netdev->features |= NETIF_F_SCTP_CSUM; - } else { - netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_SCTP_CSUM); - } - - return 0; -} - -static int igb_set_tso(struct net_device *netdev, u32 data) -{ - struct igb_adapter *adapter = netdev_priv(netdev); - - if (data) { - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - } else { - netdev->features &= ~NETIF_F_TSO; - netdev->features &= ~NETIF_F_TSO6; - } - - dev_info(&adapter->pdev->dev, "TSO is %s\n", - data ? "Enabled" : "Disabled"); - return 0; -} - static u32 igb_get_msglevel(struct net_device *netdev) { struct igb_adapter *adapter = netdev_priv(netdev); @@ -2207,14 +2148,6 @@ static const struct ethtool_ops igb_ethtool_ops = { .set_ringparam = igb_set_ringparam, .get_pauseparam = igb_get_pauseparam, .set_pauseparam = igb_set_pauseparam, - .get_rx_csum = igb_get_rx_csum, - .set_rx_csum = igb_set_rx_csum, - .get_tx_csum = igb_get_tx_csum, - .set_tx_csum = igb_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = igb_set_tso, .self_test = igb_diag_test, .get_strings = igb_get_strings, .set_phys_id = igb_set_phys_id, diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index fd64c56a433..6e67258c4b4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1748,6 +1748,21 @@ void igb_reset(struct igb_adapter *adapter) igb_get_phy_info(hw); } +static int igb_set_features(struct net_device *netdev, u32 features) +{ + struct igb_adapter *adapter = netdev_priv(netdev); + int i; + + for (i = 0; i < adapter->num_rx_queues; i++) { + if (features & NETIF_F_RXCSUM) + adapter->rx_ring[i]->flags |= IGB_RING_FLAG_RX_CSUM; + else + adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM; + } + + return 0; +} + static const struct net_device_ops igb_netdev_ops = { .ndo_open = igb_open, .ndo_stop = igb_close, @@ -1770,6 +1785,7 @@ static const struct net_device_ops igb_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = igb_netpoll, #endif + .ndo_set_features = igb_set_features, }; /** @@ -1909,17 +1925,18 @@ static int __devinit igb_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "PHY reset is blocked due to SOL/IDER session.\n"); - netdev->features = NETIF_F_SG | + netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_TSO | + NETIF_F_TSO6 | + NETIF_F_RXCSUM; + + netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - netdev->features |= NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - netdev->features |= NETIF_F_GRO; - netdev->vlan_features |= NETIF_F_TSO; netdev->vlan_features |= NETIF_F_TSO6; netdev->vlan_features |= NETIF_F_IP_CSUM; @@ -1931,8 +1948,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_HIGHDMA; } - if (hw->mac.type >= e1000_82576) + if (hw->mac.type >= e1000_82576) { + netdev->hw_features |= NETIF_F_SCTP_CSUM; netdev->features |= NETIF_F_SCTP_CSUM; + } adapter->en_mng_pt = igb_enable_mng_pass_thru(hw); -- cgit v1.2.3-70-g09d2 From f416dfc0e07120d2610e836609b7235897796c90 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Wed, 8 Jun 2011 07:32:38 +0000 Subject: ixgbevf: Fix bungled declaration of ixgbevf_mbx_ops In two places storage for mbx_ops is misidentified as type ixgbe_mac_operations. Reported-by: Andi Kleen Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf.h | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index b703f60be3b..a2bbbb35816 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -279,7 +279,7 @@ enum ixgbevf_boards { extern struct ixgbevf_info ixgbevf_82599_vf_info; extern struct ixgbevf_info ixgbevf_X540_vf_info; -extern struct ixgbe_mac_operations ixgbevf_mbx_ops; +extern struct ixgbe_mbx_operations ixgbevf_mbx_ops; /* needed by ethtool.c */ extern char ixgbevf_driver_name[]; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index b2c5ecda797..721417eb055 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -3364,7 +3364,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, hw->mac.type = ii->mac; memcpy(&hw->mbx.ops, &ixgbevf_mbx_ops, - sizeof(struct ixgbe_mac_operations)); + sizeof(struct ixgbe_mbx_operations)); adapter->flags &= ~IXGBE_FLAG_RX_PS_CAPABLE; adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; -- cgit v1.2.3-70-g09d2 From c12db7695e1f52b27108c3dfde3cf655a0368c58 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 9 Jun 2011 02:58:39 +0000 Subject: ixgbevf: remove unnecessary ampersands Use standard format for net_device_ops (without &) Signed-off-by: Stephen Hemminger Acked-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf_main.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 721417eb055..fec36bde199 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -3249,18 +3249,18 @@ static void ixgbevf_shutdown(struct pci_dev *pdev) } static const struct net_device_ops ixgbe_netdev_ops = { - .ndo_open = &ixgbevf_open, - .ndo_stop = &ixgbevf_close, - .ndo_start_xmit = &ixgbevf_xmit_frame, - .ndo_set_rx_mode = &ixgbevf_set_rx_mode, - .ndo_set_multicast_list = &ixgbevf_set_rx_mode, + .ndo_open = ixgbevf_open, + .ndo_stop = ixgbevf_close, + .ndo_start_xmit = ixgbevf_xmit_frame, + .ndo_set_rx_mode = ixgbevf_set_rx_mode, + .ndo_set_multicast_list = ixgbevf_set_rx_mode, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = &ixgbevf_set_mac, - .ndo_change_mtu = &ixgbevf_change_mtu, - .ndo_tx_timeout = &ixgbevf_tx_timeout, - .ndo_vlan_rx_register = &ixgbevf_vlan_rx_register, - .ndo_vlan_rx_add_vid = &ixgbevf_vlan_rx_add_vid, - .ndo_vlan_rx_kill_vid = &ixgbevf_vlan_rx_kill_vid, + .ndo_set_mac_address = ixgbevf_set_mac, + .ndo_change_mtu = ixgbevf_change_mtu, + .ndo_tx_timeout = ixgbevf_tx_timeout, + .ndo_vlan_rx_register = ixgbevf_vlan_rx_register, + .ndo_vlan_rx_add_vid = ixgbevf_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = ixgbevf_vlan_rx_kill_vid, }; static void ixgbevf_assign_netdev_ops(struct net_device *dev) -- cgit v1.2.3-70-g09d2 From 1fcd86b51179518f7e69164e37353fb59cd6301e Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 10:05:14 +0000 Subject: ixgbe: dcbnl reduce duplicated code and indentation Replace duplicated code in if/else branches with single check and ixgbe_init_interrupt_scheme(). Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 49 +++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 5e7ed225851..293ff06ba16 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -146,37 +146,34 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->flags |= IXGBE_FLAG_DCB_ENABLED; if (!netdev_get_num_tc(netdev)) ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS); - - ixgbe_init_interrupt_scheme(adapter); - if (netif_running(netdev)) - netdev->netdev_ops->ndo_open(netdev); } else { /* Turn off DCB */ - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - if (netif_running(netdev)) - netdev->netdev_ops->ndo_stop(netdev); - ixgbe_clear_interrupt_scheme(adapter); + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + goto out; - adapter->hw.fc.requested_mode = adapter->last_lfc_mode; - adapter->temp_dcb_cfg.pfc_mode_enable = false; - adapter->dcb_cfg.pfc_mode_enable = false; - adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; - break; - default: - break; - } - - ixgbe_setup_tc(netdev, 0); - - ixgbe_init_interrupt_scheme(adapter); - if (netif_running(netdev)) - netdev->netdev_ops->ndo_open(netdev); + if (netif_running(netdev)) + netdev->netdev_ops->ndo_stop(netdev); + ixgbe_clear_interrupt_scheme(adapter); + + adapter->hw.fc.requested_mode = adapter->last_lfc_mode; + adapter->temp_dcb_cfg.pfc_mode_enable = false; + adapter->dcb_cfg.pfc_mode_enable = false; + adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + break; + default: + break; } + + ixgbe_setup_tc(netdev, 0); } + + ixgbe_init_interrupt_scheme(adapter); + if (netif_running(netdev)) + netdev->netdev_ops->ndo_open(netdev); out: return err; } -- cgit v1.2.3-70-g09d2 From 80605c6513207344d00b32e8d1e64bd34fdf1358 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Mon, 2 May 2011 12:34:10 +0000 Subject: ixgbe: consolidate packet buffer allocation Consolidate packet buffer allocation currently being done in the DCB path and main path. This allows the feature set and packet buffer requirements to be done once. This is prep work to allow DCB to coexist with other features namely, flow director. CC: Alexander Duyck Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 42 +++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_82599.c | 39 +--------------------- drivers/net/ixgbe/ixgbe_common.c | 66 +++++++++++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_common.h | 3 ++ drivers/net/ixgbe/ixgbe_dcb.c | 10 +++--- drivers/net/ixgbe/ixgbe_dcb.h | 7 ---- drivers/net/ixgbe/ixgbe_dcb_82598.c | 43 +----------------------- drivers/net/ixgbe/ixgbe_dcb_82598.h | 3 +- drivers/net/ixgbe/ixgbe_dcb_82599.c | 62 +--------------------------------- drivers/net/ixgbe/ixgbe_dcb_82599.h | 14 +------- drivers/net/ixgbe/ixgbe_main.c | 16 ++++++++- drivers/net/ixgbe/ixgbe_type.h | 24 ++++++++++++++ drivers/net/ixgbe/ixgbe_x540.c | 1 + 13 files changed, 160 insertions(+), 170 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 8179e5060a1..bb417d746a1 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1242,6 +1242,47 @@ static void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw) } } +/** + * ixgbe_set_rxpba_82598 - Configure packet buffers + * @hw: pointer to hardware structure + * @dcb_config: pointer to ixgbe_dcb_config structure + * + * Configure packet buffers. + */ +static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb, u32 headroom, + int strategy) +{ + u32 rxpktsize = IXGBE_RXPBSIZE_64KB; + u8 i = 0; + + if (!num_pb) + return; + + /* Setup Rx packet buffer sizes */ + switch (strategy) { + case PBA_STRATEGY_WEIGHTED: + /* Setup the first four at 80KB */ + rxpktsize = IXGBE_RXPBSIZE_80KB; + for (; i < 4; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + /* Setup the last four at 48KB...don't re-init i */ + rxpktsize = IXGBE_RXPBSIZE_48KB; + /* Fall Through */ + case PBA_STRATEGY_EQUAL: + default: + /* Divide the remaining Rx packet buffer evenly among the TCs */ + for (; i < IXGBE_MAX_PACKET_BUFFERS; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + break; + } + + /* Setup Tx packet buffer sizes */ + for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB); + + return; +} + static struct ixgbe_mac_operations mac_ops_82598 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82598, @@ -1257,6 +1298,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .read_analog_reg8 = &ixgbe_read_analog_reg8_82598, .write_analog_reg8 = &ixgbe_write_analog_reg8_82598, .setup_link = &ixgbe_setup_mac_link_82598, + .set_rxpba = &ixgbe_set_rxpba_82598, .check_link = &ixgbe_check_mac_link_82598, .get_link_capabilities = &ixgbe_get_link_capabilities_82598, .led_on = &ixgbe_led_on_generic, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 0d7bc915635..324a5051f81 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1114,27 +1114,8 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) { u32 fdirctrl = 0; - u32 pbsize; int i; - /* - * Before enabling Flow Director, the Rx Packet Buffer size - * must be reduced. The new value is the current size minus - * flow director memory usage size. - */ - pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc)); - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), - (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize)); - - /* - * The defaults in the HW for RX PB 1-7 are not zero and so should be - * initialized to zero for non DCB mode otherwise actual total RX PB - * would be bigger than programmed and filter space would run into - * the PB 0 region. - */ - for (i = 1; i < 8; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); - /* Send interrupt when 64 filters are left */ fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; @@ -1202,27 +1183,8 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) { u32 fdirctrl = 0; - u32 pbsize; int i; - /* - * Before enabling Flow Director, the Rx Packet Buffer size - * must be reduced. The new value is the current size minus - * flow director memory usage size. - */ - pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc)); - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), - (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize)); - - /* - * The defaults in the HW for RX PB 1-7 are not zero and so should be - * initialized to zero for non DCB mode otherwise actual total RX PB - * would be bigger than programmed and filter space would run into - * the PB 0 region. - */ - for (i = 1; i < 8; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); - /* Send interrupt when 64 filters are left */ fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; @@ -2146,6 +2108,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .read_analog_reg8 = &ixgbe_read_analog_reg8_82599, .write_analog_reg8 = &ixgbe_write_analog_reg8_82599, .setup_link = &ixgbe_setup_mac_link_82599, + .set_rxpba = &ixgbe_set_rxpba_generic, .check_link = &ixgbe_check_mac_link_generic, .get_link_capabilities = &ixgbe_get_link_capabilities_82599, .led_on = &ixgbe_led_on_generic, diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index de65643b79a..cc2a4a1528e 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -3267,3 +3267,69 @@ s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps) return 0; } + +/** + * ixgbe_set_rxpba_generic - Initialize RX packet buffer + * @hw: pointer to hardware structure + * @num_pb: number of packet buffers to allocate + * @headroom: reserve n KB of headroom + * @strategy: packet buffer allocation strategy + **/ +void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, + int num_pb, + u32 headroom, + int strategy) +{ + u32 pbsize = hw->mac.rx_pb_size; + int i = 0; + u32 rxpktsize, txpktsize, txpbthresh; + + /* Reserve headroom */ + pbsize -= headroom; + + if (!num_pb) + num_pb = 1; + + /* Divide remaining packet buffer space amongst the number + * of packet buffers requested using supplied strategy. + */ + switch (strategy) { + case (PBA_STRATEGY_WEIGHTED): + /* pba_80_48 strategy weight first half of packet buffer with + * 5/8 of the packet buffer space. + */ + rxpktsize = ((pbsize * 5 * 2) / (num_pb * 8)); + pbsize -= rxpktsize * (num_pb / 2); + rxpktsize <<= IXGBE_RXPBSIZE_SHIFT; + for (; i < (num_pb / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + /* Fall through to configure remaining packet buffers */ + case (PBA_STRATEGY_EQUAL): + /* Divide the remaining Rx packet buffer evenly among the TCs */ + rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT; + for (; i < num_pb; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + break; + default: + break; + } + + /* + * Setup Tx packet buffer and threshold equally for all TCs + * TXPBTHRESH register is set in K so divide by 1024 and subtract + * 10 since the largest packet we support is just over 9K. + */ + txpktsize = IXGBE_TXPBSIZE_MAX / num_pb; + txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX; + for (i = 0; i < num_pb; i++) { + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize); + IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh); + } + + /* Clear unused TCs, if any, to zero buffer size*/ + for (; i < IXGBE_MAX_PB; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0); + } +} diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 46be83cfb50..32a454fc67c 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -100,6 +100,9 @@ void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf); void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); +void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, + u32 headroom, int strategy); + #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg))) #ifndef writeq diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 686a17aadef..9d88c31487b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -258,15 +258,13 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, switch (hw->mac.type) { case ixgbe_mac_82598EB: - ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->rx_pba_cfg, - pfc_en, refill, max, bwgid, - ptype); + ret = ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max, + bwgid, ptype); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: - ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->rx_pba_cfg, - pfc_en, refill, max, bwgid, - ptype, prio_tc); + ret = ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max, + bwgid, ptype, prio_tc); break; default: break; diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 944838fc7b5..e85826ae032 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -123,11 +123,6 @@ struct tc_configuration { u8 tc; /* Traffic class (TC) */ }; -enum dcb_rx_pba_cfg { - pba_equal, /* PBA[0-7] each use 64KB FIFO */ - pba_80_48 /* PBA[0-3] each use 80KB, PBA[4-7] each use 48KB */ -}; - struct dcb_num_tcs { u8 pg_tcs; u8 pfc_tcs; @@ -140,8 +135,6 @@ struct ixgbe_dcb_config { u8 bw_percentage[2][MAX_BW_GROUP]; /* One each for Tx/Rx */ bool pfc_mode_enable; - enum dcb_rx_pba_cfg rx_pba_cfg; - u32 dcb_cfg_version; /* Not used...OS-specific? */ u32 link_speed; /* For bandwidth allocation validation purpose */ }; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index 771d01a60d0..2288c3cac01 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -31,45 +31,6 @@ #include "ixgbe_dcb.h" #include "ixgbe_dcb_82598.h" -/** - * ixgbe_dcb_config_packet_buffers_82598 - Configure packet buffers - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure packet buffers for DCB mode. - */ -static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, u8 rx_pba) -{ - s32 ret_val = 0; - u32 value = IXGBE_RXPBSIZE_64KB; - u8 i = 0; - - /* Setup Rx packet buffer sizes */ - switch (rx_pba) { - case pba_80_48: - /* Setup the first four at 80KB */ - value = IXGBE_RXPBSIZE_80KB; - for (; i < 4; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value); - /* Setup the last four at 48KB...don't re-init i */ - value = IXGBE_RXPBSIZE_48KB; - /* Fall Through */ - case pba_equal: - default: - for (; i < IXGBE_MAX_PACKET_BUFFERS; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value); - - /* Setup Tx packet buffer sizes */ - for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) { - IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), - IXGBE_TXPBSIZE_40KB); - } - break; - } - - return ret_val; -} - /** * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter * @hw: pointer to hardware structure @@ -321,11 +282,9 @@ static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) * * Configure dcb settings and enable dcb mode. */ -s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, - u8 rx_pba, u8 pfc_en, u16 *refill, +s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type) { - ixgbe_dcb_config_packet_buffers_82598(hw, rx_pba); ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type); ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, prio_type); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index 1e9750c2b46..2f318935561 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h @@ -91,8 +91,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, u8 *bwg_id, u8 *prio_type); -s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, - u8 rx_pba, u8 pfc_en, u16 *refill, +s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type); #endif /* _DCB_82598_CONFIG_H */ diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index d50cf78c234..befe8ad134c 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -30,63 +30,6 @@ #include "ixgbe_dcb.h" #include "ixgbe_dcb_82599.h" -/** - * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers - * @hw: pointer to hardware structure - * @rx_pba: method to distribute packet buffer - * - * Configure packet buffers for DCB mode. - */ -static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, u8 rx_pba) -{ - int num_tcs = IXGBE_MAX_PACKET_BUFFERS; - u32 rx_pb_size = hw->mac.rx_pb_size << IXGBE_RXPBSIZE_SHIFT; - u32 rxpktsize; - u32 txpktsize; - u32 txpbthresh; - u8 i = 0; - - /* - * This really means configure the first half of the TCs - * (Traffic Classes) to use 5/8 of the Rx packet buffer - * space. To determine the size of the buffer for each TC, - * we are multiplying the average size by 5/4 and applying - * it to half of the traffic classes. - */ - if (rx_pba == pba_80_48) { - rxpktsize = (rx_pb_size * 5) / (num_tcs * 4); - rx_pb_size -= rxpktsize * (num_tcs / 2); - for (; i < (num_tcs / 2); i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); - } - - /* Divide the remaining Rx packet buffer evenly among the TCs */ - rxpktsize = rx_pb_size / (num_tcs - i); - for (; i < num_tcs; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); - - /* - * Setup Tx packet buffer and threshold equally for all TCs - * TXPBTHRESH register is set in K so divide by 1024 and subtract - * 10 since the largest packet we support is just over 9K. - */ - txpktsize = IXGBE_TXPBSIZE_MAX / num_tcs; - txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX; - for (i = 0; i < num_tcs; i++) { - IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize); - IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh); - } - - /* Clear unused TCs, if any, to zero buffer size*/ - for (; i < MAX_TRAFFIC_CLASS; i++) { - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0); - } - - return 0; -} - /** * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter * @hw: pointer to hardware structure @@ -434,7 +377,6 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) /** * ixgbe_dcb_hw_config_82599 - Configure and enable DCB * @hw: pointer to hardware structure - * @rx_pba: method to distribute packet buffer * @refill: refill credits index by traffic class * @max: max credits index by traffic class * @bwg_id: bandwidth grouping indexed by traffic class @@ -443,11 +385,9 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) * * Configure dcb settings and enable dcb mode. */ -s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, - u8 rx_pba, u8 pfc_en, u16 *refill, +s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type, u8 *prio_tc) { - ixgbe_dcb_config_packet_buffers_82599(hw, rx_pba); ixgbe_dcb_config_82599(hw); ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, prio_type, prio_tc); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 2de71a50315..08d1749862a 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -86,17 +86,6 @@ #define IXGBE_RTTPCS_ARBD_SHIFT 22 #define IXGBE_RTTPCS_ARBD_DCB 0x4 /* Arbitration delay in DCB mode */ -#define IXGBE_TXPBSIZE_20KB 0x00005000 /* 20KB Packet Buffer */ -#define IXGBE_TXPBSIZE_40KB 0x0000A000 /* 40KB Packet Buffer */ -#define IXGBE_RXPBSIZE_48KB 0x0000C000 /* 48KB Packet Buffer */ -#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */ -#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */ -#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */ -#define IXGBE_TXPBSIZE_MAX 0x00028000 /* 160KB Packet Buffer*/ - -#define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */ -#define IXGBE_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */ - /* SECTXMINIFG DCB */ #define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer IFG */ @@ -127,8 +116,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, u8 *prio_type, u8 *prio_tc); -s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, - u8 rx_pba, u8 pfc_en, u16 *refill, +s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type, u8 *prio_tc); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 06cfaf31bcf..fba1e323495 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3780,12 +3780,27 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) } #endif + +static void ixgbe_configure_pb(struct ixgbe_adapter *adapter) +{ + int hdrm = 0; + int num_tc = netdev_get_num_tc(adapter->netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || + adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) + hdrm = 64 << adapter->fdir_pballoc; + + hw->mac.ops.set_rxpba(&adapter->hw, num_tc, hdrm, PBA_STRATEGY_EQUAL); +} + static void ixgbe_configure(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; int i; + ixgbe_configure_pb(adapter); #ifdef CONFIG_IXGBE_DCB ixgbe_configure_dcb(adapter); #endif @@ -5251,7 +5266,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) } adapter->dcb_cfg.bw_percentage[DCB_TX_CONFIG][0] = 100; adapter->dcb_cfg.bw_percentage[DCB_RX_CONFIG][0] = 100; - adapter->dcb_cfg.rx_pba_cfg = pba_equal; adapter->dcb_cfg.pfc_mode_enable = false; adapter->dcb_set_bitmap = 0x00; adapter->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE; diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index fa43f2507f4..c0849a649d4 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1118,6 +1118,27 @@ #define IXGBE_GPIE_VTMODE_32 0x00008000 /* 32 VFs 4 queues per VF */ #define IXGBE_GPIE_VTMODE_64 0x0000C000 /* 64 VFs 2 queues per VF */ +/* Packet Buffer Initialization */ +#define IXGBE_TXPBSIZE_20KB 0x00005000 /* 20KB Packet Buffer */ +#define IXGBE_TXPBSIZE_40KB 0x0000A000 /* 40KB Packet Buffer */ +#define IXGBE_RXPBSIZE_48KB 0x0000C000 /* 48KB Packet Buffer */ +#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */ +#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */ +#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */ +#define IXGBE_RXPBSIZE_MAX 0x00080000 /* 512KB Packet Buffer*/ +#define IXGBE_TXPBSIZE_MAX 0x00028000 /* 160KB Packet Buffer*/ + +#define IXGBE_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */ +#define IXGBE_MAX_PB 8 + +/* Packet buffer allocation strategies */ +enum { + PBA_STRATEGY_EQUAL = 0, /* Distribute PB space equally */ +#define PBA_STRATEGY_EQUAL PBA_STRATEGY_EQUAL + PBA_STRATEGY_WEIGHTED = 1, /* Weight front half of TCs */ +#define PBA_STRATEGY_WEIGHTED PBA_STRATEGY_WEIGHTED +}; + /* Transmit Flow Control status */ #define IXGBE_TFCS_TXOFF 0x00000001 #define IXGBE_TFCS_TXOFF0 0x00000100 @@ -2615,6 +2636,9 @@ struct ixgbe_mac_operations { s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, bool *); + /* Packet Buffer Manipulation */ + void (*set_rxpba)(struct ixgbe_hw *, int, u32, int); + /* LED */ s32 (*led_on)(struct ixgbe_hw *, u32); s32 (*led_off)(struct ixgbe_hw *, u32); diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 4ed687be2fe..fa566ede765 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -876,6 +876,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = { .read_analog_reg8 = NULL, .write_analog_reg8 = NULL, .setup_link = &ixgbe_setup_mac_link_X540, + .set_rxpba = &ixgbe_set_rxpba_generic, .check_link = &ixgbe_check_mac_link_generic, .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic, .led_on = &ixgbe_led_on_generic, -- cgit v1.2.3-70-g09d2 From 72a32f1f3f68b7d95e7151b5f88831fb9906416e Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 07:25:58 +0000 Subject: ixgbe: consolidate MRQC and MTQC handling The MRQC and MTQC registers are configured in the main setup path but are also reconfigured in the DCB setup path. The DCB path fixes the DCB configuration by configuring the SECTXMINIFG gap which is required for DCB pause to operate correctly. This patch reduces the duplicate code and does all setup in ixgbe_setup_mtqc() and ixgbe_setup_mrqc(). Additionally, this removes the IXGBE_QDE. This write never set the WRITE bit in the register so the write was not actually doing anything. Also this was to clear the register but, it is never set and defaults to zero. If this is needed for SRIOV it should be added correctly in a follow up patch. But it's never been working so removing it here should be OK. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_82599.c | 57 ------------------------------------- drivers/net/ixgbe/ixgbe_main.c | 7 +++++ 2 files changed, 7 insertions(+), 57 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index befe8ad134c..ade98200288 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -318,62 +318,6 @@ static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) return 0; } -/** - * ixgbe_dcb_config_82599 - Configure general DCB parameters - * @hw: pointer to hardware structure - * - * Configure general DCB parameters. - */ -static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) -{ - u32 reg; - u32 q; - - /* Disable the Tx desc arbiter so that MTQC can be changed */ - reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS); - reg |= IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); - - /* Enable DCB for Rx with 8 TCs */ - reg = IXGBE_READ_REG(hw, IXGBE_MRQC); - switch (reg & IXGBE_MRQC_MRQE_MASK) { - case 0: - case IXGBE_MRQC_RT4TCEN: - /* RSS disabled cases */ - reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN; - break; - case IXGBE_MRQC_RSSEN: - case IXGBE_MRQC_RTRSS4TCEN: - /* RSS enabled cases */ - reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RTRSS8TCEN; - break; - default: - /* Unsupported value, assume stale data, overwrite no RSS */ - reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN; - } - IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg); - - /* Enable DCB for Tx with 8 TCs */ - reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ; - IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg); - - /* Disable drop for all queues */ - for (q = 0; q < 128; q++) - IXGBE_WRITE_REG(hw, IXGBE_QDE, q << IXGBE_QDE_IDX_SHIFT); - - /* Enable the Tx desc arbiter */ - reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS); - reg &= ~IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); - - /* Enable Security TX Buffer IFG for DCB */ - reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); - reg |= IXGBE_SECTX_DCB; - IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); - - return 0; -} - /** * ixgbe_dcb_hw_config_82599 - Configure and enable DCB * @hw: pointer to hardware structure @@ -388,7 +332,6 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type, u8 *prio_tc) { - ixgbe_dcb_config_82599(hw); ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, prio_type, prio_tc); ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fba1e323495..20467da4f90 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2816,6 +2816,7 @@ static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; u32 rttdcs; u32 mask; + u32 reg; if (hw->mac.type == ixgbe_mac_82598EB) return; @@ -2838,6 +2839,12 @@ static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) /* We enable 8 traffic classes, DCB only */ IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ)); + + /* Enable Security TX Buffer IFG for DCB */ + reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); + reg |= IXGBE_SECTX_DCB; + IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); + break; default: -- cgit v1.2.3-70-g09d2 From 8b1c0b24d9afd4a59a8aa9c778253bcff949395a Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 3 May 2011 02:26:48 +0000 Subject: ixgbe: configure minimal packet buffers to support TC ixgbe devices support different numbers of packet buffers either 8 or 4. Here we only allocate the minimal number of packet buffers required to implement the net_devices number of traffic classes. Fewer traffic classes allows for larger packet buffers in hardware. Also more Tx/Rx queues can be given to each traffic class. This patch is mostly about propagating the number of traffic classes through the init path. Specifically this adds the 4TC cases to the MRQC and MTQC setup routines. Also ixgbe_setup_tc() was sanitized to handle other traffic class value. Finally changing the number of packet buffers in the hardware requires the device to reinit. So this moves the reinit work from DCB into the main ixgbe_setup_tc() routine to consolidate the reset code. Now dcbnl_xxx ops call ixgbe_setup_tc() to configure packet buffers if needed. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 16 +-- drivers/net/ixgbe/ixgbe_main.c | 235 ++++++++++++++++++++++----------------- drivers/net/ixgbe/ixgbe_type.h | 1 + 3 files changed, 138 insertions(+), 114 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 293ff06ba16..b229febdbc1 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -125,9 +125,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) goto out; } - if (netif_running(netdev)) - netdev->netdev_ops->ndo_stop(netdev); - ixgbe_clear_interrupt_scheme(adapter); + adapter->flags |= IXGBE_FLAG_DCB_ENABLED; switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB: @@ -143,18 +141,12 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) break; } - adapter->flags |= IXGBE_FLAG_DCB_ENABLED; - if (!netdev_get_num_tc(netdev)) - ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS); + ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS); } else { /* Turn off DCB */ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) goto out; - if (netif_running(netdev)) - netdev->netdev_ops->ndo_stop(netdev); - ixgbe_clear_interrupt_scheme(adapter); - adapter->hw.fc.requested_mode = adapter->last_lfc_mode; adapter->temp_dcb_cfg.pfc_mode_enable = false; adapter->dcb_cfg.pfc_mode_enable = false; @@ -167,13 +159,9 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) default: break; } - ixgbe_setup_tc(netdev, 0); } - ixgbe_init_interrupt_scheme(adapter); - if (netif_running(netdev)) - netdev->netdev_ops->ndo_open(netdev); out: return err; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 20467da4f90..7e3850ab422 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2815,8 +2815,8 @@ static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u32 rttdcs; - u32 mask; u32 reg; + u8 tcs = netdev_get_num_tc(adapter->netdev); if (hw->mac.type == ixgbe_mac_82598EB) return; @@ -2827,28 +2827,27 @@ static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); /* set transmit pool layout */ - mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED); - switch (adapter->flags & mask) { - + switch (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { case (IXGBE_FLAG_SRIOV_ENABLED): IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF)); break; + default: + if (!tcs) + reg = IXGBE_MTQC_64Q_1PB; + else if (tcs <= 4) + reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_4TC_4TQ; + else + reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ; - case (IXGBE_FLAG_DCB_ENABLED): - /* We enable 8 traffic classes, DCB only */ - IXGBE_WRITE_REG(hw, IXGBE_MTQC, - (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ)); - - /* Enable Security TX Buffer IFG for DCB */ - reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); - reg |= IXGBE_SECTX_DCB; - IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); - - break; + IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg); - default: - IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); + /* Enable Security TX Buffer IFG for multiple pb */ + if (tcs) { + reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); + reg |= IXGBE_SECTX_DCB; + IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); + } break; } @@ -2939,7 +2938,7 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) u32 mrqc = 0, reta = 0; u32 rxcsum; int i, j; - int mask; + u8 tcs = netdev_get_num_tc(adapter->netdev); /* Fill out hash function seeds */ for (i = 0; i < 10; i++) @@ -2961,33 +2960,28 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) rxcsum |= IXGBE_RXCSUM_PCSD; IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) - mask = adapter->flags & IXGBE_FLAG_RSS_ENABLED; - else - mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED -#ifdef CONFIG_IXGBE_DCB - | IXGBE_FLAG_DCB_ENABLED -#endif - | IXGBE_FLAG_SRIOV_ENABLED - ); - - switch (mask) { -#ifdef CONFIG_IXGBE_DCB - case (IXGBE_FLAG_DCB_ENABLED | IXGBE_FLAG_RSS_ENABLED): - mrqc = IXGBE_MRQC_RTRSS8TCEN; - break; - case (IXGBE_FLAG_DCB_ENABLED): - mrqc = IXGBE_MRQC_RT8TCEN; - break; -#endif /* CONFIG_IXGBE_DCB */ - case (IXGBE_FLAG_RSS_ENABLED): + if (adapter->hw.mac.type == ixgbe_mac_82598EB && + (adapter->flags & IXGBE_FLAG_RSS_ENABLED)) { mrqc = IXGBE_MRQC_RSSEN; - break; - case (IXGBE_FLAG_SRIOV_ENABLED): - mrqc = IXGBE_MRQC_VMDQEN; - break; - default: - break; + } else { + int mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED + | IXGBE_FLAG_SRIOV_ENABLED); + + switch (mask) { + case (IXGBE_FLAG_RSS_ENABLED): + if (!tcs) + mrqc = IXGBE_MRQC_RSSEN; + else if (tcs <= 4) + mrqc = IXGBE_MRQC_RTRSS4TCEN; + else + mrqc = IXGBE_MRQC_RTRSS8TCEN; + break; + case (IXGBE_FLAG_SRIOV_ENABLED): + mrqc = IXGBE_MRQC_VMDQEN; + break; + default: + break; + } } /* Perform hash on these packet types */ @@ -4461,14 +4455,17 @@ static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) { bool ret = false; struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_DCB]; - int i, q; + int tcs = netdev_get_num_tc(adapter->netdev); + int max_q, i, q; - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || !tcs) return ret; + max_q = adapter->netdev->num_tx_queues / tcs; + f->indices = 0; - for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - q = min((int)num_online_cpus(), MAX_TRAFFIC_CLASS); + for (i = 0; i < tcs; i++) { + q = min((int)num_online_cpus(), max_q); f->indices += q; } @@ -4680,55 +4677,6 @@ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc, } } -#define IXGBE_MAX_Q_PER_TC (IXGBE_MAX_DCB_INDICES / MAX_TRAFFIC_CLASS) - -/* ixgbe_setup_tc - routine to configure net_device for multiple traffic - * classes. - * - * @netdev: net device to configure - * @tc: number of traffic classes to enable - */ -int ixgbe_setup_tc(struct net_device *dev, u8 tc) -{ - int i; - unsigned int q, offset = 0; - - if (!tc) { - netdev_reset_tc(dev); - } else { - struct ixgbe_adapter *adapter = netdev_priv(dev); - - /* Hardware supports up to 8 traffic classes */ - if (tc > MAX_TRAFFIC_CLASS || netdev_set_num_tc(dev, tc)) - return -EINVAL; - - /* Partition Tx queues evenly amongst traffic classes */ - for (i = 0; i < tc; i++) { - q = min((int)num_online_cpus(), IXGBE_MAX_Q_PER_TC); - netdev_set_prio_tc_map(dev, i, i); - netdev_set_tc_queue(dev, i, q, offset); - offset += q; - } - - /* This enables multiple traffic class support in the hardware - * which defaults to strict priority transmission by default. - * If traffic classes are already enabled perhaps through DCB - * code path then existing configuration will be used. - */ - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) && - dev->dcbnl_ops && dev->dcbnl_ops->setdcbx) { - struct ieee_ets ets = { - .prio_tc = {0, 1, 2, 3, 4, 5, 6, 7}, - }; - u8 mode = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE; - - dev->dcbnl_ops->setdcbx(dev, mode); - dev->dcbnl_ops->ieee_setets(dev, &ets); - } - } - return 0; -} - /** * ixgbe_cache_ring_dcb - Descriptor ring to register mapping for DCB * @adapter: board private structure to initialize @@ -4742,7 +4690,7 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) int i, j, k; u8 num_tcs = netdev_get_num_tc(dev); - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + if (!num_tcs) return false; for (i = 0, k = 0; i < num_tcs; i++) { @@ -7220,6 +7168,95 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, return stats; } +/* ixgbe_validate_rtr - verify 802.1Qp to Rx packet buffer mapping is valid. + * #adapter: pointer to ixgbe_adapter + * @tc: number of traffic classes currently enabled + * + * Configure a valid 802.1Qp to Rx packet buffer mapping ie confirm + * 802.1Q priority maps to a packet buffer that exists. + */ +static void ixgbe_validate_rtr(struct ixgbe_adapter *adapter, u8 tc) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 reg, rsave; + int i; + + /* 82598 have a static priority to TC mapping that can not + * be changed so no validation is needed. + */ + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC); + rsave = reg; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + u8 up2tc = reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT); + + /* If up2tc is out of bounds default to zero */ + if (up2tc > tc) + reg &= ~(0x7 << IXGBE_RTRUP2TC_UP_SHIFT); + } + + if (reg != rsave) + IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg); + + return; +} + + +/* ixgbe_setup_tc - routine to configure net_device for multiple traffic + * classes. + * + * @netdev: net device to configure + * @tc: number of traffic classes to enable + */ +int ixgbe_setup_tc(struct net_device *dev, u8 tc) +{ + unsigned int q, i, offset = 0; + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ixgbe_hw *hw = &adapter->hw; + int max_q = adapter->netdev->num_tx_queues / tc; + + /* If DCB is anabled do not remove traffic classes, multiple + * traffic classes are required to implement DCB + */ + if (!tc && (adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + return 0; + + /* Hardware supports up to 8 traffic classes */ + if (tc > MAX_TRAFFIC_CLASS || + (hw->mac.type == ixgbe_mac_82598EB && tc < MAX_TRAFFIC_CLASS)) + return -EINVAL; + + /* Hardware has to reinitialize queues and interrupts to + * match packet buffer alignment. Unfortunantly, the + * hardware is not flexible enough to do this dynamically. + */ + if (netif_running(dev)) + ixgbe_close(dev); + ixgbe_clear_interrupt_scheme(adapter); + + if (tc) + netdev_set_num_tc(dev, tc); + else + netdev_reset_tc(dev); + + /* Partition Tx queues evenly amongst traffic classes */ + for (i = 0; i < tc; i++) { + q = min((int)num_online_cpus(), max_q); + netdev_set_prio_tc_map(dev, i, i); + netdev_set_tc_queue(dev, i, q, offset); + offset += q; + } + + ixgbe_init_interrupt_scheme(adapter); + ixgbe_validate_rtr(adapter, tc); + if (netif_running(dev)) + ixgbe_open(dev); + + return 0; +} static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = ixgbe_open, @@ -7240,9 +7277,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw, .ndo_get_vf_config = ixgbe_ndo_get_vf_config, .ndo_get_stats64 = ixgbe_get_stats64, -#ifdef CONFIG_IXGBE_DCB .ndo_setup_tc = ixgbe_setup_tc, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index c0849a649d4..54550646c5c 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1881,6 +1881,7 @@ enum { #define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */ #define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */ #define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */ +#define IXGBE_MTQC_4TC_4TQ 0x8 /* 4 TC if RT_ENA or 4 TQ if VT_ENA */ /* Receive Descriptor bit definitions */ #define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */ -- cgit v1.2.3-70-g09d2 From e901acd6fa5538436e08e8a862dd2c080297f852 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 07:26:08 +0000 Subject: ixgbe: DCB use existing TX and RX queues The number of TX and RX queues allocated depends on the device type, the current features set, online CPUs, and various compile flags. To enable DCB with multiple queues and allow it to coexist with all the features currently implemented it has to setup a valid queue count. This is done at init time using the FDIR and RSS max queue counts and allowing each TC to allocate a queue per CPU. DCB will now use available queues up to (8 x TCs) this is somewhat arbitrary cap but allows DCB to use up to 64 queues. Its easy to increase this later if that is needed. This is prep work to enable Flow Director with DCB. After this DCB can easily coexist with existing features and no longer needs its own DCB feature ring. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 2 - drivers/net/ixgbe/ixgbe_main.c | 107 +++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 60 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index e467b20ed1f..d5674fc8bc0 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -244,7 +244,6 @@ struct ixgbe_ring { enum ixgbe_ring_f_enum { RING_F_NONE = 0, - RING_F_DCB, RING_F_VMDQ, /* SR-IOV uses the same ring feature */ RING_F_RSS, RING_F_FDIR, @@ -255,7 +254,6 @@ enum ixgbe_ring_f_enum { RING_F_ARRAY_SIZE /* must be last in enum set */ }; -#define IXGBE_MAX_DCB_INDICES 64 #define IXGBE_MAX_RSS_INDICES 16 #define IXGBE_MAX_VMDQ_INDICES 64 #define IXGBE_MAX_FDIR_INDICES 64 diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 7e3850ab422..3a88fb6e32e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4417,72 +4417,72 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) return false; - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { -#ifdef CONFIG_IXGBE_DCB - int tc; - struct net_device *dev = adapter->netdev; + f->indices = min((int)num_online_cpus(), f->indices); - tc = netdev_get_prio_tc_map(dev, adapter->fcoe.up); - f->indices = dev->tc_to_txq[tc].count; - f->mask = dev->tc_to_txq[tc].offset; -#endif - } else { - f->indices = min((int)num_online_cpus(), f->indices); - - adapter->num_rx_queues = 1; - adapter->num_tx_queues = 1; + adapter->num_rx_queues = 1; + adapter->num_tx_queues = 1; - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - e_info(probe, "FCoE enabled with RSS\n"); - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) - ixgbe_set_fdir_queues(adapter); - else - ixgbe_set_rss_queues(adapter); - } - /* adding FCoE rx rings to the end */ - f->mask = adapter->num_rx_queues; - adapter->num_rx_queues += f->indices; - adapter->num_tx_queues += f->indices; + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { + e_info(probe, "FCoE enabled with RSS\n"); + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || + (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + ixgbe_set_fdir_queues(adapter); + else + ixgbe_set_rss_queues(adapter); } + /* adding FCoE rx rings to the end */ + f->mask = adapter->num_rx_queues; + adapter->num_rx_queues += f->indices; + adapter->num_tx_queues += f->indices; return true; } #endif /* IXGBE_FCOE */ +/* Artificial max queue cap per traffic class in DCB mode */ +#define DCB_QUEUE_CAP 8 + #ifdef CONFIG_IXGBE_DCB static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) { - bool ret = false; - struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_DCB]; - int tcs = netdev_get_num_tc(adapter->netdev); - int max_q, i, q; + int per_tc_q, q, i, offset = 0; + struct net_device *dev = adapter->netdev; + int tcs = netdev_get_num_tc(dev); - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || !tcs) - return ret; + if (!tcs) + return false; - max_q = adapter->netdev->num_tx_queues / tcs; + /* Map queue offset and counts onto allocated tx queues */ + per_tc_q = min(dev->num_tx_queues / tcs, (unsigned int)DCB_QUEUE_CAP); + q = min((int)num_online_cpus(), per_tc_q); - f->indices = 0; for (i = 0; i < tcs; i++) { - q = min((int)num_online_cpus(), max_q); - f->indices += q; + netdev_set_prio_tc_map(dev, i, i); + netdev_set_tc_queue(dev, i, q, offset); + offset += q; } - f->mask = 0x7 << 3; - adapter->num_rx_queues = f->indices; - adapter->num_tx_queues = f->indices; - ret = true; + adapter->num_tx_queues = q * tcs; + adapter->num_rx_queues = q * tcs; #ifdef IXGBE_FCOE - /* FCoE enabled queues require special configuration done through - * configure_fcoe() and others. Here we map FCoE indices onto the - * DCB queue pairs allowing FCoE to own configuration later. + /* FCoE enabled queues require special configuration indexed + * by feature specific indices and mask. Here we map FCoE + * indices onto the DCB queue pairs allowing FCoE to own + * configuration later. */ - ixgbe_set_fcoe_queues(adapter); + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + int tc; + struct ixgbe_ring_feature *f = + &adapter->ring_feature[RING_F_FCOE]; + + tc = netdev_get_prio_tc_map(dev, adapter->fcoe.up); + f->indices = dev->tc_to_txq[tc].count; + f->mask = dev->tc_to_txq[tc].offset; + } #endif - return ret; + return true; } #endif @@ -5172,7 +5172,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus()); adapter->ring_feature[RING_F_RSS].indices = rss; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; - adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES; switch (hw->mac.type) { case ixgbe_mac_82598EB: if (hw->device_id == IXGBE_DEV_ID_82598AT) @@ -7213,10 +7212,8 @@ static void ixgbe_validate_rtr(struct ixgbe_adapter *adapter, u8 tc) */ int ixgbe_setup_tc(struct net_device *dev, u8 tc) { - unsigned int q, i, offset = 0; struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_hw *hw = &adapter->hw; - int max_q = adapter->netdev->num_tx_queues / tc; /* If DCB is anabled do not remove traffic classes, multiple * traffic classes are required to implement DCB @@ -7242,14 +7239,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) else netdev_reset_tc(dev); - /* Partition Tx queues evenly amongst traffic classes */ - for (i = 0; i < tc; i++) { - q = min((int)num_online_cpus(), max_q); - netdev_set_prio_tc_map(dev, i, i); - netdev_set_tc_queue(dev, i, q, offset); - offset += q; - } - ixgbe_init_interrupt_scheme(adapter); ixgbe_validate_rtr(adapter, tc); if (netif_running(dev)) @@ -7436,14 +7425,16 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, pci_set_master(pdev); pci_save_state(pdev); +#ifdef CONFIG_IXGBE_DCB + indices *= MAX_TRAFFIC_CLASS; +#endif + if (ii->mac == ixgbe_mac_82598EB) indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES); else indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES); -#if defined(CONFIG_DCB) - indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES); -#elif defined(IXGBE_FCOE) +#ifdef IXGBE_FCOE indices += min_t(unsigned int, num_possible_cpus(), IXGBE_MAX_FCOE_INDICES); #endif -- cgit v1.2.3-70-g09d2 From aba70d5e6c1c188fe45c1a782060440b6c2ea759 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 07:26:14 +0000 Subject: ixgbe: DCB 82598 devices, tx_idx and rx_idx swapped The tx_idx and rx_idx values are swapped on 82598 devices with DCB enabled. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 3a88fb6e32e..f829d361452 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4636,8 +4636,8 @@ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc, switch (hw->mac.type) { case ixgbe_mac_82598EB: - *tx = tc << 3; - *rx = tc << 2; + *tx = tc << 2; + *rx = tc << 3; break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: -- cgit v1.2.3-70-g09d2 From 86b4db3bcce714d6bdd8c056158821301624bf00 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 07:26:19 +0000 Subject: ixgbe: setup redirection table for multiple packet buffers Setup RSS redirection table to be compatible with multiple packet buffers. Currently, this works on 82599 devices because the RSS redirection index is masked by the number of queues per packet buffer. This sets the cap on the RSS table to maxq. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f829d361452..e81dc853922 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2939,6 +2939,10 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) u32 rxcsum; int i, j; u8 tcs = netdev_get_num_tc(adapter->netdev); + int maxq = adapter->ring_feature[RING_F_RSS].indices; + + if (tcs) + maxq = min(maxq, adapter->num_tx_queues / tcs); /* Fill out hash function seeds */ for (i = 0; i < 10; i++) @@ -2946,7 +2950,7 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) /* Fill out redirection table */ for (i = 0, j = 0; i < 128; i++, j++) { - if (j == adapter->ring_feature[RING_F_RSS].indices) + if (j == maxq) j = 0; /* reta = 4-byte sliding window of * 0x00..(indices-1)(indices-1)00..etc. */ -- cgit v1.2.3-70-g09d2 From 6f70f6acc7321f9f6501157b29d2db8c475cf3b2 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 07:26:25 +0000 Subject: ixgbe: fix bit mask for DCB version This bit mask is wrong DCBX_HOST is always set. It was missed up until now because lldpad reprograms the device on a link event. However this is still wrong and it is best not to be mis-configured for some time immediately following ixgbe_up(). Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e81dc853922..5caf42a3a7f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3745,7 +3745,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); /* reconfigure the hardware */ - if (adapter->dcbx_cap & (DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE)) { + if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE) { #ifdef CONFIG_FCOE if (adapter->netdev->features & NETIF_F_FCOE_MTU) max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); -- cgit v1.2.3-70-g09d2 From b1bbdb206a52b7eb13c2e57ee794b90618f61002 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 07:26:30 +0000 Subject: ixgbe: DCB and perfect filters can coexist Now flow directors perfect filters features can coexist with DCB. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index b229febdbc1..08c7aebe99f 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -135,7 +135,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) case ixgbe_mac_82599EB: case ixgbe_mac_X540: adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; break; default: break; -- cgit v1.2.3-70-g09d2 From fb5475ff7f2e80e920a393d18a43b64124a30270 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 26 Apr 2011 07:26:36 +0000 Subject: ixgbe: DCB, remove unneeded ixgbe_dcb_txq_to_tc() routine The ixgbe_dcb_txq_to_tc() routine was used to map TX rings to a DCB traffic class. Now that a tx_ring has a DCB traffic class associated with it this routine is no longer needed. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 58 +----------------------------------------- 1 file changed, 1 insertion(+), 57 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5caf42a3a7f..295ab6d8923 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -665,62 +665,6 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, /* tx_buffer_info must be completely set up in the transmit path */ } -/** - * ixgbe_dcb_txq_to_tc - convert a reg index to a traffic class - * @adapter: driver private struct - * @index: reg idx of queue to query (0-127) - * - * Helper function to determine the traffic index for a particular - * register index. - * - * Returns : a tc index for use in range 0-7, or 0-3 - */ -static u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx) -{ - int tc = -1; - int dcb_i = netdev_get_num_tc(adapter->netdev); - - /* if DCB is not enabled the queues have no TC */ - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - return tc; - - /* check valid range */ - if (reg_idx >= adapter->hw.mac.max_tx_queues) - return tc; - - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - tc = reg_idx >> 2; - break; - default: - if (dcb_i != 4 && dcb_i != 8) - break; - - /* if VMDq is enabled the lowest order bits determine TC */ - if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED | - IXGBE_FLAG_VMDQ_ENABLED)) { - tc = reg_idx & (dcb_i - 1); - break; - } - - /* - * Convert the reg_idx into the correct TC. This bitmask - * targets the last full 32 ring traffic class and assigns - * it a value of 1. From there the rest of the rings are - * based on shifting the mask further up to include the - * reg_idx / 16 and then reg_idx / 8. It assumes dcB_i - * will only ever be 8 or 4 and that reg_idx will never - * be greater then 128. The code without the power of 2 - * optimizations would be: - * (((reg_idx % 32) + 32) * dcb_i) >> (9 - reg_idx / 32) - */ - tc = ((reg_idx & 0X1F) + 0x20) * dcb_i; - tc >>= 9 - (reg_idx >> 5); - } - - return tc; -} - static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; @@ -766,7 +710,7 @@ static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) /* disarm tx queues that have received xoff frames */ for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; - u32 tc = ixgbe_dcb_txq_to_tc(adapter, tx_ring->reg_idx); + u8 tc = tx_ring->dcb_tc; if (xoff[tc]) clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state); -- cgit v1.2.3-70-g09d2 From 9612de92e023bff0d1cd5725ee65293accc70c56 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 7 May 2011 07:40:20 +0000 Subject: ixgbe: add support for Dell CEM This patch adds support for Dell CEM (Comprehensive Embedded Management)). This consists of informing the management firmware of the driver version during probe on 82599 and X540 HW. Signed-off-by: Emil Tantilov Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 1 + drivers/net/ixgbe/ixgbe_82599.c | 1 + drivers/net/ixgbe/ixgbe_common.c | 174 +++++++++++++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_common.h | 2 + drivers/net/ixgbe/ixgbe_main.c | 4 + drivers/net/ixgbe/ixgbe_type.h | 46 +++++++++++ drivers/net/ixgbe/ixgbe_x540.c | 1 + 7 files changed, 229 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index bb417d746a1..0d4e3826449 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1316,6 +1316,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .clear_vfta = &ixgbe_clear_vfta_82598, .set_vfta = &ixgbe_set_vfta_82598, .fc_enable = &ixgbe_fc_enable_82598, + .set_fw_drv_ver = NULL, .acquire_swfw_sync = &ixgbe_acquire_swfw_sync, .release_swfw_sync = &ixgbe_release_swfw_sync, }; diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 324a5051f81..4a6826bf933 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -2126,6 +2126,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .clear_vfta = &ixgbe_clear_vfta_generic, .set_vfta = &ixgbe_set_vfta_generic, .fc_enable = &ixgbe_fc_enable_generic, + .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, .init_uta_tables = &ixgbe_init_uta_tables_generic, .setup_sfp = &ixgbe_setup_sfp_modules_82599, .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index cc2a4a1528e..777051f54e5 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -3333,3 +3333,177 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0); } } + +/** + * ixgbe_calculate_checksum - Calculate checksum for buffer + * @buffer: pointer to EEPROM + * @length: size of EEPROM to calculate a checksum for + * Calculates the checksum for some buffer on a specified length. The + * checksum calculated is returned. + **/ +static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) +{ + u32 i; + u8 sum = 0; + + if (!buffer) + return 0; + + for (i = 0; i < length; i++) + sum += buffer[i]; + + return (u8) (0 - sum); +} + +/** + * ixgbe_host_interface_command - Issue command to manageability block + * @hw: pointer to the HW structure + * @buffer: contains the command to write and where the return status will + * be placed + * @lenght: lenght of buffer, must be multiple of 4 bytes + * + * Communicates with the manageability block. On success return 0 + * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. + **/ +static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u8 *buffer, + u32 length) +{ + u32 hicr, i; + u32 hdr_size = sizeof(struct ixgbe_hic_hdr); + u8 buf_len, dword_len; + + s32 ret_val = 0; + + if (length == 0 || length & 0x3 || + length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { + hw_dbg(hw, "Buffer length failure.\n"); + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto out; + } + + /* Check that the host interface is enabled. */ + hicr = IXGBE_READ_REG(hw, IXGBE_HICR); + if ((hicr & IXGBE_HICR_EN) == 0) { + hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n"); + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto out; + } + + /* Calculate length in DWORDs */ + dword_len = length >> 2; + + /* + * The device driver writes the relevant command block + * into the ram area. + */ + for (i = 0; i < dword_len; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, + i, *((u32 *)buffer + i)); + + /* Setting this bit tells the ARC that a new command is pending. */ + IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); + + for (i = 0; i < IXGBE_HI_COMMAND_TIMEOUT; i++) { + hicr = IXGBE_READ_REG(hw, IXGBE_HICR); + if (!(hicr & IXGBE_HICR_C)) + break; + usleep_range(1000, 2000); + } + + /* Check command successful completion. */ + if (i == IXGBE_HI_COMMAND_TIMEOUT || + (!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) { + hw_dbg(hw, "Command has failed with no status valid.\n"); + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto out; + } + + /* Calculate length in DWORDs */ + dword_len = hdr_size >> 2; + + /* first pull in the header so we know the buffer length */ + for (i = 0; i < dword_len; i++) + *((u32 *)buffer + i) = + IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i); + + /* If there is any thing in data position pull it in */ + buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; + if (buf_len == 0) + goto out; + + if (length < (buf_len + hdr_size)) { + hw_dbg(hw, "Buffer not large enough for reply message.\n"); + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + goto out; + } + + /* Calculate length in DWORDs, add one for odd lengths */ + dword_len = (buf_len + 1) >> 2; + + /* Pull in the rest of the buffer (i is where we left off)*/ + for (; i < buf_len; i++) + *((u32 *)buffer + i) = + IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i); + +out: + return ret_val; +} + +/** + * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware + * @hw: pointer to the HW structure + * @maj: driver version major number + * @min: driver version minor number + * @build: driver version build number + * @sub: driver version sub build number + * + * Sends driver version number to firmware through the manageability + * block. On success return 0 + * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring + * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + **/ +s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 sub) +{ + struct ixgbe_hic_drv_info fw_cmd; + int i; + s32 ret_val = 0; + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM) != 0) { + ret_val = IXGBE_ERR_SWFW_SYNC; + goto out; + } + + fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; + fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; + fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; + fw_cmd.port_num = (u8)hw->bus.func; + fw_cmd.ver_maj = maj; + fw_cmd.ver_min = min; + fw_cmd.ver_build = build; + fw_cmd.ver_sub = sub; + fw_cmd.hdr.checksum = 0; + fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd, + (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); + fw_cmd.pad = 0; + fw_cmd.pad2 = 0; + + for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { + ret_val = ixgbe_host_interface_command(hw, (u8 *)&fw_cmd, + sizeof(fw_cmd)); + if (ret_val != 0) + continue; + + if (fw_cmd.hdr.cmd_or_resp.ret_status == + FW_CEM_RESP_STATUS_SUCCESS) + ret_val = 0; + else + ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + + break; + } + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); +out: + return ret_val; +} diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 32a454fc67c..f24fd64a4c4 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -99,6 +99,8 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf); void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); +s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, + u8 build, u8 ver); void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom, int strategy); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 295ab6d8923..4cd66ae70cc 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -7674,6 +7674,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ixgbe_vf_configuration(pdev, (i | 0x10000000)); } + /* Inform firmware of driver version */ + if (hw->mac.ops.set_fw_drv_ver) + hw->mac.ops.set_fw_drv_ver(hw, MAJ, MIN, BUILD, KFIX); + /* add san mac addr to netdev */ ixgbe_add_sanmac_netdev(netdev); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 54550646c5c..9a499a61d14 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -707,6 +707,13 @@ #define IXGBE_HFDR 0x15FE8 #define IXGBE_FLEX_MNG 0x15800 /* 0x15800 - 0x15EFC */ +#define IXGBE_HICR_EN 0x01 /* Enable bit - RO */ +/* Driver sets this bit when done to put command in RAM */ +#define IXGBE_HICR_C 0x02 +#define IXGBE_HICR_SV 0x04 /* Status Validity */ +#define IXGBE_HICR_FW_RESET_ENABLE 0x40 +#define IXGBE_HICR_FW_RESET 0x80 + /* PCI-E registers */ #define IXGBE_GCR 0x11000 #define IXGBE_GTV 0x11004 @@ -2124,6 +2131,41 @@ enum ixgbe_fdir_pballoc_type { #define IXGBE_FDIR_INIT_DONE_POLL 10 #define IXGBE_FDIRCMD_CMD_POLL 10 +/* Manageablility Host Interface defines */ +#define IXGBE_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */ +#define IXGBE_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */ +#define IXGBE_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */ + +/* CEM Support */ +#define FW_CEM_HDR_LEN 0x4 +#define FW_CEM_CMD_DRIVER_INFO 0xDD +#define FW_CEM_CMD_DRIVER_INFO_LEN 0x5 +#define FW_CEM_CMD_RESERVED 0X0 +#define FW_CEM_MAX_RETRIES 3 +#define FW_CEM_RESP_STATUS_SUCCESS 0x1 + +/* Host Interface Command Structures */ +struct ixgbe_hic_hdr { + u8 cmd; + u8 buf_len; + union { + u8 cmd_resv; + u8 ret_status; + } cmd_or_resp; + u8 checksum; +}; + +struct ixgbe_hic_drv_info { + struct ixgbe_hic_hdr hdr; + u8 port_num; + u8 ver_sub; + u8 ver_build; + u8 ver_min; + u8 ver_maj; + u8 pad; /* end spacing to ensure length is mult. of dword */ + u16 pad2; /* end spacing to ensure length is mult. of dword2 */ +}; + /* Transmit Descriptor - Advanced */ union ixgbe_adv_tx_desc { struct { @@ -2663,6 +2705,9 @@ struct ixgbe_mac_operations { /* Flow Control */ s32 (*fc_enable)(struct ixgbe_hw *, s32); + + /* Manageability interface */ + s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8); }; struct ixgbe_phy_operations { @@ -2832,6 +2877,7 @@ struct ixgbe_info { #define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 #define IXGBE_ERR_PBA_SECTION -31 #define IXGBE_ERR_INVALID_ARGUMENT -32 +#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #endif /* _IXGBE_TYPE_H_ */ diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index fa566ede765..bec30ed91ad 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -894,6 +894,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = { .clear_vfta = &ixgbe_clear_vfta_generic, .set_vfta = &ixgbe_set_vfta_generic, .fc_enable = &ixgbe_fc_enable_generic, + .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, .init_uta_tables = &ixgbe_init_uta_tables_generic, .setup_sfp = NULL, .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, -- cgit v1.2.3-70-g09d2 From dadbe85ac47f180fa1e3ef93b276ab7938b1a98b Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Wed, 11 May 2011 05:41:46 +0000 Subject: ixgbe: setup per CPU PCI pool for FCoE DDP Currently single PCI pool used across all CPUs and that doesn't scales up as number of CPU increases, so this patch adds per CPU PCI pool to setup udl and that aligns well from FCoE stack as that already has per CPU exch locking. Adds per CPU PCI alloc setup and free in ixgbe_fcoe_ddp_pools_alloc and ixgbe_fcoe_ddp_pools_free, use CPU specific pool during DDP setup. Re-arranged ixgbe_fcoe struct to have fewer holes along with adding pools ptr using pahole. Signed-off-by: Vasu Dev Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_fcoe.c | 105 +++++++++++++++++++++++++++++------------ drivers/net/ixgbe/ixgbe_fcoe.h | 13 ++--- 2 files changed, 82 insertions(+), 36 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 05920726e82..f5f39edb86a 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -128,7 +128,11 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) if (ddp->sgl) pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, DMA_FROM_DEVICE); - pci_pool_free(fcoe->pool, ddp->udl, ddp->udp); + if (ddp->pool) { + pci_pool_free(ddp->pool, ddp->udl, ddp->udp); + ddp->pool = NULL; + } + ixgbe_fcoe_clear_ddp(ddp); out_ddp_put: @@ -163,6 +167,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, unsigned int thislen = 0; u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; dma_addr_t addr = 0; + struct pci_pool *pool; if (!netdev || !sgl) return 0; @@ -199,12 +204,14 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, return 0; } - /* alloc the udl from our ddp pool */ - ddp->udl = pci_pool_alloc(fcoe->pool, GFP_ATOMIC, &ddp->udp); + /* alloc the udl from per cpu ddp pool */ + pool = *per_cpu_ptr(fcoe->pool, get_cpu()); + ddp->udl = pci_pool_alloc(pool, GFP_ATOMIC, &ddp->udp); if (!ddp->udl) { e_err(drv, "failed allocated ddp context\n"); goto out_noddp_unmap; } + ddp->pool = pool; ddp->sgl = sgl; ddp->sgc = sgc; @@ -268,6 +275,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, j++; lastsize = 1; } + put_cpu(); fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); @@ -311,11 +319,12 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, return 1; out_noddp_free: - pci_pool_free(fcoe->pool, ddp->udl, ddp->udp); + pci_pool_free(pool, ddp->udl, ddp->udp); ixgbe_fcoe_clear_ddp(ddp); out_noddp_unmap: pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE); + put_cpu(); return 0; } @@ -585,6 +594,46 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, return skb_is_gso(skb); } +static void ixgbe_fcoe_ddp_pools_free(struct ixgbe_fcoe *fcoe) +{ + unsigned int cpu; + struct pci_pool **pool; + + for_each_possible_cpu(cpu) { + pool = per_cpu_ptr(fcoe->pool, cpu); + if (*pool) + pci_pool_destroy(*pool); + } + free_percpu(fcoe->pool); + fcoe->pool = NULL; +} + +static void ixgbe_fcoe_ddp_pools_alloc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_fcoe *fcoe = &adapter->fcoe; + unsigned int cpu; + struct pci_pool **pool; + char pool_name[32]; + + fcoe->pool = alloc_percpu(struct pci_pool *); + if (!fcoe->pool) + return; + + /* allocate pci pool for each cpu */ + for_each_possible_cpu(cpu) { + snprintf(pool_name, 32, "ixgbe_fcoe_ddp_%d", cpu); + pool = per_cpu_ptr(fcoe->pool, cpu); + *pool = pci_pool_create(pool_name, + adapter->pdev, IXGBE_FCPTR_MAX, + IXGBE_FCPTR_ALIGN, PAGE_SIZE); + if (!*pool) { + e_err(drv, "failed to alloc DDP pool on cpu:%d\n", cpu); + ixgbe_fcoe_ddp_pools_free(fcoe); + return; + } + } +} + /** * ixgbe_configure_fcoe - configures registers for fcoe at start * @adapter: ptr to ixgbe adapter @@ -604,22 +653,20 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) u32 up2tc; #endif - /* create the pool for ddp if not created yet */ if (!fcoe->pool) { - /* allocate ddp pool */ - fcoe->pool = pci_pool_create("ixgbe_fcoe_ddp", - adapter->pdev, IXGBE_FCPTR_MAX, - IXGBE_FCPTR_ALIGN, PAGE_SIZE); - if (!fcoe->pool) - e_err(drv, "failed to allocated FCoE DDP pool\n"); - spin_lock_init(&fcoe->lock); + ixgbe_fcoe_ddp_pools_alloc(adapter); + if (!fcoe->pool) { + e_err(drv, "failed to alloc percpu fcoe DDP pools\n"); + return; + } + /* Extra buffer to be shared by all DDPs for HW work around */ fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); if (fcoe->extra_ddp_buffer == NULL) { e_err(drv, "failed to allocated extra DDP buffer\n"); - goto out_extra_ddp_buffer_alloc; + goto out_ddp_pools; } fcoe->extra_ddp_buffer_dma = @@ -630,7 +677,7 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) if (dma_mapping_error(&adapter->pdev->dev, fcoe->extra_ddp_buffer_dma)) { e_err(drv, "failed to map extra DDP buffer\n"); - goto out_extra_ddp_buffer_dma; + goto out_extra_ddp_buffer; } } @@ -684,11 +731,10 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) return; -out_extra_ddp_buffer_dma: +out_extra_ddp_buffer: kfree(fcoe->extra_ddp_buffer); -out_extra_ddp_buffer_alloc: - pci_pool_destroy(fcoe->pool); - fcoe->pool = NULL; +out_ddp_pools: + ixgbe_fcoe_ddp_pools_free(fcoe); } /** @@ -704,18 +750,17 @@ void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter) int i; struct ixgbe_fcoe *fcoe = &adapter->fcoe; - /* release ddp resource */ - if (fcoe->pool) { - for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) - ixgbe_fcoe_ddp_put(adapter->netdev, i); - dma_unmap_single(&adapter->pdev->dev, - fcoe->extra_ddp_buffer_dma, - IXGBE_FCBUFF_MIN, - DMA_FROM_DEVICE); - kfree(fcoe->extra_ddp_buffer); - pci_pool_destroy(fcoe->pool); - fcoe->pool = NULL; - } + if (!fcoe->pool) + return; + + for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) + ixgbe_fcoe_ddp_put(adapter->netdev, i); + dma_unmap_single(&adapter->pdev->dev, + fcoe->extra_ddp_buffer_dma, + IXGBE_FCBUFF_MIN, + DMA_FROM_DEVICE); + kfree(fcoe->extra_ddp_buffer); + ixgbe_fcoe_ddp_pools_free(fcoe); } /** diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index 5a650a4ace6..d876e7ac225 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -62,20 +62,21 @@ struct ixgbe_fcoe_ddp { struct scatterlist *sgl; dma_addr_t udp; u64 *udl; + struct pci_pool *pool; }; struct ixgbe_fcoe { -#ifdef CONFIG_IXGBE_DCB - u8 tc; - u8 up; -#endif - unsigned long mode; + struct pci_pool **pool; atomic_t refcnt; spinlock_t lock; - struct pci_pool *pool; struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; unsigned char *extra_ddp_buffer; dma_addr_t extra_ddp_buffer_dma; + unsigned long mode; +#ifdef CONFIG_IXGBE_DCB + u8 tc; + u8 up; +#endif }; #endif /* _IXGBE_FCOE_H */ -- cgit v1.2.3-70-g09d2 From 43d620c82985b19008d87a437b4cf83f356264f7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Jun 2011 19:08:06 +0000 Subject: drivers/net: Remove casts of void * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unnecessary casts of void * clutter the code. These are the remainder casts after several specific patches to remove netdev_priv and dev_priv. Done via coccinelle script (and a little editing): $ cat cast_void_pointer.cocci @@ type T; T *pt; void *pv; @@ - pt = (T *)pv; + pt = pv; Signed-off-by: Joe Perches Acked-by: Sjur Brændeland Acked-By: Chris Snook Acked-by: Jon Mason Acked-by: Geert Uytterhoeven Acked-by: David Dillow Signed-off-by: David S. Miller --- drivers/net/a2065.c | 11 +++------- drivers/net/appletalk/ltpc.c | 8 +++---- drivers/net/atl1e/atl1e_main.c | 5 ++--- drivers/net/atlx/atl2.c | 3 +-- drivers/net/benet/be_cmds.c | 3 +-- drivers/net/benet/be_ethtool.c | 4 ++-- drivers/net/bna/bfa_cee.c | 2 +- drivers/net/bna/cna.h | 2 +- drivers/net/caif/caif_shmcore.c | 2 +- drivers/net/cnic.c | 4 ++-- drivers/net/cxgb3/cxgb3_offload.c | 2 +- drivers/net/davinci_cpdma.c | 2 +- drivers/net/declance.c | 38 ++++++++++++++++++-------------- drivers/net/depca.c | 4 ++-- drivers/net/dl2k.c | 4 ++-- drivers/net/ehea/ehea_qmr.c | 2 +- drivers/net/epic100.c | 4 ++-- drivers/net/fealnx.c | 4 ++-- drivers/net/gianfar.c | 4 ++-- drivers/net/hamachi.c | 4 ++-- drivers/net/macmace.c | 2 +- drivers/net/mlx4/en_rx.c | 2 +- drivers/net/mlx4/en_tx.c | 5 ++--- drivers/net/netxen/netxen_nic_ctx.c | 16 +++++++------- drivers/net/pxa168_eth.c | 2 +- drivers/net/qla3xxx.c | 5 ++--- drivers/net/qlcnic/qlcnic_ctx.c | 26 +++++++++++----------- drivers/net/qlcnic/qlcnic_ethtool.c | 2 +- drivers/net/qlcnic/qlcnic_hw.c | 3 +-- drivers/net/qlcnic/qlcnic_main.c | 2 +- drivers/net/qlge/qlge_main.c | 4 ++-- drivers/net/s2io.c | 18 ++++++--------- drivers/net/sfc/siena.c | 2 +- drivers/net/sis900.c | 4 ++-- drivers/net/tokenring/madgemc.c | 2 +- drivers/net/typhoon.c | 2 +- drivers/net/vxge/vxge-config.c | 44 +++++++++++++------------------------ drivers/net/vxge/vxge-traffic.c | 6 ++--- drivers/net/wan/pc300_tty.c | 2 +- drivers/net/xilinx_emaclite.c | 4 ++-- drivers/net/yellowfin.c | 6 ++--- 41 files changed, 124 insertions(+), 147 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index deaa8bc16cf..25ea98aacf3 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -421,16 +421,11 @@ static int lance_tx (struct net_device *dev) static irqreturn_t lance_interrupt (int irq, void *dev_id) { - struct net_device *dev; - struct lance_private *lp; - volatile struct lance_regs *ll; + struct net_device *dev = dev_id; + struct lance_private *lp = netdev_priv(dev); + volatile struct lance_regs *ll = lp->ll; int csr0; - dev = (struct net_device *) dev_id; - - lp = netdev_priv(dev); - ll = lp->ll; - ll->rap = LE_CSR0; /* LANCE Controller Status */ csr0 = ll->rdp; diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index e69eead12ec..34ffb542262 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -652,9 +652,9 @@ static int do_write(struct net_device *dev, void *cbuf, int cbuflen, int ret; if(i) { - qels[i].cbuf = (unsigned char *) cbuf; + qels[i].cbuf = cbuf; qels[i].cbuflen = cbuflen; - qels[i].dbuf = (unsigned char *) dbuf; + qels[i].dbuf = dbuf; qels[i].dbuflen = dbuflen; qels[i].QWrite = 1; qels[i].mailbox = i; /* this should be initted rather */ @@ -676,9 +676,9 @@ static int do_read(struct net_device *dev, void *cbuf, int cbuflen, int ret; if(i) { - qels[i].cbuf = (unsigned char *) cbuf; + qels[i].cbuf = cbuf; qels[i].cbuflen = cbuflen; - qels[i].dbuf = (unsigned char *) dbuf; + qels[i].dbuf = dbuf; qels[i].dbuflen = dbuflen; qels[i].QWrite = 0; qels[i].mailbox = i; /* this should be initted rather */ diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 86a91228313..c3c5db13cf2 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -800,8 +800,7 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter) /* Init TPD Ring */ tx_ring->dma = roundup(adapter->ring_dma, 8); offset = tx_ring->dma - adapter->ring_dma; - tx_ring->desc = (struct atl1e_tpd_desc *) - (adapter->ring_vir_addr + offset); + tx_ring->desc = adapter->ring_vir_addr + offset; size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count); tx_ring->tx_buffer = kzalloc(size, GFP_KERNEL); if (tx_ring->tx_buffer == NULL) { @@ -827,7 +826,7 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter) /* Init CMB dma address */ tx_ring->cmb_dma = adapter->ring_dma + offset; - tx_ring->cmb = (u32 *)(adapter->ring_vir_addr + offset); + tx_ring->cmb = adapter->ring_vir_addr + offset; offset += sizeof(u32); for (i = 0; i < adapter->num_rx_queues; i++) { diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 16249e9b6b9..24e15926cee 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -311,8 +311,7 @@ static s32 atl2_setup_ring_resources(struct atl2_adapter *adapter) adapter->txd_dma = adapter->ring_dma ; offset = (adapter->txd_dma & 0x7) ? (8 - (adapter->txd_dma & 0x7)) : 0; adapter->txd_dma += offset; - adapter->txd_ring = (struct tx_pkt_header *) (adapter->ring_vir_addr + - offset); + adapter->txd_ring = adapter->ring_vir_addr + offset; /* Init TXS Ring */ adapter->txs_dma = adapter->txd_dma + adapter->txd_ring_size; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 0c12c2d4532..30719f591fb 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -2334,8 +2334,7 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter) status = be_mbox_notify_wait(adapter); if (!status) { - attribs = (struct mgmt_controller_attrib *)( attribs_cmd.va + - sizeof(struct be_cmd_resp_hdr)); + attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr); adapter->hba_port_num = attribs->hba_attribs.phy_port; } diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 84e03a74786..30c1386027f 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -408,7 +408,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) } status = be_cmd_get_phy_info(adapter, &phy_cmd); if (!status) { - resp = (struct be_cmd_resp_get_phy_info *) phy_cmd.va; + resp = phy_cmd.va; intf_type = le16_to_cpu(resp->interface_type); switch (intf_type) { @@ -712,7 +712,7 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd); if (!status) { - resp = (struct be_cmd_resp_seeprom_read *) eeprom_cmd.va; + resp = eeprom_cmd.va; memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len); } dma_free_coherent(&adapter->pdev->dev, eeprom_cmd.size, eeprom_cmd.va, diff --git a/drivers/net/bna/bfa_cee.c b/drivers/net/bna/bfa_cee.c index f7b789a3b21..dcfbf08bcf4 100644 --- a/drivers/net/bna/bfa_cee.c +++ b/drivers/net/bna/bfa_cee.c @@ -236,7 +236,7 @@ static void bfa_cee_hbfail(void *arg) { struct bfa_cee *cee; - cee = (struct bfa_cee *) arg; + cee = arg; if (cee->get_attr_pending == true) { cee->get_attr_status = BFA_STATUS_FAILED; diff --git a/drivers/net/bna/cna.h b/drivers/net/bna/cna.h index bbd39dc6597..3c47dc52b42 100644 --- a/drivers/net/bna/cna.h +++ b/drivers/net/bna/cna.h @@ -74,7 +74,7 @@ typedef struct mac { u8 mac[MAC_ADDRLEN]; } mac_t; bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \ bfa_q_qe_init(*((struct list_head **) _qe)); \ } else { \ - *((struct list_head **) (_qe)) = (struct list_head *) NULL; \ + *((struct list_head **)(_qe)) = NULL; \ } \ } diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 731aa119377..d4b26fb24ed 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -134,7 +134,7 @@ int caif_shmdrv_rx_cb(u32 mbx_msg, void *priv) u32 avail_emptybuff = 0; unsigned long flags = 0; - pshm_drv = (struct shmdrv_layer *)priv; + pshm_drv = priv; /* Check for received buffers. */ if (mbx_msg & SHM_FULL_MASK) { diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index e66c3d9ab2c..5533b1526b1 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4318,7 +4318,7 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16); cnic_ctx_wr(dev, cid_addr, offset1, val); - txbd = (struct tx_bd *) udev->l2_ring; + txbd = udev->l2_ring; buf_map = udev->l2_buf_map; for (i = 0; i < MAX_TX_DESC_CNT; i++, txbd++) { @@ -4377,7 +4377,7 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id); cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val); - rxbd = (struct rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE); + rxbd = udev->l2_ring + BCM_PAGE_SIZE; for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; int n = (i % cp->l2_rx_ring_size) + 1; diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 862804f32b6..9db9068d29d 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -567,7 +567,7 @@ static void t3_process_tid_release_list(struct work_struct *work) while (td->tid_release_list) { struct t3c_tid_entry *p = td->tid_release_list; - td->tid_release_list = (struct t3c_tid_entry *)p->ctx; + td->tid_release_list = p->ctx; spin_unlock_bh(&td->tid_release_lock); skb = alloc_skb(sizeof(struct cpl_tid_release), diff --git a/drivers/net/davinci_cpdma.c b/drivers/net/davinci_cpdma.c index ae47f23ba93..dca9d3369cd 100644 --- a/drivers/net/davinci_cpdma.c +++ b/drivers/net/davinci_cpdma.c @@ -167,7 +167,7 @@ cpdma_desc_pool_create(struct device *dev, u32 phys, u32 hw_addr, } else { pool->cpumap = dma_alloc_coherent(dev, size, &pool->phys, GFP_KERNEL); - pool->iomap = (void __force __iomem *)pool->cpumap; + pool->iomap = pool->cpumap; pool->hw_addr = pool->phys; } diff --git a/drivers/net/declance.c b/drivers/net/declance.c index 219eb5ad5c1..cabd3a542ef 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -326,15 +326,18 @@ static void load_csrs(struct lance_private *lp) */ static void cp_to_buf(const int type, void *to, const void *from, int len) { - unsigned short *tp, *fp, clen; - unsigned char *rtp, *rfp; + unsigned short *tp; + const unsigned short *fp; + unsigned short clen; + unsigned char *rtp; + const unsigned char *rfp; if (type == PMAD_LANCE) { memcpy(to, from, len); } else if (type == PMAX_LANCE) { clen = len >> 1; - tp = (unsigned short *) to; - fp = (unsigned short *) from; + tp = to; + fp = from; while (clen--) { *tp++ = *fp++; @@ -342,8 +345,8 @@ static void cp_to_buf(const int type, void *to, const void *from, int len) } clen = len & 1; - rtp = (unsigned char *) tp; - rfp = (unsigned char *) fp; + rtp = tp; + rfp = fp; while (clen--) { *rtp++ = *rfp++; } @@ -352,8 +355,8 @@ static void cp_to_buf(const int type, void *to, const void *from, int len) * copy 16 Byte chunks */ clen = len >> 4; - tp = (unsigned short *) to; - fp = (unsigned short *) from; + tp = to; + fp = from; while (clen--) { *tp++ = *fp++; *tp++ = *fp++; @@ -382,15 +385,18 @@ static void cp_to_buf(const int type, void *to, const void *from, int len) static void cp_from_buf(const int type, void *to, const void *from, int len) { - unsigned short *tp, *fp, clen; - unsigned char *rtp, *rfp; + unsigned short *tp; + const unsigned short *fp; + unsigned short clen; + unsigned char *rtp; + const unsigned char *rfp; if (type == PMAD_LANCE) { memcpy(to, from, len); } else if (type == PMAX_LANCE) { clen = len >> 1; - tp = (unsigned short *) to; - fp = (unsigned short *) from; + tp = to; + fp = from; while (clen--) { *tp++ = *fp++; fp++; @@ -398,8 +404,8 @@ static void cp_from_buf(const int type, void *to, const void *from, int len) clen = len & 1; - rtp = (unsigned char *) tp; - rfp = (unsigned char *) fp; + rtp = tp; + rfp = fp; while (clen--) { *rtp++ = *rfp++; @@ -410,8 +416,8 @@ static void cp_from_buf(const int type, void *to, const void *from, int len) * copy 16 Byte chunks */ clen = len >> 4; - tp = (unsigned short *) to; - fp = (unsigned short *) from; + tp = to; + fp = from; while (clen--) { *tp++ = *fp++; *tp++ = *fp++; diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 8b0084d17c8..d54a0e93ba9 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -708,11 +708,11 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) /* Tx & Rx descriptors (aligned to a quadword boundary) */ offset = (offset + DEPCA_ALIGN) & ~DEPCA_ALIGN; - lp->rx_ring = (struct depca_rx_desc __iomem *) (lp->sh_mem + offset); + lp->rx_ring = lp->sh_mem + offset; lp->rx_ring_offset = offset; offset += (sizeof(struct depca_rx_desc) * NUM_RX_DESC); - lp->tx_ring = (struct depca_tx_desc __iomem *) (lp->sh_mem + offset); + lp->tx_ring = lp->sh_mem + offset; lp->tx_ring_offset = offset; offset += (sizeof(struct depca_tx_desc) * NUM_TX_DESC); diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 23179dbcedd..ed73e4a9350 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -221,13 +221,13 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) ring_space = pci_alloc_consistent (pdev, TX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_iounmap; - np->tx_ring = (struct netdev_desc *) ring_space; + np->tx_ring = ring_space; np->tx_ring_dma = ring_dma; ring_space = pci_alloc_consistent (pdev, RX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_unmap_tx; - np->rx_ring = (struct netdev_desc *) ring_space; + np->rx_ring = ring_space; np->rx_ring_dma = ring_dma; /* Parse eeprom data */ diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index cd44bb8017d..95b9f4fa811 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -331,7 +331,7 @@ struct ehea_eqe *ehea_poll_eq(struct ehea_eq *eq) unsigned long flags; spin_lock_irqsave(&eq->spinlock, flags); - eqe = (struct ehea_eqe *)hw_eqit_eq_get_inc_valid(&eq->hw_queue); + eqe = hw_eqit_eq_get_inc_valid(&eq->hw_queue); spin_unlock_irqrestore(&eq->spinlock, flags); return eqe; diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index c353bf3113c..814c187d5f9 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -391,13 +391,13 @@ static int __devinit epic_init_one (struct pci_dev *pdev, ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_iounmap; - ep->tx_ring = (struct epic_tx_desc *)ring_space; + ep->tx_ring = ring_space; ep->tx_ring_dma = ring_dma; ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_unmap_tx; - ep->rx_ring = (struct epic_rx_desc *)ring_space; + ep->rx_ring = ring_space; ep->rx_ring_dma = ring_dma; if (dev->mem_start) { diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index dd54abe2f71..fa8677c3238 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -566,7 +566,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, err = -ENOMEM; goto err_out_free_dev; } - np->rx_ring = (struct fealnx_desc *)ring_space; + np->rx_ring = ring_space; np->rx_ring_dma = ring_dma; ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma); @@ -574,7 +574,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, err = -ENOMEM; goto err_out_free_rx; } - np->tx_ring = (struct fealnx_desc *)ring_space; + np->tx_ring = ring_space; np->tx_ring_dma = ring_dma; /* find the connected MII xcvrs */ diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index dc0a7aa42b2..3321d714ca2 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -267,7 +267,7 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) for (i = 0; i < priv->num_tx_queues; i++) { tx_queue = priv->tx_queue[i]; - tx_queue->tx_bd_base = (struct txbd8 *) vaddr; + tx_queue->tx_bd_base = vaddr; tx_queue->tx_bd_dma_base = addr; tx_queue->dev = ndev; /* enet DMA only understands physical addresses */ @@ -278,7 +278,7 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) /* Start the rx descriptor ring where the tx ring leaves off */ for (i = 0; i < priv->num_rx_queues; i++) { rx_queue = priv->rx_queue[i]; - rx_queue->rx_bd_base = (struct rxbd8 *) vaddr; + rx_queue->rx_bd_base = vaddr; rx_queue->rx_bd_dma_base = addr; rx_queue->dev = ndev; addr += sizeof (struct rxbd8) * rx_queue->rx_ring_size; diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index a09041aa850..c274b3d77eb 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -648,13 +648,13 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_cleardev; - hmp->tx_ring = (struct hamachi_desc *)ring_space; + hmp->tx_ring = ring_space; hmp->tx_ring_dma = ring_dma; ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_unmap_tx; - hmp->rx_ring = (struct hamachi_desc *)ring_space; + hmp->rx_ring = ring_space; hmp->rx_ring_dma = ring_dma; /* Check for options being passed in */ diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index c685a465687..4286e67f963 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -221,7 +221,7 @@ static int __devinit mace_probe(struct platform_device *pdev) SET_NETDEV_DEV(dev, &pdev->dev); dev->base_addr = (u32)MACE_BASE; - mp->mace = (volatile struct mace *) MACE_BASE; + mp->mace = MACE_BASE; dev->irq = IRQ_MAC_MACE; mp->dma_intr = IRQ_MAC_MACE_DMA; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 277215fb9d7..5197b50b2d8 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -859,7 +859,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) priv->rx_ring[0].cqn, &context); ptr = ((void *) &context) + 0x3c; - rss_context = (struct mlx4_en_rss_context *) ptr; + rss_context = ptr; rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 | (rss_map->base_qpn)); rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn); diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index b229acf1855..6e03de034ac 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -238,8 +238,7 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, } else { if (!tx_info->inl) { if ((void *) data >= end) { - data = (struct mlx4_wqe_data_seg *) - (ring->buf + ((void *) data - end)); + data = ring->buf + ((void *)data - end); } if (tx_info->linear) { @@ -253,7 +252,7 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, for (i = 0; i < frags; i++) { /* Check for wraparound before unmapping */ if ((void *) data >= end) - data = (struct mlx4_wqe_data_seg *) ring->buf; + data = ring->buf; frag = &skb_shinfo(skb)->frags[i]; pci_unmap_page(mdev->pdev, (dma_addr_t) be64_to_cpu(data->addr), diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index f16966afa64..a925392abd6 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -163,7 +163,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) rq_size, &hostrq_phys_addr); if (addr == NULL) return -ENOMEM; - prq = (nx_hostrq_rx_ctx_t *)addr; + prq = addr; addr = pci_alloc_consistent(adapter->pdev, rsp_size, &cardrsp_phys_addr); @@ -171,7 +171,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) err = -ENOMEM; goto out_free_rq; } - prsp = (nx_cardrsp_rx_ctx_t *)addr; + prsp = addr; prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); @@ -318,10 +318,10 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) } memset(rq_addr, 0, rq_size); - prq = (nx_hostrq_tx_ctx_t *)rq_addr; + prq = rq_addr; memset(rsp_addr, 0, rsp_size); - prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr; + prsp = rsp_addr; prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr); @@ -629,7 +629,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) } memset(addr, 0, sizeof(struct netxen_ring_ctx)); - recv_ctx->hwctx = (struct netxen_ring_ctx *)addr; + recv_ctx->hwctx = addr; recv_ctx->hwctx->ctx_id = cpu_to_le32(port); recv_ctx->hwctx->cmd_consumer_offset = cpu_to_le64(recv_ctx->phys_addr + @@ -648,7 +648,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) goto err_out_free; } - tx_ring->desc_head = (struct cmd_desc_type0 *)addr; + tx_ring->desc_head = addr; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; @@ -662,7 +662,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) err = -ENOMEM; goto err_out_free; } - rds_ring->desc_head = (struct rcv_desc *)addr; + rds_ring->desc_head = addr; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) rds_ring->crb_rcv_producer = @@ -683,7 +683,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) err = -ENOMEM; goto err_out_free; } - sds_ring->desc_head = (struct status_desc *)addr; + sds_ring->desc_head = addr; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { sds_ring->crb_sts_consumer = diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 1f97db1fc4b..c1bb05be7a7 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -502,7 +502,7 @@ static int add_del_hash_entry(struct pxa168_eth_private *pep, * Pick the appropriate table, start scanning for free/reusable * entries at the index obtained by hashing the specified MAC address */ - start = (struct addr_table_entry *)(pep->htpr); + start = pep->htpr; entry = start + hash_function(mac_addr); for (i = 0; i < HOP_NUMBER; i++) { if (!(le32_to_cpu(entry->lo) & HASH_ENTRY_VALID)) { diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 771bb614ccc..2f6914025ef 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2873,7 +2873,7 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) PAGE_SIZE, &qdev->shadow_reg_phy_addr); if (qdev->shadow_reg_virt_addr != NULL) { - qdev->preq_consumer_index = (u16 *) qdev->shadow_reg_virt_addr; + qdev->preq_consumer_index = qdev->shadow_reg_virt_addr; qdev->req_consumer_index_phy_addr_high = MS_64BITS(qdev->shadow_reg_phy_addr); qdev->req_consumer_index_phy_addr_low = @@ -3114,8 +3114,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) qdev->small_buf_release_cnt = 8; qdev->lrg_buf_q_producer_index = qdev->num_lbufq_entries - 1; qdev->lrg_buf_release_cnt = 8; - qdev->lrg_buf_next_free = - (struct bufq_addr_element *)qdev->lrg_buf_q_virt_addr; + qdev->lrg_buf_next_free = qdev->lrg_buf_q_virt_addr; qdev->small_buf_index = 0; qdev->lrg_buf_index = 0; qdev->lrg_buf_free_count = 0; diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index bab041a5c75..c77024f9007 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -126,7 +126,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) err = -EIO; goto error; } - tmp_tmpl = (struct qlcnic_dump_template_hdr *) tmp_addr; + tmp_tmpl = tmp_addr; csum = qlcnic_temp_checksum((uint32_t *) tmp_addr, temp_size); if (csum) { dev_err(&adapter->pdev->dev, @@ -139,7 +139,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) err = -EIO; goto error; } - tmp_buf = (u32 *) tmp_addr; + tmp_buf = tmp_addr; template = (u32 *) ahw->fw_dump.tmpl_hdr; for (i = 0; i < temp_size/sizeof(u32); i++) *template++ = __le32_to_cpu(*tmp_buf++); @@ -214,7 +214,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) &hostrq_phys_addr, GFP_KERNEL); if (addr == NULL) return -ENOMEM; - prq = (struct qlcnic_hostrq_rx_ctx *)addr; + prq = addr; addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size, &cardrsp_phys_addr, GFP_KERNEL); @@ -222,7 +222,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) err = -ENOMEM; goto out_free_rq; } - prsp = (struct qlcnic_cardrsp_rx_ctx *)addr; + prsp = addr; prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); @@ -380,10 +380,10 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) } memset(rq_addr, 0, rq_size); - prq = (struct qlcnic_hostrq_tx_ctx *)rq_addr; + prq = rq_addr; memset(rsp_addr, 0, rsp_size); - prsp = (struct qlcnic_cardrsp_tx_ctx *)rsp_addr; + prsp = rsp_addr; prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr); @@ -493,7 +493,7 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) goto err_out_free; } - tx_ring->desc_head = (struct cmd_desc_type0 *)addr; + tx_ring->desc_head = addr; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; @@ -506,7 +506,7 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) err = -ENOMEM; goto err_out_free; } - rds_ring->desc_head = (struct rcv_desc *)addr; + rds_ring->desc_head = addr; } @@ -522,7 +522,7 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) err = -ENOMEM; goto err_out_free; } - sds_ring->desc_head = (struct status_desc *)addr; + sds_ring->desc_head = addr; } return 0; @@ -662,7 +662,7 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, return -ENOMEM; memset(nic_info_addr, 0, nic_size); - nic_info = (struct qlcnic_info *) nic_info_addr; + nic_info = nic_info_addr; err = qlcnic_issue_cmd(adapter, adapter->ahw->pci_func, adapter->fw_hal_version, @@ -720,7 +720,7 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) return -ENOMEM; memset(nic_info_addr, 0, nic_size); - nic_info = (struct qlcnic_info *)nic_info_addr; + nic_info = nic_info_addr; nic_info->pci_func = cpu_to_le16(nic->pci_func); nic_info->op_mode = cpu_to_le16(nic->op_mode); @@ -769,7 +769,7 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, return -ENOMEM; memset(pci_info_addr, 0, pci_size); - npar = (struct qlcnic_pci_info *) pci_info_addr; + npar = pci_info_addr; err = qlcnic_issue_cmd(adapter, adapter->ahw->pci_func, adapter->fw_hal_version, @@ -877,7 +877,7 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, QLCNIC_CDRP_CMD_GET_ESWITCH_STATS); if (!err) { - stats = (struct __qlcnic_esw_statistics *)stats_addr; + stats = stats_addr; esw_stats->context_id = le16_to_cpu(stats->context_id); esw_stats->version = le16_to_cpu(stats->version); esw_stats->size = le16_to_cpu(stats->size); diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 9efc690a289..8ea800192d5 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -996,7 +996,7 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, /* Copy template header first */ copy_sz = fw_dump->tmpl_hdr->size; hdr_ptr = (u32 *) fw_dump->tmpl_hdr; - data = (u32 *) buffer; + data = buffer; for (i = 0; i < copy_sz/sizeof(u32); i++) *data++ = cpu_to_le32(*hdr_ptr++); diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index a5d9fbf9d81..1947f817bf2 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -1673,8 +1673,7 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter) tmpl_hdr->sys_info[1] = adapter->fw_version; for (i = 0; i < no_entries; i++) { - entry = (struct qlcnic_dump_entry *) ((void *) tmpl_hdr + - entry_offset); + entry = (void *)tmpl_hdr + entry_offset; if (!(entry->hdr.mask & tmpl_hdr->drv_cap_mask)) { entry->hdr.flags |= QLCNIC_DUMP_SKIP; entry_offset += entry->hdr.offset; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 0f6af5c61a7..347a4a8d126 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1861,7 +1861,7 @@ qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) return; adapter->fhash.fmax = QLCNIC_LB_MAX_FILTERS; - adapter->fhash.fhead = (struct hlist_head *)head; + adapter->fhash.fhead = head; for (i = 0; i < adapter->fhash.fmax; i++) INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 930ae45457b..be89610f16a 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3096,7 +3096,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->lbq_len) { cqicb->flags |= FLAGS_LL; /* Load lbq values */ tmp = (u64)rx_ring->lbq_base_dma; - base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect; + base_indirect_ptr = rx_ring->lbq_base_indirect; page_entries = 0; do { *base_indirect_ptr = cpu_to_le64(tmp); @@ -3120,7 +3120,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->sbq_len) { cqicb->flags |= FLAGS_LS; /* Load sbq values */ tmp = (u64)rx_ring->sbq_base_dma; - base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect; + base_indirect_ptr = rx_ring->sbq_base_indirect; page_entries = 0; do { *base_indirect_ptr = cpu_to_le64(tmp); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index df0d2c8ecc0..f4d80f9050e 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -841,7 +841,7 @@ static int init_shared_mem(struct s2io_nic *nic) tmp_p_addr = ring->rx_blocks[j].block_dma_addr; tmp_p_addr_next = ring->rx_blocks[next].block_dma_addr; - pre_rxd_blk = (struct RxD_block *)tmp_v_addr; + pre_rxd_blk = tmp_v_addr; pre_rxd_blk->reserved_2_pNext_RxD_block = (unsigned long)tmp_v_addr_next; pre_rxd_blk->pNext_RxD_Blk_physical = @@ -918,7 +918,7 @@ static int init_shared_mem(struct s2io_nic *nic) mac_control->stats_mem_sz = size; tmp_v_addr = mac_control->stats_mem; - mac_control->stats_info = (struct stat_block *)tmp_v_addr; + mac_control->stats_info = tmp_v_addr; memset(tmp_v_addr, 0, size); DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr); @@ -2439,7 +2439,7 @@ static void free_tx_buffers(struct s2io_nic *nic) spin_lock_irqsave(&fifo->tx_lock, flags); for (j = 0; j < tx_cfg->fifo_len; j++) { - txdp = (struct TxD *)fifo->list_info[j].list_virt_addr; + txdp = fifo->list_info[j].list_virt_addr; skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); if (skb) { swstats->mem_freed += skb->truesize; @@ -3075,8 +3075,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) get_info = fifo_data->tx_curr_get_info; memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info)); - txdlp = (struct TxD *) - fifo_data->list_info[get_info.offset].list_virt_addr; + txdlp = fifo_data->list_info[get_info.offset].list_virt_addr; while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && (get_info.offset != put_info.offset) && (txdlp->Host_Control)) { @@ -3129,8 +3128,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) get_info.offset++; if (get_info.offset == get_info.fifo_len + 1) get_info.offset = 0; - txdlp = (struct TxD *) - fifo_data->list_info[get_info.offset].list_virt_addr; + txdlp = fifo_data->list_info[get_info.offset].list_virt_addr; fifo_data->tx_curr_get_info.offset = get_info.offset; } @@ -4163,7 +4161,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) put_off = (u16)fifo->tx_curr_put_info.offset; get_off = (u16)fifo->tx_curr_get_info.offset; - txdp = (struct TxD *)fifo->list_info[put_off].list_virt_addr; + txdp = fifo->list_info[put_off].list_virt_addr; queue_len = fifo->tx_curr_put_info.fifo_len + 1; /* Avoid "put" pointer going beyond "get" pointer */ @@ -7972,9 +7970,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Initializing the BAR1 address as the start of the FIFO pointer. */ for (j = 0; j < MAX_TX_FIFOS; j++) { - mac_control->tx_FIFO_start[j] = - (struct TxFIFO_element __iomem *) - (sp->bar1 + (j * 0x00020000)); + mac_control->tx_FIFO_start[j] = sp->bar1 + (j * 0x00020000); } /* Driver entry points */ diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index fb4721f780f..a66818ed401 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -400,7 +400,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) u64 generation_end; mac_stats = &efx->mac_stats; - dma_stats = (u64 *)efx->stats_buffer.addr; + dma_stats = efx->stats_buffer.addr; generation_end = dma_stats[MC_CMD_MAC_GENERATION_END]; if (generation_end == STATS_GENERATION_INVALID) diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 484f795a779..658a1928fe7 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -482,7 +482,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, ret = -ENOMEM; goto err_out_cleardev; } - sis_priv->tx_ring = (BufferDesc *)ring_space; + sis_priv->tx_ring = ring_space; sis_priv->tx_ring_dma = ring_dma; ring_space = pci_alloc_consistent(pci_dev, RX_TOTAL_SIZE, &ring_dma); @@ -490,7 +490,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, ret = -ENOMEM; goto err_unmap_tx; } - sis_priv->rx_ring = (BufferDesc *)ring_space; + sis_priv->rx_ring = ring_space; sis_priv->rx_ring_dma = ring_dma; /* The SiS900-specific entries in the device structure. */ diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 2bedc0ace81..6153cfd696b 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -418,7 +418,7 @@ static irqreturn_t madgemc_interrupt(int irq, void *dev_id) return IRQ_NONE; } - dev = (struct net_device *)dev_id; + dev = dev_id; /* Make sure its really us. -- the Madge way */ pending = inb(dev->base_addr + MC_CONTROL_REG0); diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 3de4283344e..1d5091a1e49 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -2367,7 +2367,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->irq = pdev->irq; tp = netdev_priv(dev); - tp->shared = (struct typhoon_shared *) shared; + tp->shared = shared; tp->shared_dma = shared_dma; tp->pdev = pdev; tp->tx_pdev = pdev; diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 32763b2dd73..857618afa14 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -582,7 +582,7 @@ __vxge_hw_device_toc_get(void __iomem *bar0) goto exit; val64 = readq(&legacy_reg->toc_first_pointer); - toc = (struct vxge_hw_toc_reg __iomem *)(bar0+val64); + toc = bar0 + val64; exit: return toc; } @@ -600,7 +600,7 @@ __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev) u32 i; enum vxge_hw_status status = VXGE_HW_OK; - hldev->legacy_reg = (struct vxge_hw_legacy_reg __iomem *)hldev->bar0; + hldev->legacy_reg = hldev->bar0; hldev->toc_reg = __vxge_hw_device_toc_get(hldev->bar0); if (hldev->toc_reg == NULL) { @@ -609,39 +609,31 @@ __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev) } val64 = readq(&hldev->toc_reg->toc_common_pointer); - hldev->common_reg = - (struct vxge_hw_common_reg __iomem *)(hldev->bar0 + val64); + hldev->common_reg = hldev->bar0 + val64; val64 = readq(&hldev->toc_reg->toc_mrpcim_pointer); - hldev->mrpcim_reg = - (struct vxge_hw_mrpcim_reg __iomem *)(hldev->bar0 + val64); + hldev->mrpcim_reg = hldev->bar0 + val64; for (i = 0; i < VXGE_HW_TITAN_SRPCIM_REG_SPACES; i++) { val64 = readq(&hldev->toc_reg->toc_srpcim_pointer[i]); - hldev->srpcim_reg[i] = - (struct vxge_hw_srpcim_reg __iomem *) - (hldev->bar0 + val64); + hldev->srpcim_reg[i] = hldev->bar0 + val64; } for (i = 0; i < VXGE_HW_TITAN_VPMGMT_REG_SPACES; i++) { val64 = readq(&hldev->toc_reg->toc_vpmgmt_pointer[i]); - hldev->vpmgmt_reg[i] = - (struct vxge_hw_vpmgmt_reg __iomem *)(hldev->bar0 + val64); + hldev->vpmgmt_reg[i] = hldev->bar0 + val64; } for (i = 0; i < VXGE_HW_TITAN_VPATH_REG_SPACES; i++) { val64 = readq(&hldev->toc_reg->toc_vpath_pointer[i]); - hldev->vpath_reg[i] = - (struct vxge_hw_vpath_reg __iomem *) - (hldev->bar0 + val64); + hldev->vpath_reg[i] = hldev->bar0 + val64; } val64 = readq(&hldev->toc_reg->toc_kdfc); switch (VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val64)) { case 0: - hldev->kdfc = (u8 __iomem *)(hldev->bar0 + - VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64)); + hldev->kdfc = hldev->bar0 + VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64) ; break; default: break; @@ -1024,7 +1016,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, } val64 = readq(&toc->toc_common_pointer); - common_reg = (struct vxge_hw_common_reg __iomem *)(bar0 + val64); + common_reg = bar0 + val64; status = __vxge_hw_device_vpath_reset_in_prog_check( (u64 __iomem *)&common_reg->vpath_rst_in_prog); @@ -1044,8 +1036,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, val64 = readq(&toc->toc_vpmgmt_pointer[i]); - vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *) - (bar0 + val64); + vpmgmt_reg = bar0 + val64; hw_info->func_id = __vxge_hw_vpath_func_id_get(vpmgmt_reg); if (__vxge_hw_device_access_rights_get(hw_info->host_type, @@ -1054,8 +1045,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, val64 = readq(&toc->toc_mrpcim_pointer); - mrpcim_reg = (struct vxge_hw_mrpcim_reg __iomem *) - (bar0 + val64); + mrpcim_reg = bar0 + val64; writeq(0, &mrpcim_reg->xgmac_gen_fw_memo_mask); wmb(); @@ -1064,8 +1054,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, val64 = readq(&toc->toc_vpath_pointer[i]); spin_lock_init(&vpath.lock); - vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) - (bar0 + val64); + vpath.vp_reg = bar0 + val64; vpath.vp_open = VXGE_HW_VP_NOT_OPEN; status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info); @@ -1088,8 +1077,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, continue; val64 = readq(&toc->toc_vpath_pointer[i]); - vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) - (bar0 + val64); + vpath.vp_reg = bar0 + val64; vpath.vp_open = VXGE_HW_VP_NOT_OPEN; status = __vxge_hw_vpath_addr_get(&vpath, @@ -2140,8 +2128,7 @@ __vxge_hw_ring_mempool_item_alloc(struct vxge_hw_mempool *mempoolh, memblock_index, item, &memblock_item_idx); - rxdp = (struct vxge_hw_ring_rxd_1 *) - ring->channel.reserve_arr[reserve_index]; + rxdp = ring->channel.reserve_arr[reserve_index]; uld_priv = ((u8 *)rxdblock_priv + ring->rxd_priv_size * i); @@ -4880,8 +4867,7 @@ vxge_hw_vpath_open(struct __vxge_hw_device *hldev, goto vpath_open_exit8; } - vpath->hw_stats = (struct vxge_hw_vpath_stats_hw_info *)vpath-> - stats_block->memblock; + vpath->hw_stats = vpath->stats_block->memblock; memset(vpath->hw_stats, 0, sizeof(struct vxge_hw_vpath_stats_hw_info)); diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index f9351705516..ad64ce0afe3 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -1309,7 +1309,7 @@ enum vxge_hw_status vxge_hw_ring_rxd_next_completed( vxge_hw_channel_dtr_try_complete(channel, rxdh); - rxdp = (struct vxge_hw_ring_rxd_1 *)*rxdh; + rxdp = *rxdh; if (rxdp == NULL) { status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS; goto exit; @@ -1565,7 +1565,7 @@ void vxge_hw_fifo_txdl_post(struct __vxge_hw_fifo *fifo, void *txdlh) channel = &fifo->channel; txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdlh); - txdp_first = (struct vxge_hw_fifo_txd *)txdlh; + txdp_first = txdlh; txdp_last = (struct vxge_hw_fifo_txd *)txdlh + (txdl_priv->frags - 1); txdp_last->control_0 |= @@ -1631,7 +1631,7 @@ enum vxge_hw_status vxge_hw_fifo_txdl_next_completed( vxge_hw_channel_dtr_try_complete(channel, txdlh); - txdp = (struct vxge_hw_fifo_txd *)*txdlh; + txdp = *txdlh; if (txdp == NULL) { status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS; goto exit; diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 1c65d1c3387..d47d2cd1047 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -755,7 +755,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev) dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch)); - cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; + cpc_tty = pc300dev->cpc_tty; while (1) { rx_len = 0; diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 039d976ba31..8018d7d045b 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -252,11 +252,11 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr, u16 *from_u16_ptr, *to_u16_ptr; to_u32_ptr = dest_ptr; - from_u16_ptr = (u16 *) src_ptr; + from_u16_ptr = src_ptr; align_buffer = 0; for (; length > 3; length -= 4) { - to_u16_ptr = (u16 *) ((void *) &align_buffer); + to_u16_ptr = (u16 *)&align_buffer; *to_u16_ptr++ = *from_u16_ptr++; *to_u16_ptr++ = *from_u16_ptr++; diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index ec47e22fa18..3e5ac60b89a 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -442,19 +442,19 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_cleardev; - np->tx_ring = (struct yellowfin_desc *)ring_space; + np->tx_ring = ring_space; np->tx_ring_dma = ring_dma; ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_unmap_tx; - np->rx_ring = (struct yellowfin_desc *)ring_space; + np->rx_ring = ring_space; np->rx_ring_dma = ring_dma; ring_space = pci_alloc_consistent(pdev, STATUS_TOTAL_SIZE, &ring_dma); if (!ring_space) goto err_out_unmap_rx; - np->tx_status = (struct tx_status_words *)ring_space; + np->tx_status = ring_space; np->tx_status_dma = ring_dma; if (dev->mem_start) -- cgit v1.2.3-70-g09d2 From 3b0c9cbb6e5fe25a4162be68ed1459b6f7432da9 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 20 Jun 2011 11:42:30 +0000 Subject: ifb: convert to 64 bit stats Convert input functional block device to use 64 bit stats. Signed-off-by: Stephen Hemminger Signed-off-by: Eric Dumazet Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- drivers/net/ifb.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index ce53f4a23b1..6e82dd32e80 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -41,8 +41,16 @@ struct ifb_private { struct tasklet_struct ifb_tasklet; int tasklet_pending; + + struct u64_stats_sync rsync; struct sk_buff_head rq; + u64 rx_packets; + u64 rx_bytes; + + struct u64_stats_sync tsync; struct sk_buff_head tq; + u64 tx_packets; + u64 tx_bytes; }; static int numifbs = 2; @@ -54,10 +62,8 @@ static int ifb_close(struct net_device *dev); static void ri_tasklet(unsigned long dev) { - struct net_device *_dev = (struct net_device *)dev; struct ifb_private *dp = netdev_priv(_dev); - struct net_device_stats *stats = &_dev->stats; struct netdev_queue *txq; struct sk_buff *skb; @@ -77,15 +83,18 @@ static void ri_tasklet(unsigned long dev) skb->tc_verd = 0; skb->tc_verd = SET_TC_NCLS(skb->tc_verd); - stats->tx_packets++; - stats->tx_bytes +=skb->len; + + u64_stats_update_begin(&dp->tsync); + dp->tx_packets++; + dp->tx_bytes += skb->len; + u64_stats_update_end(&dp->tsync); rcu_read_lock(); skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif); if (!skb->dev) { rcu_read_unlock(); dev_kfree_skb(skb); - stats->tx_dropped++; + _dev->stats.tx_dropped++; if (skb_queue_len(&dp->tq) != 0) goto resched; break; @@ -120,9 +129,37 @@ resched: } +static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + struct ifb_private *dp = netdev_priv(dev); + unsigned int start; + + do { + start = u64_stats_fetch_begin_bh(&dp->rsync); + stats->rx_packets = dp->rx_packets; + stats->rx_bytes = dp->rx_bytes; + } while (u64_stats_fetch_retry_bh(&dp->rsync, start)); + + do { + start = u64_stats_fetch_begin_bh(&dp->tsync); + + stats->tx_packets = dp->tx_packets; + stats->tx_bytes = dp->tx_bytes; + + } while (u64_stats_fetch_retry_bh(&dp->tsync, start)); + + stats->rx_dropped = dev->stats.rx_dropped; + stats->tx_dropped = dev->stats.tx_dropped; + + return stats; +} + + static const struct net_device_ops ifb_netdev_ops = { .ndo_open = ifb_open, .ndo_stop = ifb_close, + .ndo_get_stats64 = ifb_stats64, .ndo_start_xmit = ifb_xmit, .ndo_validate_addr = eth_validate_addr, }; @@ -153,15 +190,16 @@ static void ifb_setup(struct net_device *dev) static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) { struct ifb_private *dp = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; u32 from = G_TC_FROM(skb->tc_verd); - stats->rx_packets++; - stats->rx_bytes+=skb->len; + u64_stats_update_begin(&dp->rsync); + dp->rx_packets++; + dp->rx_bytes += skb->len; + u64_stats_update_end(&dp->rsync); if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) { dev_kfree_skb(skb); - stats->rx_dropped++; + dev->stats.rx_dropped++; return NETDEV_TX_OK; } -- cgit v1.2.3-70-g09d2 From 62ea05577ed3ea4f542f9bc17cb716787316e2ea Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 20 Jun 2011 10:35:07 +0000 Subject: vxge: fix 64 bit access on 32 bit platforms Need to add stat_sync wrapper around 64 bit statistic values. Fix wraparound bug in lockup detector where it is unsafely comparing 64 bit value that is not atomic. Since only care about detecting activity just looking at current low order bits will work. Remove unused entries in old vxge_sw_stats structure. Change the error counters to unsigned long since they won't grow so large as to have to be 64 bits. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 51 +++++++++++++++++++++++++++++++++++--------- drivers/net/vxge/vxge-main.h | 48 ++++++++++++++++------------------------- 2 files changed, 59 insertions(+), 40 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index e658edd1c95..54ca74806bb 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -296,11 +296,13 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan, skb_record_rx_queue(skb, ring->driver_id); skb->protocol = eth_type_trans(skb, ring->ndev); + u64_stats_update_begin(&ring->stats.syncp); ring->stats.rx_frms++; ring->stats.rx_bytes += pkt_length; if (skb->pkt_type == PACKET_MULTICAST) ring->stats.rx_mcast++; + u64_stats_update_end(&ring->stats.syncp); vxge_debug_rx(VXGE_TRACE, "%s: %s:%d skb protocol = %d", @@ -592,8 +594,10 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr, vxge_hw_fifo_txdl_free(fifo_hw, dtr); /* Updating the statistics block */ + u64_stats_update_begin(&fifo->stats.syncp); fifo->stats.tx_frms++; fifo->stats.tx_bytes += skb->len; + u64_stats_update_end(&fifo->stats.syncp); *done_skb++ = skb; @@ -2630,11 +2634,16 @@ static void vxge_poll_vp_lockup(unsigned long data) struct vxge_vpath *vpath; struct vxge_ring *ring; int i; + unsigned long rx_frms; for (i = 0; i < vdev->no_of_vpath; i++) { ring = &vdev->vpaths[i].ring; + + /* Truncated to machine word size number of frames */ + rx_frms = ACCESS_ONCE(ring->stats.rx_frms); + /* Did this vpath received any packets */ - if (ring->stats.prev_rx_frms == ring->stats.rx_frms) { + if (ring->stats.prev_rx_frms == rx_frms) { status = vxge_hw_vpath_check_leak(ring->handle); /* Did it received any packets last time */ @@ -2654,7 +2663,7 @@ static void vxge_poll_vp_lockup(unsigned long data) } } } - ring->stats.prev_rx_frms = ring->stats.rx_frms; + ring->stats.prev_rx_frms = rx_frms; ring->last_status = status; } @@ -3125,14 +3134,36 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) /* net_stats already zeroed by caller */ for (k = 0; k < vdev->no_of_vpath; k++) { - net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms; - net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes; - net_stats->rx_errors += vdev->vpaths[k].ring.stats.rx_errors; - net_stats->multicast += vdev->vpaths[k].ring.stats.rx_mcast; - net_stats->rx_dropped += vdev->vpaths[k].ring.stats.rx_dropped; - net_stats->tx_packets += vdev->vpaths[k].fifo.stats.tx_frms; - net_stats->tx_bytes += vdev->vpaths[k].fifo.stats.tx_bytes; - net_stats->tx_errors += vdev->vpaths[k].fifo.stats.tx_errors; + struct vxge_ring_stats *rxstats = &vdev->vpaths[k].ring.stats; + struct vxge_fifo_stats *txstats = &vdev->vpaths[k].fifo.stats; + unsigned int start; + u64 packets, bytes, multicast; + + do { + start = u64_stats_fetch_begin(&rxstats->syncp); + + packets = rxstats->rx_frms; + multicast = rxstats->rx_mcast; + bytes = rxstats->rx_bytes; + } while (u64_stats_fetch_retry(&rxstats->syncp, start)); + + net_stats->rx_packets += packets; + net_stats->rx_bytes += bytes; + net_stats->multicast += multicast; + + net_stats->rx_errors += rxstats->rx_errors; + net_stats->rx_dropped += rxstats->rx_dropped; + + do { + start = u64_stats_fetch_begin(&txstats->syncp); + + packets = txstats->tx_frms; + bytes = txstats->tx_bytes; + } while (u64_stats_fetch_retry(&txstats->syncp, start)); + + net_stats->tx_packets += packets; + net_stats->tx_bytes += bytes; + net_stats->tx_errors += txstats->tx_errors; } return net_stats; diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index ed120aba443..66e6de86ff0 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -201,30 +201,14 @@ struct vxge_msix_entry { /* Software Statistics */ struct vxge_sw_stats { - /* Network Stats (interface stats) */ - - /* Tx */ - u64 tx_frms; - u64 tx_errors; - u64 tx_bytes; - u64 txd_not_free; - u64 txd_out_of_desc; /* Virtual Path */ - u64 vpaths_open; - u64 vpath_open_fail; - - /* Rx */ - u64 rx_frms; - u64 rx_errors; - u64 rx_bytes; - u64 rx_mcast; + unsigned long vpaths_open; + unsigned long vpath_open_fail; /* Misc. */ - u64 link_up; - u64 link_down; - u64 pci_map_fail; - u64 skb_alloc_fail; + unsigned long link_up; + unsigned long link_down; }; struct vxge_mac_addrs { @@ -237,12 +221,14 @@ struct vxge_mac_addrs { struct vxgedev; struct vxge_fifo_stats { + struct u64_stats_sync syncp; u64 tx_frms; - u64 tx_errors; u64 tx_bytes; - u64 txd_not_free; - u64 txd_out_of_desc; - u64 pci_map_fail; + + unsigned long tx_errors; + unsigned long txd_not_free; + unsigned long txd_out_of_desc; + unsigned long pci_map_fail; }; struct vxge_fifo { @@ -264,14 +250,16 @@ struct vxge_fifo { } ____cacheline_aligned; struct vxge_ring_stats { - u64 prev_rx_frms; + struct u64_stats_sync syncp; u64 rx_frms; - u64 rx_errors; - u64 rx_dropped; - u64 rx_bytes; u64 rx_mcast; - u64 pci_map_fail; - u64 skb_alloc_fail; + u64 rx_bytes; + + unsigned long rx_errors; + unsigned long rx_dropped; + unsigned long prev_rx_frms; + unsigned long pci_map_fail; + unsigned long skb_alloc_fail; }; struct vxge_ring { -- cgit v1.2.3-70-g09d2 From e00f85bec0a9924eb517ccd126ddbb9787068f53 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 21 Jun 2011 05:35:31 +0000 Subject: xen: convert to 64 bit stats interface Convert xen driver to 64 bit statistics interface. Use stats_sync to ensure that 64 bit update is read atomically on 32 bit platform. Put hot statistics into per-cpu table. Signed-off-by: Stephen Hemminger Acked-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 69 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index d29365a232a..d7c8a98daff 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -70,6 +70,14 @@ struct netfront_cb { #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) +struct netfront_stats { + u64 rx_packets; + u64 tx_packets; + u64 rx_bytes; + u64 tx_bytes; + struct u64_stats_sync syncp; +}; + struct netfront_info { struct list_head list; struct net_device *netdev; @@ -122,6 +130,8 @@ struct netfront_info { struct mmu_update rx_mmu[NET_RX_RING_SIZE]; /* Statistics */ + struct netfront_stats __percpu *stats; + unsigned long rx_gso_checksum_fixup; }; @@ -468,6 +478,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned short id; struct netfront_info *np = netdev_priv(dev); + struct netfront_stats *stats = this_cpu_ptr(np->stats); struct xen_netif_tx_request *tx; struct xen_netif_extra_info *extra; char *data = skb->data; @@ -552,8 +563,10 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (notify) notify_remote_via_irq(np->netdev->irq); - dev->stats.tx_bytes += skb->len; - dev->stats.tx_packets++; + u64_stats_update_begin(&stats->syncp); + stats->tx_bytes += skb->len; + stats->tx_packets++; + u64_stats_update_end(&stats->syncp); /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ xennet_tx_buf_gc(dev); @@ -847,6 +860,8 @@ out: static int handle_incoming_queue(struct net_device *dev, struct sk_buff_head *rxq) { + struct netfront_info *np = netdev_priv(dev); + struct netfront_stats *stats = this_cpu_ptr(np->stats); int packets_dropped = 0; struct sk_buff *skb; @@ -871,8 +886,10 @@ static int handle_incoming_queue(struct net_device *dev, continue; } - dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; + u64_stats_update_begin(&stats->syncp); + stats->rx_packets++; + stats->rx_bytes += skb->len; + u64_stats_update_end(&stats->syncp); /* Pass it up. */ netif_receive_skb(skb); @@ -1034,6 +1051,38 @@ static int xennet_change_mtu(struct net_device *dev, int mtu) return 0; } +static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *tot) +{ + struct netfront_info *np = netdev_priv(dev); + int cpu; + + for_each_possible_cpu(cpu) { + struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu); + u64 rx_packets, rx_bytes, tx_packets, tx_bytes; + unsigned int start; + + do { + start = u64_stats_fetch_begin_bh(&stats->syncp); + + rx_packets = stats->rx_packets; + tx_packets = stats->tx_packets; + rx_bytes = stats->rx_bytes; + tx_bytes = stats->tx_bytes; + } while (u64_stats_fetch_retry_bh(&stats->syncp, start)); + + tot->rx_packets += rx_packets; + tot->tx_packets += tx_packets; + tot->rx_bytes += rx_bytes; + tot->tx_bytes += tx_bytes; + } + + tot->rx_errors = dev->stats.rx_errors; + tot->tx_dropped = dev->stats.tx_dropped; + + return tot; +} + static void xennet_release_tx_bufs(struct netfront_info *np) { struct sk_buff *skb; @@ -1182,6 +1231,7 @@ static const struct net_device_ops xennet_netdev_ops = { .ndo_stop = xennet_close, .ndo_start_xmit = xennet_start_xmit, .ndo_change_mtu = xennet_change_mtu, + .ndo_get_stats64 = xennet_get_stats64, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_fix_features = xennet_fix_features, @@ -1216,6 +1266,11 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev np->rx_refill_timer.data = (unsigned long)netdev; np->rx_refill_timer.function = rx_refill_timeout; + err = -ENOMEM; + np->stats = alloc_percpu(struct netfront_stats); + if (np->stats == NULL) + goto exit; + /* Initialise tx_skbs as a free chain containing every entry. */ np->tx_skb_freelist = 0; for (i = 0; i < NET_TX_RING_SIZE; i++) { @@ -1234,7 +1289,7 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev &np->gref_tx_head) < 0) { printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); err = -ENOMEM; - goto exit; + goto exit_free_stats; } /* A grant for every rx ring slot */ if (gnttab_alloc_grant_references(RX_MAX_TARGET, @@ -1270,6 +1325,8 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev exit_free_tx: gnttab_free_grant_references(np->gref_tx_head); + exit_free_stats: + free_percpu(np->stats); exit: free_netdev(netdev); return ERR_PTR(err); @@ -1869,6 +1926,8 @@ static int __devexit xennet_remove(struct xenbus_device *dev) xennet_sysfs_delif(info->netdev); + free_percpu(info->stats); + free_netdev(info->netdev); return 0; -- cgit v1.2.3-70-g09d2 From 73151ce35bd6d56e61a87b2855193f82540bf3d3 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Tue, 21 Jun 2011 16:00:24 -0700 Subject: mv643xx_eth: fix race in trasmit path. Because the socket buffer is freed in the completion interrupt, it is not safe to access it after submitting it to the hardware. Signed-off-by: Richard Cochran Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index a5d9b1c310b..1b7d2c1c34b 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -859,7 +859,7 @@ no_csum: static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev) { struct mv643xx_eth_private *mp = netdev_priv(dev); - int queue; + int length, queue; struct tx_queue *txq; struct netdev_queue *nq; @@ -881,10 +881,12 @@ static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } + length = skb->len; + if (!txq_submit_skb(txq, skb)) { int entries_left; - txq->tx_bytes += skb->len; + txq->tx_bytes += length; txq->tx_packets++; entries_left = txq->tx_ring_size - txq->tx_desc_count; -- cgit v1.2.3-70-g09d2 From 3b182d7d4287f38711f70d58d68cf2a34e582992 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Tue, 21 Jun 2011 16:01:11 -0700 Subject: mv643xx_eth: enable transmit time stamping. This patch enables software (and phy device) transmit time stamping. Compile tested only. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 1b7d2c1c34b..77dc6abe186 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -840,6 +840,8 @@ no_csum: __skb_queue_tail(&txq->tx_skb, skb); + skb_tx_timestamp(skb); + /* ensure all other descriptors are written before first cmd_sts */ wmb(); desc->cmd_sts = cmd_sts; -- cgit v1.2.3-70-g09d2 From f4b5ad26bcb983c493e131ff34b2fa60100c82e5 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 20 Jun 2011 15:15:56 +0000 Subject: cnic, bnx2i: Add support for new devices - 57800, 57810, and 57840 And change iSCSI RQ doorbell size from 16B to 64B to match new firmware. Signed-off-by: Michael Chan Signed-off-by: Eddie Wai Signed-off-by: David S. Miller --- drivers/net/cnic.h | 14 +++++++++++++- drivers/scsi/bnx2i/57xx_iscsi_constants.h | 2 +- drivers/scsi/bnx2i/bnx2i.h | 2 +- drivers/scsi/bnx2i/bnx2i_init.c | 21 +++++++++++++++------ include/linux/pci_ids.h | 9 +++++++++ 5 files changed, 39 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 330ef935041..7a2928f82d4 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -384,6 +384,9 @@ struct bnx2x_bd_chain_next { #define BNX2X_CHIP_NUM_57712E 0x1663 #define BNX2X_CHIP_NUM_57713 0x1651 #define BNX2X_CHIP_NUM_57713E 0x1652 +#define BNX2X_CHIP_NUM_57800 0x168a +#define BNX2X_CHIP_NUM_57810 0x168e +#define BNX2X_CHIP_NUM_57840 0x168d #define BNX2X_CHIP_NUM(x) (x >> 16) #define BNX2X_CHIP_IS_57710(x) \ @@ -402,10 +405,19 @@ struct bnx2x_bd_chain_next { (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713) #define BNX2X_CHIP_IS_57713E(x) \ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713E) +#define BNX2X_CHIP_IS_57800(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57800) +#define BNX2X_CHIP_IS_57810(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57810) +#define BNX2X_CHIP_IS_57840(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57840) #define BNX2X_CHIP_IS_E2(x) \ (BNX2X_CHIP_IS_57712(x) || BNX2X_CHIP_IS_57712E(x) || \ BNX2X_CHIP_IS_57713(x) || BNX2X_CHIP_IS_57713E(x)) -#define BNX2X_CHIP_IS_E2_PLUS(x) BNX2X_CHIP_IS_E2(x) +#define BNX2X_CHIP_IS_E3(x) \ + (BNX2X_CHIP_IS_57800(x) || BNX2X_CHIP_IS_57810(x) || \ + BNX2X_CHIP_IS_57840(x)) +#define BNX2X_CHIP_IS_E2_PLUS(x) (BNX2X_CHIP_IS_E2(x) || BNX2X_CHIP_IS_E3(x)) #define IS_E1H_OFFSET BNX2X_CHIP_IS_E1H(cp->chip_id) diff --git a/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/drivers/scsi/bnx2i/57xx_iscsi_constants.h index 30e6bdbd65a..15673cc786f 100644 --- a/drivers/scsi/bnx2i/57xx_iscsi_constants.h +++ b/drivers/scsi/bnx2i/57xx_iscsi_constants.h @@ -125,7 +125,7 @@ /* SQ/RQ/CQ DB structure sizes */ #define ISCSI_SQ_DB_SIZE (16) -#define ISCSI_RQ_DB_SIZE (16) +#define ISCSI_RQ_DB_SIZE (64) #define ISCSI_CQ_DB_SIZE (80) #define ISCSI_SQN_TO_NOTIFY_NOT_VALID 0xFFFF diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 6bdd25a93db..e7cb7ecf684 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -478,7 +478,7 @@ struct bnx2i_5771x_cq_db { struct bnx2i_5771x_sq_rq_db { u16 prod_idx; - u8 reserved0[14]; /* Pad structure size to 16 bytes */ + u8 reserved0[62]; /* Pad structure size to 64 bytes */ }; diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 6adbdc34a9a..6973413e91e 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -30,7 +30,7 @@ MODULE_AUTHOR("Anil Veerabhadrappa and " "Eddie Wai "); MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/57710/57711/57712" - " iSCSI Driver"); + "/57800/57810/57840 iSCSI Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); @@ -88,11 +88,20 @@ void bnx2i_identify_device(struct bnx2i_hba *hba) (hba->pci_did == PCI_DEVICE_ID_NX2_5709S)) { set_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type); hba->mail_queue_access = BNX2I_MQ_BIN_MODE; - } else if (hba->pci_did == PCI_DEVICE_ID_NX2_57710 || - hba->pci_did == PCI_DEVICE_ID_NX2_57711 || - hba->pci_did == PCI_DEVICE_ID_NX2_57711E || - hba->pci_did == PCI_DEVICE_ID_NX2_57712 || - hba->pci_did == PCI_DEVICE_ID_NX2_57712E) + } else if (hba->pci_did == PCI_DEVICE_ID_NX2_57710 || + hba->pci_did == PCI_DEVICE_ID_NX2_57711 || + hba->pci_did == PCI_DEVICE_ID_NX2_57711E || + hba->pci_did == PCI_DEVICE_ID_NX2_57712 || + hba->pci_did == PCI_DEVICE_ID_NX2_57712E || + hba->pci_did == PCI_DEVICE_ID_NX2_57800 || + hba->pci_did == PCI_DEVICE_ID_NX2_57800_MF || + hba->pci_did == PCI_DEVICE_ID_NX2_57800_VF || + hba->pci_did == PCI_DEVICE_ID_NX2_57810 || + hba->pci_did == PCI_DEVICE_ID_NX2_57810_MF || + hba->pci_did == PCI_DEVICE_ID_NX2_57810_VF || + hba->pci_did == PCI_DEVICE_ID_NX2_57840 || + hba->pci_did == PCI_DEVICE_ID_NX2_57840_MF || + hba->pci_did == PCI_DEVICE_ID_NX2_57840_VF) set_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type); else printk(KERN_ALERT "bnx2i: unknown device, 0x%x\n", diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index a311008af5e..d76bd9e4c78 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2102,6 +2102,9 @@ #define PCI_DEVICE_ID_TIGON3_5761E 0x1680 #define PCI_DEVICE_ID_TIGON3_5761 0x1681 #define PCI_DEVICE_ID_TIGON3_5764 0x1684 +#define PCI_DEVICE_ID_NX2_57800 0x168a +#define PCI_DEVICE_ID_NX2_57840 0x168d +#define PCI_DEVICE_ID_NX2_57810 0x168e #define PCI_DEVICE_ID_TIGON3_5787M 0x1693 #define PCI_DEVICE_ID_TIGON3_5782 0x1696 #define PCI_DEVICE_ID_TIGON3_5784 0x1698 @@ -2109,11 +2112,17 @@ #define PCI_DEVICE_ID_TIGON3_5787 0x169b #define PCI_DEVICE_ID_TIGON3_5788 0x169c #define PCI_DEVICE_ID_TIGON3_5789 0x169d +#define PCI_DEVICE_ID_NX2_57800_MF 0x16a5 #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 +#define PCI_DEVICE_ID_NX2_57800_VF 0x16a9 #define PCI_DEVICE_ID_NX2_5706S 0x16aa +#define PCI_DEVICE_ID_NX2_57840_MF 0x16ab #define PCI_DEVICE_ID_NX2_5708S 0x16ac +#define PCI_DEVICE_ID_NX2_57840_VF 0x16ad +#define PCI_DEVICE_ID_NX2_57810_MF 0x16ae +#define PCI_DEVICE_ID_NX2_57810_VF 0x16af #define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6 #define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7 #define PCI_DEVICE_ID_TIGON3_5781 0x16dd -- cgit v1.2.3-70-g09d2 From b7f080cfe223b3b7424872639d153695615a9255 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 16 Jun 2011 11:01:34 +0000 Subject: net: remove mm.h inclusion from netdevice.h Remove linux/mm.h inclusion from netdevice.h -- it's unused (I've checked manually). To prevent mm.h inclusion via other channels also extract "enum dma_data_direction" definition into separate header. This tiny piece is what gluing netdevice.h with mm.h via "netdevice.h => dmaengine.h => dma-mapping.h => scatterlist.h => mm.h". Removal of mm.h from scatterlist.h was tried and was found not feasible on most archs, so the link was cutoff earlier. Hope people are OK with tiny include file. Note, that mm_types.h is still dragged in, but it is a separate story. Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- arch/arm/mach-davinci/board-mityomapl138.c | 1 + arch/arm/mach-davinci/dm646x.c | 1 + arch/arm/mach-davinci/pm.c | 1 + arch/arm/mach-imx/dma-v1.c | 1 + arch/arm/mach-imx/mach-mx31_3ds.c | 1 + arch/arm/mach-iop13xx/setup.c | 1 + arch/arm/mach-mxs/devices/platform-auart.c | 1 + arch/arm/mach-mxs/devices/platform-dma.c | 1 + arch/arm/mach-mxs/devices/platform-fec.c | 1 + arch/arm/plat-mxc/devices/platform-fec.c | 1 + arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c | 1 + arch/arm/plat-mxc/devices/platform-imx-fb.c | 1 + arch/arm/plat-mxc/devices/platform-ipu-core.c | 1 + arch/arm/plat-mxc/devices/platform-mxc-ehci.c | 1 + arch/arm/plat-mxc/devices/platform-mxc-mmc.c | 1 + arch/arm/plat-nomadik/include/plat/ste_dma40.h | 1 + arch/x86/kernel/tboot.c | 1 + crypto/async_tx/raid6test.c | 1 + drivers/dma/coh901318.c | 1 + drivers/dma/dmaengine.c | 1 + drivers/dma/dmatest.c | 1 + drivers/dma/ipu/ipu_idmac.c | 1 + drivers/dma/ste_dma40.c | 1 + drivers/media/dvb/mantis/mantis_ca.c | 1 + drivers/media/dvb/mantis/mantis_evm.c | 1 + drivers/media/dvb/mantis/mantis_hif.c | 1 + drivers/media/dvb/mantis/mantis_ioc.c | 1 + drivers/media/dvb/mantis/mantis_pcmcia.c | 1 + drivers/media/dvb/mantis/mantis_uart.c | 1 + drivers/media/dvb/mantis/mantis_vp1034.c | 1 + drivers/mmc/host/tmio_mmc_dma.c | 1 + drivers/mtd/nand/atmel_nand.c | 1 + drivers/net/arm/ks8695net.c | 1 + drivers/net/bnx2x/bnx2x.h | 1 + drivers/net/can/janz-ican3.c | 1 + drivers/net/can/softing/softing_fw.c | 1 + drivers/net/can/softing/softing_main.c | 1 + drivers/net/ethoc.c | 1 + drivers/net/fec_mpc52xx.c | 1 + drivers/net/greth.c | 1 + drivers/net/irda/pxaficp_ir.c | 1 + drivers/net/ks8851_mll.c | 1 + drivers/net/sgiseeq.c | 1 + drivers/net/stmmac/dwmac1000_core.c | 1 + drivers/net/stmmac/dwmac1000_dma.c | 1 + drivers/net/stmmac/dwmac100_core.c | 1 + drivers/net/stmmac/dwmac100_dma.c | 1 + drivers/net/stmmac/stmmac_ethtool.c | 1 + drivers/net/stmmac/stmmac_mdio.c | 1 + drivers/net/usb/cdc-phonet.c | 1 + drivers/net/vxge/vxge-config.h | 1 + drivers/net/wireless/ath/ath5k/base.c | 1 + drivers/net/wireless/ath/ath9k/beacon.c | 1 + drivers/net/wireless/ath/ath9k/init.c | 1 + drivers/net/wireless/ath/ath9k/recv.c | 1 + drivers/net/wireless/ath/ath9k/xmit.c | 1 + drivers/staging/pohmelfs/crypto.c | 1 + drivers/tty/serial/ifx6x60.c | 1 + drivers/usb/gadget/f_phonet.c | 1 + include/crypto/if_alg.h | 1 + include/linux/dma-direction.h | 13 +++++++++++++ include/linux/dma-mapping.h | 10 +--------- include/linux/dmaengine.h | 4 +++- include/linux/netdevice.h | 1 - net/sched/sch_netem.c | 1 + security/apparmor/lib.c | 1 + 66 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 include/linux/dma-direction.h (limited to 'drivers/net') diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 606a6f27ed6..5f5d7830887 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 1e0f809644b..e00d61e2efb 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -8,6 +8,7 @@ * is licensed "as is" without any warranty of any kind, whether express * or implied. */ +#include #include #include #include diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index 1bd73a04be2..04c49f7543e 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -17,6 +17,7 @@ #include #include +#include #include #include diff --git a/arch/arm/mach-imx/dma-v1.c b/arch/arm/mach-imx/dma-v1.c index 236f1495efa..f8aa5be0eb1 100644 --- a/arch/arm/mach-imx/dma-v1.c +++ b/arch/arm/mach-imx/dma-v1.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index 9b982449cb5..b5ecc26d08a 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c index 5c147fb66a0..a5b989728b9 100644 --- a/arch/arm/mach-iop13xx/setup.c +++ b/arch/arm/mach-iop13xx/setup.c @@ -17,6 +17,7 @@ * */ +#include #include #include #ifdef CONFIG_MTD_PHYSMAP diff --git a/arch/arm/mach-mxs/devices/platform-auart.c b/arch/arm/mach-mxs/devices/platform-auart.c index 796606cce0c..27608f5d2ac 100644 --- a/arch/arm/mach-mxs/devices/platform-auart.c +++ b/arch/arm/mach-mxs/devices/platform-auart.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include #include diff --git a/arch/arm/mach-mxs/devices/platform-dma.c b/arch/arm/mach-mxs/devices/platform-dma.c index 295c4424d5d..6a0202b1016 100644 --- a/arch/arm/mach-mxs/devices/platform-dma.c +++ b/arch/arm/mach-mxs/devices/platform-dma.c @@ -6,6 +6,7 @@ * Free Software Foundation. */ #include +#include #include #include diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c index 9859cf28333..ae96a4fd8f1 100644 --- a/arch/arm/mach-mxs/devices/platform-fec.c +++ b/arch/arm/mach-mxs/devices/platform-fec.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include #include diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c index ccc789e21da..4fc6ffc2a13 100644 --- a/arch/arm/plat-mxc/devices/platform-fec.c +++ b/arch/arm/plat-mxc/devices/platform-fec.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include #include diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c index 59c33f6e401..23ce08e6ffd 100644 --- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c +++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include diff --git a/arch/arm/plat-mxc/devices/platform-imx-fb.c b/arch/arm/plat-mxc/devices/platform-imx-fb.c index 79a1cb18a5b..2b0b5e0aa99 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-fb.c +++ b/arch/arm/plat-mxc/devices/platform-imx-fb.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include diff --git a/arch/arm/plat-mxc/devices/platform-ipu-core.c b/arch/arm/plat-mxc/devices/platform-ipu-core.c index edf65034aea..79d340ae0af 100644 --- a/arch/arm/plat-mxc/devices/platform-ipu-core.c +++ b/arch/arm/plat-mxc/devices/platform-ipu-core.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c index cc488f4b620..e1763e03e7c 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c +++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include diff --git a/arch/arm/plat-mxc/devices/platform-mxc-mmc.c b/arch/arm/plat-mxc/devices/platform-mxc-mmc.c index 90d762f6f93..540d3a7d92d 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc-mmc.c +++ b/arch/arm/plat-mxc/devices/platform-mxc-mmc.c @@ -6,6 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h index c44886062f8..685c78716d9 100644 --- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -10,6 +10,7 @@ #define STE_DMA40_H #include +#include #include #include diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 30ac65df7d4..e07a2fc876b 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/crypto/async_tx/raid6test.c b/crypto/async_tx/raid6test.c index c1321935ebc..c88ff9e3fd3 100644 --- a/crypto/async_tx/raid6test.c +++ b/crypto/async_tx/raid6test.c @@ -21,6 +21,7 @@ */ #include #include +#include #include #undef pr diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index af8c0b5ed70..a92d95eac86 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -11,6 +11,7 @@ #include #include /* printk() */ #include /* everything... */ +#include #include /* kmalloc() */ #include #include diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 8bcb15fb959..48694c34d96 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -45,6 +45,7 @@ * See Documentation/dmaengine.txt for more details */ +#include #include #include #include diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index b4f5c32b6a4..765f5ff2230 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ #include +#include #include #include #include diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index c1a125e7d1d..fd7d2b308cf 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 8f222d4db7d..29d1addbe0c 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -6,6 +6,7 @@ * License terms: GNU General Public License (GPL) version 2 */ +#include #include #include #include diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c index 330216febd7..3d704690900 100644 --- a/drivers/media/dvb/mantis/mantis_ca.c +++ b/drivers/media/dvb/mantis/mantis_ca.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c index 9f73c2cfc9e..36f2256ebb0 100644 --- a/drivers/media/dvb/mantis/mantis_evm.c +++ b/drivers/media/dvb/mantis/mantis_evm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c index 5772ebb3a69..672cf4d2462 100644 --- a/drivers/media/dvb/mantis/mantis_hif.c +++ b/drivers/media/dvb/mantis/mantis_hif.c @@ -23,6 +23,7 @@ #include #include +#include #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c index 479086dbb9a..24fcdc63d6d 100644 --- a/drivers/media/dvb/mantis/mantis_ioc.c +++ b/drivers/media/dvb/mantis/mantis_ioc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/dvb/mantis/mantis_pcmcia.c index 5cb545b913f..2f188c08966 100644 --- a/drivers/media/dvb/mantis/mantis_pcmcia.c +++ b/drivers/media/dvb/mantis/mantis_pcmcia.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c index f807c8ba26e..18340dafa42 100644 --- a/drivers/media/dvb/mantis/mantis_uart.c +++ b/drivers/media/dvb/mantis/mantis_uart.c @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c index 26bc0cbe84d..430ae84ce52 100644 --- a/drivers/media/dvb/mantis/mantis_vp1034.c +++ b/drivers/media/dvb/mantis/mantis_vp1034.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c index 25f1ad6cbe0..bf12513d629 100644 --- a/drivers/mmc/host/tmio_mmc_dma.c +++ b/drivers/mmc/host/tmio_mmc_dma.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index b300705d41c..1b90fd56bef 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -22,6 +22,7 @@ * */ +#include #include #include #include diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index bb62b3f5183..c827a6097d0 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -16,6 +16,7 @@ * Vincent Sanders */ +#include #include #include #include diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 69fc7280be3..eff78a439ee 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -14,6 +14,7 @@ #ifndef BNX2X_H #define BNX2X_H #include +#include #include /* compilation time flags */ diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index f1942cab35f..32778d56d33 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -22,6 +22,7 @@ #include #include +#include /* the DPM has 64k of memory, organized into 256x 256 byte pages */ #define DPM_NUM_PAGES 256 diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c index b520784fb19..31059617567 100644 --- a/drivers/net/can/softing/softing_fw.c +++ b/drivers/net/can/softing/softing_fw.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "softing.h" diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 60a49e5a2a5..954b2959b6b 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "softing.h" diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 0e8cc75bb5f..0da6295d9da 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -11,6 +11,7 @@ * Written by Thierry Reding */ +#include #include #include #include diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index cecc3b1eb48..381bdea97d5 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -14,6 +14,7 @@ * */ +#include #include #include diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 69b86d7fac8..82c3767ec5f 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -22,6 +22,7 @@ * Marko Isomaki */ +#include #include #include #include diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index b1d1ce3dd8b..d0851dfa037 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -12,6 +12,7 @@ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor * */ +#include #include #include #include diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index aefbdd896d6..a82378231fc 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -35,6 +35,7 @@ #include #include #include +#include #define DRV_NAME "ks8851_mll" diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 54415c7b84a..52fb7ed9f36 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -6,6 +6,7 @@ #undef DEBUG +#include #include #include #include diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index f20455cbfbb..0f63b3c83c1 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -28,6 +28,7 @@ #include #include +#include #include "dwmac1000.h" static void dwmac1000_core_init(void __iomem *ioaddr) diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c index 2c47712d45d..3dbeea61908 100644 --- a/drivers/net/stmmac/dwmac1000_dma.c +++ b/drivers/net/stmmac/dwmac1000_dma.c @@ -26,6 +26,7 @@ Author: Giuseppe Cavallaro *******************************************************************************/ +#include #include "dwmac1000.h" #include "dwmac_dma.h" diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c index c724fc36a24..743a5801763 100644 --- a/drivers/net/stmmac/dwmac100_core.c +++ b/drivers/net/stmmac/dwmac100_core.c @@ -29,6 +29,7 @@ *******************************************************************************/ #include +#include #include "dwmac100.h" static void dwmac100_core_init(void __iomem *ioaddr) diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c index e3e224b7d9e..627f656b0f3 100644 --- a/drivers/net/stmmac/dwmac100_dma.c +++ b/drivers/net/stmmac/dwmac100_dma.c @@ -28,6 +28,7 @@ Author: Giuseppe Cavallaro *******************************************************************************/ +#include #include "dwmac100.h" #include "dwmac_dma.h" diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index 720c5a1531b..7ed8fb6c211 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "stmmac.h" #include "dwmac_dma.h" diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index 234b4068a1f..29a6bb6b805 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "stmmac.h" diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index f967913e11b..a60d0069cc4 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 6219006d9d2..dd362584f5c 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -16,6 +16,7 @@ #include #include #include +#include #ifndef VXGE_CACHE_LINE_SIZE #define VXGE_CACHE_LINE_SIZE 128 diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b6c5d3715b9..779a1d27024 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 0174cdb65a8..4c790b5f793 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "ath9k.h" #define FUDGE 2 diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d4b166cfdf6..1202bb0a553 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 07e35e59c9e..c4c5d9f455b 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "ath9k.h" #include "ar9003_mac.h" diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index ec012b4317a..7e79bbaf2ba 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "ath9k.h" #include "ar9003_mac.h" diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c index 5cca24fcf6c..ad92771dce5 100644 --- a/drivers/staging/pohmelfs/crypto.c +++ b/drivers/staging/pohmelfs/crypto.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "netfs.h" diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 5315525220f..426434e5eb7 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -36,6 +36,7 @@ * you need to use this driver for another platform. * *****************************************************************************/ +#include #include #include #include diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 5e1495097ec..f22fc685ddf 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -20,6 +20,7 @@ * 02110-1301 USA */ +#include #include #include #include diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index c5813c87de0..d61c1117021 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/include/linux/dma-direction.h b/include/linux/dma-direction.h new file mode 100644 index 00000000000..95b6a82f595 --- /dev/null +++ b/include/linux/dma-direction.h @@ -0,0 +1,13 @@ +#ifndef _LINUX_DMA_DIRECTION_H +#define _LINUX_DMA_DIRECTION_H +/* + * These definitions mirror those in pci.h, so they can be used + * interchangeably with their PCI_ counterparts. + */ +enum dma_data_direction { + DMA_BIDIRECTIONAL = 0, + DMA_TO_DEVICE = 1, + DMA_FROM_DEVICE = 2, + DMA_NONE = 3, +}; +#endif diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index ba8319ae5fc..1a167c48d84 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -4,17 +4,9 @@ #include #include #include +#include #include -/* These definitions mirror those in pci.h, so they can be used - * interchangeably with their PCI_ counterparts */ -enum dma_data_direction { - DMA_BIDIRECTIONAL = 0, - DMA_TO_DEVICE = 1, - DMA_FROM_DEVICE = 2, - DMA_NONE = 3, -}; - struct dma_map_ops { void* (*alloc_coherent)(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index eee7addec28..8fbf40e0713 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -23,7 +23,9 @@ #include #include -#include +#include + +struct scatterlist; /** * typedef dma_cookie_t - an opaque DMA cookie diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 22a8ceca0ed..011eb89e958 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 69c35f6cd13..eb3b9a86c6e 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -13,6 +13,7 @@ * Catalin(ux aka Dino) BOIE */ +#include #include #include #include diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 506d2baf614..b82e383beb7 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c @@ -12,6 +12,7 @@ * License. */ +#include #include #include #include -- cgit v1.2.3-70-g09d2 From f470e5ae34d68880a38aa79ee5c102ebc2a1aef6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 21 Jun 2011 20:32:53 -0700 Subject: irda: fix smsc-ircc2 section mismatch warning Fix section mismatch warning: WARNING: drivers/net/irda/smsc-ircc2.o(.devinit.text+0x1a7): Section mismatch in reference from the function smsc_ircc_pnp_probe() to the function .init.text:smsc_ircc_open() Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/irda/smsc-ircc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index d5072af81b2..954f6e938fb 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -516,7 +516,7 @@ static const struct net_device_ops smsc_ircc_netdev_ops = { * Try to open driver instance * */ -static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) +static int __devinit smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) { struct smsc_ircc_cb *self; struct net_device *dev; -- cgit v1.2.3-70-g09d2 From 56f8a75c17abb854b5907f4a815dc4c3f186ba11 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 21 Jun 2011 20:33:34 -0700 Subject: ip: introduce ip_is_fragment helper inline function There are enough instances of this: iph->frag_off & htons(IP_MF | IP_OFFSET) that a helper function is probably warranted. Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- drivers/net/ioc3-eth.c | 2 +- drivers/net/myri10ge/myri10ge.c | 2 +- drivers/net/s2io.c | 2 +- drivers/net/sfc/filter.c | 2 +- drivers/net/vxge/vxge-main.c | 2 +- include/net/ip.h | 5 +++++ net/core/dev.c | 2 +- net/ipv4/ip_input.c | 4 ++-- net/ipv4/ip_output.c | 2 +- net/ipv4/ipconfig.c | 2 +- net/ipv4/netfilter/nf_defrag_ipv4.c | 2 +- net/ipv4/netfilter/nf_nat_standalone.c | 2 +- net/ipv4/xfrm4_policy.c | 2 +- net/netfilter/ipvs/ip_vs_core.c | 7 +++---- net/sched/cls_flow.c | 4 ++-- net/sched/cls_rsvp.h | 2 +- net/sched/sch_choke.c | 2 +- net/sched/sch_sfq.c | 2 +- 19 files changed, 27 insertions(+), 23 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d117280b9cd..ebb1d219b45 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3438,7 +3438,7 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) int layer4_xor = 0; if (skb->protocol == htons(ETH_P_IP)) { - if (!(iph->frag_off & htons(IP_MF|IP_OFFSET)) && + if (!ip_is_fragment(iph) && (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)) { layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1))); diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 32f07f868d8..318a25a9231 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -532,7 +532,7 @@ static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len) return; ih = (struct iphdr *) ((char *)eh + ETH_HLEN); - if (ih->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(ih)) return; proto = ih->protocol; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 3e89a842fc5..3ed5f3505ce 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2257,7 +2257,7 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, *ip_hdr = iph; if (iph->protocol != IPPROTO_TCP) return -1; - if (iph->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(iph)) return -1; *hdr_flags |= LRO_TCP; *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index f4d80f9050e..043850b8c30 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -4109,7 +4109,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) struct tcphdr *th; ip = ip_hdr(skb); - if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) { + if (!ip_is_fragment(ip)) { th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index 95a980fd63d..f2fc2587c09 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -652,7 +652,7 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, /* RFS must validate the IP header length before calling us */ EFX_BUG_ON_PARANOID(!pskb_may_pull(skb, nhoff + sizeof(*ip))); ip = (const struct iphdr *)(skb->data + nhoff); - if (ip->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(ip)) return -EPROTONOSUPPORT; EFX_BUG_ON_PARANOID(!pskb_may_pull(skb, nhoff + 4 * ip->ihl + 4)); ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 54ca74806bb..1c92af39299 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -633,7 +633,7 @@ static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb) ip = ip_hdr(skb); - if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) { + if (!ip_is_fragment(ip)) { th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); diff --git a/include/net/ip.h b/include/net/ip.h index e9ea7c73f8c..d603cd329c4 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -250,6 +250,11 @@ int ip_decrease_ttl(struct iphdr *iph) return --iph->ttl; } +static inline bool ip_is_fragment(const struct iphdr *iph) +{ + return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; +} + static inline int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) { diff --git a/net/core/dev.c b/net/core/dev.c index 8efe8507013..6b6ef14b42f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2532,7 +2532,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb) goto done; ip = (const struct iphdr *) (skb->data + nhoff); - if (ip->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(ip)) ip_proto = 0; else ip_proto = ip->protocol; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index c8f48efc5fd..073a9b01c40 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -165,7 +165,7 @@ int ip_call_ra_chain(struct sk_buff *skb) (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dev->ifindex) && net_eq(sock_net(sk), dev_net(dev))) { - if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { + if (ip_is_fragment(ip_hdr(skb))) { if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) return 1; } @@ -256,7 +256,7 @@ int ip_local_deliver(struct sk_buff *skb) * Reassemble IP fragments. */ - if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { + if (ip_is_fragment(ip_hdr(skb))) { if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER)) return 0; } diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index a8024eaa0e8..167da8ba416 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -489,7 +489,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) if (first_len - hlen > mtu || ((first_len - hlen) & 7) || - (iph->frag_off & htons(IP_MF|IP_OFFSET)) || + ip_is_fragment(iph) || skb_cloned(skb)) goto slow_path; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index ab7e5542c1c..ae93dd5ef40 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -932,7 +932,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str goto drop; /* Fragments are not supported */ - if (h->frag_off & htons(IP_OFFSET | IP_MF)) { + if (ip_is_fragment(h)) { if (net_ratelimit()) printk(KERN_ERR "DHCP/BOOTP: Ignoring fragmented " "reply.\n"); diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index f3a9b42b16c..9bb1b8a37a2 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c @@ -82,7 +82,7 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, #endif #endif /* Gather fragments. */ - if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { + if (ip_is_fragment(ip_hdr(skb))) { enum ip_defrag_users user = nf_ct_defrag_user(hooknum, skb); if (nf_ct_ipv4_gather_frags(skb, user)) return NF_STOLEN; diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index 483b76d042d..a6e606e8482 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c @@ -88,7 +88,7 @@ nf_nat_fn(unsigned int hooknum, /* We never see fragments: conntrack defrags on pre-routing and local-out, and nf_nat_out protects post-routing. */ - NF_CT_ASSERT(!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET))); + NF_CT_ASSERT(!ip_is_fragment(ip_hdr(skb))); ct = nf_ct_get(skb, &ctinfo); /* Can't track? It's not due to stress, or conntrack would diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 981e43eaf70..fc5368ad2b0 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -117,7 +117,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) memset(fl4, 0, sizeof(struct flowi4)); fl4->flowi4_mark = skb->mark; - if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) { + if (!ip_is_fragment(iph)) { switch (iph->protocol) { case IPPROTO_UDP: case IPPROTO_UDPLITE: diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index e33d48cae9f..4f77bb16d22 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -852,7 +852,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related, *related = 1; /* reassemble IP fragments */ - if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { + if (ip_is_fragment(ip_hdr(skb))) { if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -1156,8 +1156,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); } else #endif - if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) && - !pp->dont_defrag)) { + if (unlikely(ip_is_fragment(ip_hdr(skb)) && !pp->dont_defrag)) { if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; @@ -1310,7 +1309,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) *related = 1; /* reassemble IP fragments */ - if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { + if (ip_is_fragment(ip_hdr(skb))) { if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 8ec01391d98..34533a5d1b3 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -121,7 +121,7 @@ static u32 flow_get_proto_src(struct sk_buff *skb) if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ip_hdr(skb); - if (iph->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(iph)) break; poff = proto_ports_offset(iph->protocol); if (poff >= 0 && @@ -163,7 +163,7 @@ static u32 flow_get_proto_dst(struct sk_buff *skb) if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ip_hdr(skb); - if (iph->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(iph)) break; poff = proto_ports_offset(iph->protocol); if (poff >= 0 && diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 402c44b241a..ed691b14838 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -167,7 +167,7 @@ restart: dst = &nhptr->daddr; protocol = nhptr->protocol; xprt = ((u8 *)nhptr) + (nhptr->ihl<<2); - if (nhptr->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(nhptr)) return -1; #endif diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 06afbaeb4c8..3422b25df9e 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -181,7 +181,7 @@ static bool choke_match_flow(struct sk_buff *skb1, ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr) return false; - if ((ip1->frag_off | ip2->frag_off) & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(ip1) | ip_is_fragment(ip2)) ip_proto = 0; off1 += ip1->ihl * 4; off2 += ip2->ihl * 4; diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index b6ea6afa55b..4536ee64383 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -157,7 +157,7 @@ static unsigned int sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) iph = ip_hdr(skb); h = (__force u32)iph->daddr; h2 = (__force u32)iph->saddr ^ iph->protocol; - if (iph->frag_off & htons(IP_MF | IP_OFFSET)) + if (ip_is_fragment(iph)) break; poff = proto_ports_offset(iph->protocol); if (poff >= 0 && -- cgit v1.2.3-70-g09d2 From e7c62552ec43c094ca523fc46b98181df364f49f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 19 Jun 2011 02:18:11 +0200 Subject: b43: HT-PHY: implement killing radio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closed drivers kill radio right after reading radio version and MACCTL, so it was easy to find related PHY ops: phy_read(0x0810) -> 0x0000 phy_write(0x0810) <- 0x0000 To find out the mask of above OP, MMIO hack was used to fake read val: phy_read(0x0810) -> 0xffff phy_write(0x0810) <- 0x0000 Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 15 +++++++++++++-- drivers/net/wireless/b43/phy_ht.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 5777cdbc047..e84d4c13535 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -59,6 +59,19 @@ static void b43_phy_ht_op_free(struct b43_wldev *dev) phy->ht = NULL; } +/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */ +static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, + bool blocked) +{ + if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) + b43err(dev->wl, "MAC not suspended\n"); + + if (blocked) { + b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); + } else { + } +} + static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) { if (on) { @@ -141,9 +154,7 @@ const struct b43_phy_operations b43_phyops_ht = { .phy_maskset = b43_phy_ht_op_maskset, .radio_read = b43_phy_ht_op_radio_read, .radio_write = b43_phy_ht_op_radio_write, - /* .software_rfkill = b43_phy_ht_op_software_rfkill, - */ .switch_analog = b43_phy_ht_op_switch_analog, /* .switch_channel = b43_phy_ht_op_switch_channel, diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 84ac47cbfaa..e16d4bbeb4b 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -8,6 +8,8 @@ #define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ #define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ +#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) + #define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) #define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111) #define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114) -- cgit v1.2.3-70-g09d2 From 1a3f71ae669a599139165c7ae6d8e7908fe12e64 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 19 Jun 2011 02:18:12 +0200 Subject: b43: HT-PHY: enable radio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The trick was to find 0x810 PHY reg ops close to analog enabling code. To find out proper masks and sets, MMIO hacks were used. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index e84d4c13535..008c1a96c2d 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -69,6 +69,10 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, if (blocked) { b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); } else { + b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); + b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1); + b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); + b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2); } } -- cgit v1.2.3-70-g09d2 From 5192bf56b9bb0d90c9aa08e5593ea4897309fc07 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 19 Jun 2011 12:17:19 +0200 Subject: b43: HT-PHY: define standard structs for channel switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/phy_ht.c | 1 + drivers/net/wireless/b43/phy_ht.h | 6 ++++++ drivers/net/wireless/b43/radio_2059.c | 30 ++++++++++++++++++++++++++++++ drivers/net/wireless/b43/radio_2059.h | 21 +++++++++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 drivers/net/wireless/b43/radio_2059.c create mode 100644 drivers/net/wireless/b43/radio_2059.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 58d614a889b..900dc9c8c68 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -11,6 +11,7 @@ b43-$(CONFIG_B43_PHY_N) += phy_n.o b43-$(CONFIG_B43_PHY_LP) += phy_lp.o b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o b43-$(CONFIG_B43_PHY_HT) += phy_ht.o +b43-$(CONFIG_B43_PHY_HT) += radio_2059.o b43-y += sysfs.o b43-y += xmit.o b43-y += lo.o diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 008c1a96c2d..763dbb0f417 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -24,6 +24,7 @@ #include "b43.h" #include "phy_ht.h" +#include "radio_2059.h" #include "main.h" /************************************************** diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index e16d4bbeb4b..afa448d6571 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -18,6 +18,12 @@ #define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119) +/* Values for PHY registers used on channel switching */ +struct b43_phy_ht_channeltab_e_phy { + /* TODO */ +}; + + struct b43_phy_ht { }; diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c new file mode 100644 index 00000000000..55d7da74f15 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2059.c @@ -0,0 +1,30 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n 2059 radio device data tables + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "radio_2059.h" + +const struct b43_phy_ht_channeltab_e_radio2059 +*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq) +{ + return NULL; +} diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h new file mode 100644 index 00000000000..69eb46ee376 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2059.h @@ -0,0 +1,21 @@ +#ifndef B43_RADIO_2059_H_ +#define B43_RADIO_2059_H_ + +#include + +#include "phy_ht.h" + +/* Values for various registers uploaded on channel switching */ +struct b43_phy_ht_channeltab_e_radio2059 { + /* The channel frequency in MHz */ + u16 freq; + /* Values for radio registers */ + /* TODO */ + /* Values for PHY registers */ + struct b43_phy_ht_channeltab_e_phy phy_regs; +}; + +const struct b43_phy_ht_channeltab_e_radio2059 +*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq); + +#endif /* B43_RADIO_2059_H_ */ -- cgit v1.2.3-70-g09d2 From 39ca554c96d25436b7c9acdd8f3b5fb9702049c6 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 19 Jun 2011 12:17:20 +0200 Subject: b43: HT-PHY: add place for implementing channel switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 61 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 763dbb0f417..12ad47f38df 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -27,6 +27,49 @@ #include "radio_2059.h" #include "main.h" +static void b43_radio_2059_channel_setup(struct b43_wldev *dev, + const struct b43_phy_ht_channeltab_e_radio2059 *e) +{ + /* TODO */ +} + +static void b43_phy_ht_channel_setup(struct b43_wldev *dev, + const struct b43_phy_ht_channeltab_e_phy *e, + struct ieee80211_channel *new_channel) +{ + /* TODO */ +} + +static int b43_phy_ht_set_channel(struct b43_wldev *dev, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type) +{ + struct b43_phy *phy = &dev->phy; + + const struct b43_phy_ht_channeltab_e_radio2059 *chent_r2059 = NULL; + + if (phy->radio_ver == 0x2059) { + chent_r2059 = b43_phy_ht_get_channeltab_e_r2059(dev, + channel->center_freq); + if (!chent_r2059) + return -ESRCH; + } else { + return -ESRCH; + } + + /* TODO: In case of N-PHY some bandwidth switching goes here */ + + if (phy->radio_ver == 0x2059) { + b43_radio_2059_channel_setup(dev, chent_r2059); + b43_phy_ht_channel_setup(dev, &(chent_r2059->phy_regs), + channel); + } else { + return -ESRCH; + } + + return 0; +} + /************************************************** * Basic PHY ops. **************************************************/ @@ -96,6 +139,22 @@ static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) } } +static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev, + unsigned int new_channel) +{ + struct ieee80211_channel *channel = dev->wl->hw->conf.channel; + enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; + + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if ((new_channel < 1) || (new_channel > 14)) + return -EINVAL; + } else { + return -EINVAL; + } + + return b43_phy_ht_set_channel(dev, channel, channel_type); +} + static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -161,9 +220,7 @@ const struct b43_phy_operations b43_phyops_ht = { .radio_write = b43_phy_ht_op_radio_write, .software_rfkill = b43_phy_ht_op_software_rfkill, .switch_analog = b43_phy_ht_op_switch_analog, - /* .switch_channel = b43_phy_ht_op_switch_channel, - */ .get_default_chan = b43_phy_ht_op_get_default_chan, /* .recalc_txpower = b43_phy_ht_op_recalc_txpower, -- cgit v1.2.3-70-g09d2 From a6b7da5d2cf8b67c310aedf09e8e74bfb53423ba Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 19 Jun 2011 12:17:21 +0200 Subject: b43: HT-PHY: switch radio to requested channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switching channel happens after specific SHM write to B43_SHM_SH_CHAN. This is the way we found it in BCM4331 MMIO dumps. By comparing with N-PHY code we noticed there is routing used for SYN and TX/RX. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 39 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/radio_2059.h | 30 ++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 12ad47f38df..0b13f6f37c2 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -30,6 +30,45 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, const struct b43_phy_ht_channeltab_e_radio2059 *e) { + u8 i; + u16 routing; + + b43_radio_write(dev, 0x16, e->radio_syn16); + b43_radio_write(dev, 0x17, e->radio_syn17); + b43_radio_write(dev, 0x22, e->radio_syn22); + b43_radio_write(dev, 0x25, e->radio_syn25); + b43_radio_write(dev, 0x27, e->radio_syn27); + b43_radio_write(dev, 0x28, e->radio_syn28); + b43_radio_write(dev, 0x29, e->radio_syn29); + b43_radio_write(dev, 0x2c, e->radio_syn2c); + b43_radio_write(dev, 0x2d, e->radio_syn2d); + b43_radio_write(dev, 0x37, e->radio_syn37); + b43_radio_write(dev, 0x41, e->radio_syn41); + b43_radio_write(dev, 0x43, e->radio_syn43); + b43_radio_write(dev, 0x47, e->radio_syn47); + b43_radio_write(dev, 0x4a, e->radio_syn4a); + b43_radio_write(dev, 0x58, e->radio_syn58); + b43_radio_write(dev, 0x5a, e->radio_syn5a); + b43_radio_write(dev, 0x6a, e->radio_syn6a); + b43_radio_write(dev, 0x6d, e->radio_syn6d); + b43_radio_write(dev, 0x6e, e->radio_syn6e); + b43_radio_write(dev, 0x92, e->radio_syn92); + b43_radio_write(dev, 0x98, e->radio_syn98); + + for (i = 0; i < 2; i++) { + routing = i ? 0x800 : 0x400; + b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a); + b43_radio_write(dev, routing | 0x58, e->radio_rxtx58); + b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a); + b43_radio_write(dev, routing | 0x6a, e->radio_rxtx6a); + b43_radio_write(dev, routing | 0x6d, e->radio_rxtx6d); + b43_radio_write(dev, routing | 0x6e, e->radio_rxtx6e); + b43_radio_write(dev, routing | 0x92, e->radio_rxtx92); + b43_radio_write(dev, routing | 0x98, e->radio_rxtx98); + } + + udelay(50); + /* TODO */ } diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h index 69eb46ee376..c2874b14526 100644 --- a/drivers/net/wireless/b43/radio_2059.h +++ b/drivers/net/wireless/b43/radio_2059.h @@ -10,7 +10,35 @@ struct b43_phy_ht_channeltab_e_radio2059 { /* The channel frequency in MHz */ u16 freq; /* Values for radio registers */ - /* TODO */ + u8 radio_syn16; + u8 radio_syn17; + u8 radio_syn22; + u8 radio_syn25; + u8 radio_syn27; + u8 radio_syn28; + u8 radio_syn29; + u8 radio_syn2c; + u8 radio_syn2d; + u8 radio_syn37; + u8 radio_syn41; + u8 radio_syn43; + u8 radio_syn47; + u8 radio_syn4a; + u8 radio_syn58; + u8 radio_syn5a; + u8 radio_syn6a; + u8 radio_syn6d; + u8 radio_syn6e; + u8 radio_syn92; + u8 radio_syn98; + u8 radio_rxtx4a; + u8 radio_rxtx58; + u8 radio_rxtx5a; + u8 radio_rxtx6a; + u8 radio_rxtx6d; + u8 radio_rxtx6e; + u8 radio_rxtx92; + u8 radio_rxtx98; /* Values for PHY registers */ struct b43_phy_ht_channeltab_e_phy phy_regs; }; -- cgit v1.2.3-70-g09d2 From 2a870831776dd37577c6aec7b86189645183e152 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 19 Jun 2011 13:30:20 +0200 Subject: b43: N-PHY: update switching analog on/off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specs were recently updated. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index ad14f3b428c..e7dfdac9e4d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -4025,11 +4025,24 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) { - u16 val = on ? 0 : 0x7FFF; + u16 override = on ? 0x0 : 0x7FFF; + u16 core = on ? 0xD : 0x00FD; - if (dev->phy.rev >= 3) - b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, val); - b43_phy_write(dev, B43_NPHY_AFECTL_OVER, val); + if (dev->phy.rev >= 3) { + if (on) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, core); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, core); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); + } else { + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override); + b43_phy_write(dev, B43_NPHY_AFECTL_C1, core); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, core); + } + } else { + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); + } } static int b43_nphy_op_switch_channel(struct b43_wldev *dev, -- cgit v1.2.3-70-g09d2 From 9c803a03bc07553f8148d024c15c784b28c1d9ee Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 19 Jun 2011 13:30:21 +0200 Subject: b43: N-PHY: move declarations of chantables functions to correct files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2055.h | 5 +++++ drivers/net/wireless/b43/radio_2056.h | 5 +++++ drivers/net/wireless/b43/tables_nphy.h | 8 -------- 3 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h index d9bfa0f21b7..67f96122f8d 100644 --- a/drivers/net/wireless/b43/radio_2055.h +++ b/drivers/net/wireless/b43/radio_2055.h @@ -251,4 +251,9 @@ struct b43_nphy_channeltab_entry_rev2 { void b2055_upload_inittab(struct b43_wldev *dev, bool ghz5, bool ignore_uploadflag); +/* Get the NPHY Channel Switch Table entry for a channel. + * Returns NULL on failure to find an entry. */ +const struct b43_nphy_channeltab_entry_rev2 * +b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); + #endif /* B43_RADIO_2055_H_ */ diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index d601f6e7e31..d52df6be705 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h @@ -1117,4 +1117,9 @@ struct b43_nphy_channeltab_entry_rev3 { void b2056_upload_inittabs(struct b43_wldev *dev, bool ghz5, bool ignore_uploadflag); +/* Get the NPHY Channel Switch Table entry for a channel. + * Returns NULL on failure to find an entry. */ +const struct b43_nphy_channeltab_entry_rev3 * +b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); + #endif /* B43_RADIO_2056_H_ */ diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 18569367ce4..a81696bff0e 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -60,16 +60,8 @@ struct nphy_gain_ctl_workaround_entry { struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( struct b43_wldev *dev, bool ghz5, bool ext_lna); -/* Get the NPHY Channel Switch Table entry for a channel. - * Returns NULL on failure to find an entry. */ -const struct b43_nphy_channeltab_entry_rev2 * -b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); -const struct b43_nphy_channeltab_entry_rev3 * -b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); - /* The N-PHY tables. */ - #define B43_NTAB_TYPEMASK 0xF0000000 #define B43_NTAB_8BIT 0x10000000 #define B43_NTAB_16BIT 0x20000000 -- cgit v1.2.3-70-g09d2 From 7f503fc49f144bb509dbd33daf3426df3f176e6b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 19 Jun 2011 19:46:02 +0200 Subject: rt2x00: fix possible memory corruption in case of invalid rxdesc.size Sometimes rxdesc descriptor provided by hardware contains invalid (random) data. For example rxdesc.size can be bigger than actual size of the buffer. When this happen rt2x00crypto_rx_insert_iv() corrupt memory doing memmove outside of buffer boundaries. Signed-off-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 939821b4af2..0955c941317 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -582,6 +582,18 @@ void rt2x00lib_rxdone(struct queue_entry *entry) memset(&rxdesc, 0, sizeof(rxdesc)); rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); + /* + * Check for valid size in case we get corrupted descriptor from + * hardware. + */ + if (unlikely(rxdesc.size == 0 || + rxdesc.size > entry->queue->data_size)) { + WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", + rxdesc.size, entry->queue->data_size); + dev_kfree_skb(entry->skb); + goto renew_skb; + } + /* * The data behind the ieee80211 header must be * aligned on a 4 byte boundary. @@ -642,6 +654,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry) ieee80211_rx_ni(rt2x00dev->hw, entry->skb); +renew_skb: /* * Replace the skb with the freshly allocated one. */ -- cgit v1.2.3-70-g09d2 From bf4c02d5e772903be5bf8952bac730a2956d0619 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 19 Jun 2011 19:47:39 +0200 Subject: rt2x00: reset usb devices at probe When module is reloaded, device may fail to work, with messages: [ 342.211926] phy40 -> rt2x00lib_rxdone_read_signal: Warning - Frame received with unrecognized signal, mode=0x0000, signal=0x0059, type=2. [ 342.314254] phy40 -> rt2x00lib_rxdone_read_signal: Warning - Frame received with unrecognized signal, mode=0x0000, signal=0x004a, type=2. [ 342.416458] phy40 -> rt2x00lib_rxdone: Warning - Wrong frame size 3183 max 2432. [ 342.518605] phy40 -> rt2x00lib_rxdone_read_signal: Warning - Frame received with unrecognized signal, mode=0x0000, signal=0x00c9, type=2. [ 342.620836] phy40 -> rt2x00lib_rxdone_read_signal: Warning - Frame received with unrecognized signal, mode=0x0000, signal=0x00ae, type=1. [ 342.723201] phy40 -> rt2x00lib_rxdone: Warning - Wrong frame size 0 max 2432. [ 342.825399] phy40 -> rt2x00lib_rxdone: Warning - Wrong frame size 0 max 2432. [ 342.927624] phy40 -> rt2x00lib_rxdone: Warning - Wrong frame size 0 max 2432. [ 343.029804] phy40 -> rt2x00lib_rxdone: Warning - Wrong frame size 2491 max 2432. [ 343.132008] phy40 -> rt2x00lib_rxdone: Warning - Wrong frame size 2576 max 2432. [ 343.234326] phy40 -> rt2x00lib_rxdone_read_signal: Warning - Frame received with unrecognized signal, mode=0x0000, signal=0x004c, type=1. [ 343.438723] phy40 -> rt2x00lib_rxdone_read_signal: Warning - Frame received with unrecognized signal, mode=0x0000, signal=0x00e6, type=1. Whereas replugging device make it functional. To solve that problem force reset device during probe. With patch messages are gone. Unfortunately device may sometimes still does not operate correctly after module reload (fail to receive data after associate), but such cases are rarer than without the patch. Signed-off-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 8f90f626807..b6b4542c246 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -802,6 +802,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, int retval; usb_dev = usb_get_dev(usb_dev); + usb_reset_device(usb_dev); hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); if (!hw) { -- cgit v1.2.3-70-g09d2 From c1c3daee97498f5d74bfd23531cfe23c8e14a619 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 20 Jun 2011 03:12:19 +0200 Subject: b43: HT-PHY: calibrate radio after switching channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After uploading radio values calibration goes in. In MMIO dump it is: radio_read(0x002b) -> 0x0008 radio_write(0x002b) <- 0x0008 radio_read(0x002e) -> 0x0004 radio_write(0x002e) <- 0x0000 radio_read(0x002e) -> 0x0000 radio_write(0x002e) <- 0x0004 radio_read(0x002b) -> 0x0008 radio_write(0x002b) <- 0x0009 To find masks and sets, MMIO hacks were used to fool closed driver. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 0b13f6f37c2..72f01ce8b42 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -69,7 +69,13 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, udelay(50); - /* TODO */ + /* Calibration */ + b43_radio_mask(dev, 0x2b, ~0x1); + b43_radio_mask(dev, 0x2e, ~0x4); + b43_radio_set(dev, 0x2e, 0x4); + b43_radio_set(dev, 0x2b, 0x1); + + udelay(300); } static void b43_phy_ht_channel_setup(struct b43_wldev *dev, -- cgit v1.2.3-70-g09d2 From 7a1d6564a15183cb5994656040966df09af8390f Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 20 Jun 2011 14:42:28 +0300 Subject: zd1211rw: fix invalid signal values from device Driver uses IEEE80211_HW_SIGNAL_UNSPEC and so signal values reported to mac80211 should be in range 0..100. Sometimes device return out of range values. These out of range values can then trigger warning in cfg80211_inform_bss_frame. This patch adds checks to enforce range returned from driver to mac80211 be in 0..100 range. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_def.h | 6 ++++++ drivers/net/wireless/zd1211rw/zd_mac.c | 20 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h index 5463ca9ebc0..9a1b013f81b 100644 --- a/drivers/net/wireless/zd1211rw/zd_def.h +++ b/drivers/net/wireless/zd1211rw/zd_def.h @@ -37,9 +37,15 @@ typedef u16 __nocast zd_addr_t; if (net_ratelimit()) \ dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \ } while (0) +# define dev_dbg_f_cond(dev, cond, fmt, args...) ({ \ + bool __cond = !!(cond); \ + if (unlikely(__cond)) \ + dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \ +}) #else # define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0) # define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0) +# define dev_dbg_f_cond(dev, cond, fmt, args...) do { (void)(dev); } while (0) #endif /* DEBUG */ #ifdef DEBUG diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 5037c8b2b41..5de28bf6fa5 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -160,6 +160,22 @@ static int zd_reg2alpha2(u8 regdomain, char *alpha2) return 1; } +static int zd_check_signal(struct ieee80211_hw *hw, int signal) +{ + struct zd_mac *mac = zd_hw_mac(hw); + + dev_dbg_f_cond(zd_mac_dev(mac), signal < 0 || signal > 100, + "%s: signal value from device not in range 0..100, " + "but %d.\n", __func__, signal); + + if (signal < 0) + signal = 0; + else if (signal > 100) + signal = 100; + + return signal; +} + int zd_mac_preinit_hw(struct ieee80211_hw *hw) { int r; @@ -461,7 +477,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, if (istatus.rates[i].idx = -1; /* terminate */ - info->status.ack_signal = ackssi; + info->status.ack_signal = zd_check_signal(hw, ackssi); ieee80211_tx_status_irqsafe(hw, skb); } @@ -982,7 +998,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; stats.band = IEEE80211_BAND_2GHZ; - stats.signal = status->signal_strength; + stats.signal = zd_check_signal(hw, status->signal_strength); rate = zd_rx_rate(buffer, status); -- cgit v1.2.3-70-g09d2 From b405e1b83dc2bb662c4be2612674a8d0ef900e26 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 20 Jun 2011 14:42:33 +0300 Subject: zd1211rw: make 'handle_rx_packet: invalid, small RX packet' message debug-only This message is should be debug-only as it tells almost nothing useful. It also happens very often and just floods logs. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 631194d4982..621c2cc9fc8 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -579,8 +579,8 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, if (length < sizeof(struct rx_length_info)) { /* It's not a complete packet anyhow. */ - printk("%s: invalid, small RX packet : %d\n", - __func__, length); + dev_dbg_f(zd_usb_dev(usb), "invalid, small RX packet : %d\n", + length); return; } length_info = (struct rx_length_info *) -- cgit v1.2.3-70-g09d2 From f762d8c3f8b502b93d20bd755fc30ce99d3d0abd Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 20 Jun 2011 14:42:39 +0300 Subject: zd1211rw: only update HW beacon if new beacon differs from currect Update HW beacon only when needed. This appears to make device work in AP-mode (dtim_period=1) somewhat more stable. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 76 ++++++++++++++++++++++++++++------ drivers/net/wireless/zd1211rw/zd_mac.h | 1 + 2 files changed, 64 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 5de28bf6fa5..08286052370 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -403,10 +403,8 @@ int zd_restore_settings(struct zd_mac *mac) mac->type == NL80211_IFTYPE_AP) { if (mac->vif != NULL) { beacon = ieee80211_beacon_get(mac->hw, mac->vif); - if (beacon) { + if (beacon) zd_mac_config_beacon(mac->hw, beacon); - kfree_skb(beacon); - } } zd_set_beacon_interval(&mac->chip, beacon_interval, @@ -680,6 +678,32 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, /* FIXME: Management frame? */ } +static bool zd_mac_match_cur_beacon(struct zd_mac *mac, struct sk_buff *beacon) +{ + if (!mac->beacon.cur_beacon) + return false; + + if (mac->beacon.cur_beacon->len != beacon->len) + return false; + + return !memcmp(beacon->data, mac->beacon.cur_beacon->data, beacon->len); +} + +static void zd_mac_free_cur_beacon_locked(struct zd_mac *mac) +{ + ZD_ASSERT(mutex_is_locked(&mac->chip.mutex)); + + kfree_skb(mac->beacon.cur_beacon); + mac->beacon.cur_beacon = NULL; +} + +static void zd_mac_free_cur_beacon(struct zd_mac *mac) +{ + mutex_lock(&mac->chip.mutex); + zd_mac_free_cur_beacon_locked(mac); + mutex_unlock(&mac->chip.mutex); +} + static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) { struct zd_mac *mac = zd_hw_mac(hw); @@ -690,13 +714,21 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) unsigned long end_jiffies, message_jiffies; struct zd_ioreq32 *ioreqs; + mutex_lock(&mac->chip.mutex); + + /* Check if hw already has this beacon. */ + if (zd_mac_match_cur_beacon(mac, beacon)) { + r = 0; + goto out_nofree; + } + /* Alloc memory for full beacon write at once. */ num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL); - if (!ioreqs) - return -ENOMEM; - - mutex_lock(&mac->chip.mutex); + if (!ioreqs) { + r = -ENOMEM; + goto out_nofree; + } r = zd_iowrite32_locked(&mac->chip, 0, CR_BCN_FIFO_SEMAPHORE); if (r < 0) @@ -773,9 +805,19 @@ release_sema: if (r < 0 || ret < 0) { if (r >= 0) r = ret; + + /* We don't know if beacon was written successfully or not, + * so clear current. */ + zd_mac_free_cur_beacon_locked(mac); + goto out; } + /* Beacon has now been written successfully, update current. */ + zd_mac_free_cur_beacon_locked(mac); + mac->beacon.cur_beacon = beacon; + beacon = NULL; + /* 802.11b/g 2.4G CCK 1Mb * 802.11a, not yet implemented, uses different values (see GPL vendor * driver) @@ -783,11 +825,17 @@ release_sema: r = zd_iowrite32_locked(&mac->chip, 0x00000400 | (full_len << 19), CR_BCN_PLCP_CFG); out: - mutex_unlock(&mac->chip.mutex); kfree(ioreqs); +out_nofree: + kfree_skb(beacon); + mutex_unlock(&mac->chip.mutex); + return r; reset_device: + zd_mac_free_cur_beacon_locked(mac); + kfree_skb(beacon); + mutex_unlock(&mac->chip.mutex); kfree(ioreqs); @@ -1073,6 +1121,8 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, mac->vif = NULL; zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED); zd_write_mac_addr(&mac->chip, NULL); + + zd_mac_free_cur_beacon(mac); } static int zd_op_config(struct ieee80211_hw *hw, u32 changed) @@ -1110,10 +1160,8 @@ static void zd_beacon_done(struct zd_mac *mac) * Fetch next beacon so that tim_count is updated. */ beacon = ieee80211_beacon_get(mac->hw, mac->vif); - if (beacon) { + if (beacon) zd_mac_config_beacon(mac->hw, beacon); - kfree_skb(beacon); - } spin_lock_irq(&mac->lock); mac->beacon.last_update = jiffies; @@ -1240,7 +1288,6 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, zd_chip_disable_hwint(&mac->chip); zd_mac_config_beacon(hw, beacon); zd_chip_enable_hwint(&mac->chip); - kfree_skb(beacon); } } @@ -1390,8 +1437,9 @@ static void beacon_watchdog_handler(struct work_struct *work) beacon = ieee80211_beacon_get(mac->hw, mac->vif); if (beacon) { + zd_mac_free_cur_beacon(mac); + zd_mac_config_beacon(mac->hw, beacon); - kfree_skb(beacon); } zd_set_beacon_interval(&mac->chip, interval, period, mac->type); @@ -1426,6 +1474,8 @@ static void beacon_disable(struct zd_mac *mac) { dev_dbg_f(zd_mac_dev(mac), "\n"); cancel_delayed_work_sync(&mac->beacon.watchdog_work); + + zd_mac_free_cur_beacon(mac); } #define LINK_LED_WORK_DELAY HZ diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index f8c93c3fe75..c01eca859f9 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -165,6 +165,7 @@ struct housekeeping { struct beacon { struct delayed_work watchdog_work; + struct sk_buff *cur_beacon; unsigned long last_update; u16 interval; u8 period; -- cgit v1.2.3-70-g09d2 From c900eff30a14ecf209ee7a17a7c3c54890694ce6 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 20 Jun 2011 14:42:44 +0300 Subject: zd1211rw: handle lost read-reg interrupts Device losses read-reg interrupts. By looking at usbmon it appears that USB_INT_ID_RETRY_FAILED can override USB_INT_ID_REGS. This causes read command to timeout, usually under heavy TX. Fix by retrying read registers again if USB_INT_ID_RETRY_FAILED is received while waiting for USB_INT_ID_REGS. However USB_INT_ID_REGS is not always lost but is received after USB_INT_ID_RETRY_FAILED and is usually received by the retried read command. USB_INT_ID_REGS of the retry is then left unhandled and might be received by next read command. Handle this by ignoring previous USB_INT_ID_REGS that doesn't match current read command request. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 125 +++++++++++++++++++++++++++------ drivers/net/wireless/zd1211rw/zd_usb.h | 5 +- 2 files changed, 109 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 621c2cc9fc8..cf0d69dd7be 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -111,6 +111,9 @@ MODULE_DEVICE_TABLE(usb, usb_ids); #define FW_ZD1211_PREFIX "zd1211/zd1211_" #define FW_ZD1211B_PREFIX "zd1211/zd1211b_" +static bool check_read_regs(struct zd_usb *usb, struct usb_req_read_regs *req, + unsigned int count); + /* USB device initialization */ static void int_urb_complete(struct urb *urb); @@ -365,6 +368,20 @@ exit: #define urb_dev(urb) (&(urb)->dev->dev) +static inline void handle_regs_int_override(struct urb *urb) +{ + struct zd_usb *usb = urb->context; + struct zd_usb_interrupt *intr = &usb->intr; + + spin_lock(&intr->lock); + if (atomic_read(&intr->read_regs_enabled)) { + atomic_set(&intr->read_regs_enabled, 0); + intr->read_regs_int_overridden = 1; + complete(&intr->read_regs.completion); + } + spin_unlock(&intr->lock); +} + static inline void handle_regs_int(struct urb *urb) { struct zd_usb *usb = urb->context; @@ -383,25 +400,45 @@ static inline void handle_regs_int(struct urb *urb) USB_MAX_EP_INT_BUFFER); spin_unlock(&mac->lock); schedule_work(&mac->process_intr); - } else if (intr->read_regs_enabled) { - intr->read_regs.length = len = urb->actual_length; - + } else if (atomic_read(&intr->read_regs_enabled)) { + len = urb->actual_length; + intr->read_regs.length = urb->actual_length; if (len > sizeof(intr->read_regs.buffer)) len = sizeof(intr->read_regs.buffer); + memcpy(intr->read_regs.buffer, urb->transfer_buffer, len); - intr->read_regs_enabled = 0; + + /* Sometimes USB_INT_ID_REGS is not overridden, but comes after + * USB_INT_ID_RETRY_FAILED. Read-reg retry then gets this + * delayed USB_INT_ID_REGS, but leaves USB_INT_ID_REGS of + * retry unhandled. Next read-reg command then might catch + * this wrong USB_INT_ID_REGS. Fix by ignoring wrong reads. + */ + if (!check_read_regs(usb, intr->read_regs.req, + intr->read_regs.req_count)) + goto out; + + atomic_set(&intr->read_regs_enabled, 0); + intr->read_regs_int_overridden = 0; complete(&intr->read_regs.completion); + goto out; } out: spin_unlock(&intr->lock); + + /* CR_INTERRUPT might override read_reg too. */ + if (int_num == CR_INTERRUPT && atomic_read(&intr->read_regs_enabled)) + handle_regs_int_override(urb); } static void int_urb_complete(struct urb *urb) { int r; struct usb_int_header *hdr; + struct zd_usb *usb; + struct zd_usb_interrupt *intr; switch (urb->status) { case 0: @@ -430,6 +467,14 @@ static void int_urb_complete(struct urb *urb) goto resubmit; } + /* USB_INT_ID_RETRY_FAILED triggered by tx-urb submit can override + * pending USB_INT_ID_REGS causing read command timeout. + */ + usb = urb->context; + intr = &usb->intr; + if (hdr->id != USB_INT_ID_REGS && atomic_read(&intr->read_regs_enabled)) + handle_regs_int_override(urb); + switch (hdr->id) { case USB_INT_ID_REGS: handle_regs_int(urb); @@ -1129,6 +1174,7 @@ static inline void init_usb_interrupt(struct zd_usb *usb) spin_lock_init(&intr->lock); intr->interval = int_urb_interval(zd_usb_to_usbdev(usb)); init_completion(&intr->read_regs.completion); + atomic_set(&intr->read_regs_enabled, 0); intr->read_regs.cr_int_addr = cpu_to_le16((u16)CR_INTERRUPT); } @@ -1563,12 +1609,16 @@ static int usb_int_regs_length(unsigned int count) return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); } -static void prepare_read_regs_int(struct zd_usb *usb) +static void prepare_read_regs_int(struct zd_usb *usb, + struct usb_req_read_regs *req, + unsigned int count) { struct zd_usb_interrupt *intr = &usb->intr; spin_lock_irq(&intr->lock); - intr->read_regs_enabled = 1; + atomic_set(&intr->read_regs_enabled, 1); + intr->read_regs.req = req; + intr->read_regs.req_count = count; INIT_COMPLETION(intr->read_regs.completion); spin_unlock_irq(&intr->lock); } @@ -1578,22 +1628,18 @@ static void disable_read_regs_int(struct zd_usb *usb) struct zd_usb_interrupt *intr = &usb->intr; spin_lock_irq(&intr->lock); - intr->read_regs_enabled = 0; + atomic_set(&intr->read_regs_enabled, 0); spin_unlock_irq(&intr->lock); } -static int get_results(struct zd_usb *usb, u16 *values, - struct usb_req_read_regs *req, unsigned int count) +static bool check_read_regs(struct zd_usb *usb, struct usb_req_read_regs *req, + unsigned int count) { - int r; int i; struct zd_usb_interrupt *intr = &usb->intr; struct read_regs_int *rr = &intr->read_regs; struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; - spin_lock_irq(&intr->lock); - - r = -EIO; /* The created block size seems to be larger than expected. * However results appear to be correct. */ @@ -1601,13 +1647,14 @@ static int get_results(struct zd_usb *usb, u16 *values, dev_dbg_f(zd_usb_dev(usb), "error: actual length %d less than expected %d\n", rr->length, usb_int_regs_length(count)); - goto error_unlock; + return false; } + if (rr->length > sizeof(rr->buffer)) { dev_dbg_f(zd_usb_dev(usb), "error: actual length %d exceeds buffer size %zu\n", rr->length, sizeof(rr->buffer)); - goto error_unlock; + return false; } for (i = 0; i < count; i++) { @@ -1617,8 +1664,39 @@ static int get_results(struct zd_usb *usb, u16 *values, "rd[%d] addr %#06hx expected %#06hx\n", i, le16_to_cpu(rd->addr), le16_to_cpu(req->addr[i])); - goto error_unlock; + return false; } + } + + return true; +} + +static int get_results(struct zd_usb *usb, u16 *values, + struct usb_req_read_regs *req, unsigned int count, + bool *retry) +{ + int r; + int i; + struct zd_usb_interrupt *intr = &usb->intr; + struct read_regs_int *rr = &intr->read_regs; + struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; + + spin_lock_irq(&intr->lock); + + r = -EIO; + + /* Read failed because firmware bug? */ + *retry = !!intr->read_regs_int_overridden; + if (*retry) + goto error_unlock; + + if (!check_read_regs(usb, req, count)) { + dev_dbg_f(zd_usb_dev(usb), "error: invalid read regs\n"); + goto error_unlock; + } + + for (i = 0; i < count; i++) { + struct reg_data *rd = ®s->regs[i]; values[i] = le16_to_cpu(rd->value); } @@ -1631,11 +1709,11 @@ error_unlock: int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, const zd_addr_t *addresses, unsigned int count) { - int r; - int i, req_len, actual_req_len; + int r, i, req_len, actual_req_len, try_count = 0; struct usb_device *udev; struct usb_req_read_regs *req = NULL; unsigned long timeout; + bool retry = false; if (count < 1) { dev_dbg_f(zd_usb_dev(usb), "error: count is zero\n"); @@ -1671,8 +1749,10 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, for (i = 0; i < count; i++) req->addr[i] = cpu_to_le16((u16)addresses[i]); +retry_read: + try_count++; udev = zd_usb_to_usbdev(usb); - prepare_read_regs_int(usb); + prepare_read_regs_int(usb, req, count); r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); if (r) { dev_dbg_f(zd_usb_dev(usb), @@ -1696,7 +1776,12 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, goto error; } - r = get_results(usb, values, req, count); + r = get_results(usb, values, req, count, &retry); + if (retry && try_count < 20) { + dev_dbg_f(zd_usb_dev(usb), "read retry, tries so far: %d\n", + try_count); + goto retry_read; + } error: return r; } diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index bf942843b73..99193b456a7 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -144,6 +144,8 @@ struct usb_int_retry_fail { struct read_regs_int { struct completion completion; + struct usb_req_read_regs *req; + unsigned int req_count; /* Stores the USB int structure and contains the USB address of the * first requested register before request. */ @@ -169,7 +171,8 @@ struct zd_usb_interrupt { void *buffer; dma_addr_t buffer_dma; int interval; - u8 read_regs_enabled:1; + atomic_t read_regs_enabled; + u8 read_regs_int_overridden:1; }; static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) -- cgit v1.2.3-70-g09d2 From dde4673b8d73dd873e1a62774728e4b7f972facd Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 20 Jun 2011 14:42:49 +0300 Subject: zd1211rw: don't let zd_mac_config_beacon() run too long from beacon interrupt handler zd_mac_config_beacon() has only limited time to set up beacon when called from beacon interrupt handler/worker. So do not let it retry acquiring beacon fifo semaphore in interrupt handler. Beacon fifo semaphore should not be locked by firmware anyway at this time, it's only locked when device is using/txing beacon. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 08286052370..b67c52d9c36 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -143,7 +143,7 @@ static void beacon_enable(struct zd_mac *mac); static void beacon_disable(struct zd_mac *mac); static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble); static int zd_mac_config_beacon(struct ieee80211_hw *hw, - struct sk_buff *beacon); + struct sk_buff *beacon, bool in_intr); static int zd_reg2alpha2(u8 regdomain, char *alpha2) { @@ -404,7 +404,7 @@ int zd_restore_settings(struct zd_mac *mac) if (mac->vif != NULL) { beacon = ieee80211_beacon_get(mac->hw, mac->vif); if (beacon) - zd_mac_config_beacon(mac->hw, beacon); + zd_mac_config_beacon(mac->hw, beacon, false); } zd_set_beacon_interval(&mac->chip, beacon_interval, @@ -704,7 +704,8 @@ static void zd_mac_free_cur_beacon(struct zd_mac *mac) mutex_unlock(&mac->chip.mutex); } -static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) +static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon, + bool in_intr) { struct zd_mac *mac = zd_hw_mac(hw); int r, ret, num_cmds, req_pos = 0; @@ -736,6 +737,10 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE); if (r < 0) goto release_sema; + if (in_intr && tmp & 0x2) { + r = -EBUSY; + goto release_sema; + } end_jiffies = jiffies + HZ / 2; /*~500ms*/ message_jiffies = jiffies + HZ / 10; /*~100ms*/ @@ -790,7 +795,7 @@ release_sema: end_jiffies = jiffies + HZ / 2; /*~500ms*/ ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); while (ret < 0) { - if (time_is_before_eq_jiffies(end_jiffies)) { + if (in_intr || time_is_before_eq_jiffies(end_jiffies)) { ret = -ETIMEDOUT; break; } @@ -1161,7 +1166,7 @@ static void zd_beacon_done(struct zd_mac *mac) */ beacon = ieee80211_beacon_get(mac->hw, mac->vif); if (beacon) - zd_mac_config_beacon(mac->hw, beacon); + zd_mac_config_beacon(mac->hw, beacon, true); spin_lock_irq(&mac->lock); mac->beacon.last_update = jiffies; @@ -1286,7 +1291,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, if (beacon) { zd_chip_disable_hwint(&mac->chip); - zd_mac_config_beacon(hw, beacon); + zd_mac_config_beacon(hw, beacon, false); zd_chip_enable_hwint(&mac->chip); } } @@ -1439,7 +1444,7 @@ static void beacon_watchdog_handler(struct work_struct *work) if (beacon) { zd_mac_free_cur_beacon(mac); - zd_mac_config_beacon(mac->hw, beacon); + zd_mac_config_beacon(mac->hw, beacon, false); } zd_set_beacon_interval(&mac->chip, interval, period, mac->type); -- cgit v1.2.3-70-g09d2 From 55f7782e14032c70051aa92d882b4effda407ad5 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 20 Jun 2011 14:42:54 +0300 Subject: zd1211rw: detect stalled beacon interrupt faster As USB_INT_ID_RETRY_FAILED can override USB_INT_ID_REGS, beacon interrupt (CR_INTERRUPT) might be lost. Problem is that when device trigger CR_INTERRUPT it disables HW interrupt. Now if USB_INT_ID_REGS with CR_INTERRUPT gets lost, beacon interrupt stays disabled until beacon watchdog notices the stall. This happen very often on heavy TX. Improve watchdog to trigger earlier, after three missing beacon interrupts. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index b67c52d9c36..cabfae1e70b 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -1429,7 +1429,8 @@ static void beacon_watchdog_handler(struct work_struct *work) spin_lock_irq(&mac->lock); interval = mac->beacon.interval; period = mac->beacon.period; - timeout = mac->beacon.last_update + msecs_to_jiffies(interval) + HZ; + timeout = mac->beacon.last_update + + msecs_to_jiffies(interval * 1024 / 1000) * 3; spin_unlock_irq(&mac->lock); if (interval > 0 && time_is_before_jiffies(timeout)) { -- cgit v1.2.3-70-g09d2 From a5ffddb70c5cab29fa00e2fdf12217b64b940796 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 20 Jun 2011 15:21:48 -0700 Subject: mwifiex: remove casts of void pointers In some cases local pointers are used to cast void pointers passed to the function. Those unnecessary local pointers are also removed. This patch was inspired by Joe Perches' patch [PATCH net-next 1/2] wireless: Remove casts of void *; and the comments from Julian Calaby. Signed-off-by: Amitkumar Karwar Cc: Joe Perches Cc: Julian Calaby Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 33 ++++----- drivers/net/wireless/mwifiex/11n.h | 14 ++-- drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 +- drivers/net/wireless/mwifiex/11n_rxreorder.h | 5 +- drivers/net/wireless/mwifiex/cmdevt.c | 28 +++----- drivers/net/wireless/mwifiex/join.c | 23 +++--- drivers/net/wireless/mwifiex/main.c | 2 +- drivers/net/wireless/mwifiex/main.h | 16 ++--- drivers/net/wireless/mwifiex/scan.c | 6 +- drivers/net/wireless/mwifiex/sta_cmd.c | 101 ++++++++++++--------------- drivers/net/wireless/mwifiex/sta_cmdresp.c | 69 ++++++++---------- drivers/net/wireless/mwifiex/sta_rx.c | 2 +- drivers/net/wireless/mwifiex/txrx.c | 2 +- 13 files changed, 129 insertions(+), 177 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 916183d3900..34bba523429 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -185,13 +185,12 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, * * Handling includes changing the header fields into CPU format. */ -int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) +int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, + struct mwifiex_ds_11n_tx_cfg *tx_cfg) { - struct mwifiex_ds_11n_tx_cfg *tx_cfg; struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; - if (data_buf) { - tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf; + if (tx_cfg) { tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap); tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info); } @@ -208,11 +207,10 @@ int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) */ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, int cmd_action, - void *data_buf) + u16 *buf_size) { struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf; u16 action = (u16) cmd_action; - u16 buf_size = *((u16 *) data_buf); cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF); cmd->size = @@ -220,8 +218,8 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, tx_buf->action = cpu_to_le16(action); switch (action) { case HostCmd_ACT_GEN_SET: - dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size); - tx_buf->buff_size = cpu_to_le16(buf_size); + dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", *buf_size); + tx_buf->buff_size = cpu_to_le16(*buf_size); break; case HostCmd_ACT_GEN_GET: default: @@ -240,13 +238,12 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, - int cmd_action, void *data_buf) + int cmd_action, + struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl) { struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = &cmd->params.amsdu_aggr_ctrl; u16 action = (u16) cmd_action; - struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl = - (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl) @@ -272,15 +269,13 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, * Handling includes changing the header fields into CPU format. */ int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_11n_amsdu_aggr_ctrl + *amsdu_aggr_ctrl) { - struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl; struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = &resp->params.amsdu_aggr_ctrl; - if (data_buf) { - amsdu_aggr_ctrl = - (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; + if (amsdu_aggr_ctrl) { amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable); amsdu_aggr_ctrl->curr_buf_size = le16_to_cpu(amsdu_ctrl->curr_buf_size); @@ -296,12 +291,10 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, * - Setting HT Tx capability and HT Tx information fields * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, + struct mwifiex_ds_11n_tx_cfg *txcfg) { struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; - struct mwifiex_ds_11n_tx_cfg *txcfg = - (struct mwifiex_ds_11n_tx_cfg *) data_buf; cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN); diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index a4390a1a2a9..90b421e343d 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -29,9 +29,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, - void *data_buf); -int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf); + struct mwifiex_ds_11n_tx_cfg *tx_cfg); +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, + struct mwifiex_ds_11n_tx_cfg *txcfg); int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc, @@ -62,12 +62,14 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, struct mwifiex_ds_tx_ba_stream_tbl *buf); int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, - void *data_buf); + struct mwifiex_ds_11n_amsdu_aggr_ctrl + *amsdu_aggr_ctrl); int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - int cmd_action, void *data_buf); + int cmd_action, u16 *buf_size); int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, - int cmd_action, void *data_buf); + int cmd_action, + struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); /* * This function checks whether AMPDU is allowed or not for a particular TID. diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index e5dfdc39a92..7aa9aa0ac95 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -328,13 +328,12 @@ int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) */ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf) + struct host_cmd_ds_11n_addba_req + *cmd_addba_req) { struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = (struct host_cmd_ds_11n_addba_rsp *) &cmd->params.add_ba_rsp; - struct host_cmd_ds_11n_addba_req *cmd_addba_req = - (struct host_cmd_ds_11n_addba_req *) data_buf; u8 tid; int win_size; uint16_t block_ack_param_set; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index f3ca8c8c18f..033c8adbdcd 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -52,8 +52,9 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, - struct host_cmd_ds_command - *cmd, void *data_buf); + struct host_cmd_ds_command *cmd, + struct host_cmd_ds_11n_addba_req + *cmd_addba_req); int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index cd89fed206a..b5352afb871 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -104,13 +104,11 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, * main thread. */ static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) + struct host_cmd_ds_command *cmd, + struct mwifiex_ds_misc_cmd *pcmd_ptr) { - struct mwifiex_ds_misc_cmd *pcmd_ptr = - (struct mwifiex_ds_misc_cmd *) data_buf; - /* Copy the HOST command to command buffer */ - memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len); + memcpy(cmd, pcmd_ptr->cmd, pcmd_ptr->len); dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len); return 0; } @@ -707,15 +705,14 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { /* Copy original response back to response buffer */ - struct mwifiex_ds_misc_cmd *hostcmd = NULL; + struct mwifiex_ds_misc_cmd *hostcmd; uint16_t size = le16_to_cpu(resp->size); dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size); size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER); if (adapter->curr_cmd->data_buf) { - hostcmd = (struct mwifiex_ds_misc_cmd *) - adapter->curr_cmd->data_buf; + hostcmd = adapter->curr_cmd->data_buf; hostcmd->len = size; - memcpy(hostcmd->cmd, (void *) resp, size); + memcpy(hostcmd->cmd, resp, size); } } orig_cmdresp_no = le16_to_cpu(resp->command); @@ -1155,7 +1152,7 @@ EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp); int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, uint16_t ps_bitmap, - void *data_buf) + struct mwifiex_ds_auto_ds *auto_ds) { struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh = &cmd->params.psmode_enh; @@ -1218,9 +1215,8 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, sizeof(struct mwifiex_ie_types_header)); cmd_size += sizeof(*auto_ds_tlv); tlv += sizeof(*auto_ds_tlv); - if (data_buf) - idletime = ((struct mwifiex_ds_auto_ds *) - data_buf)->idle_time; + if (auto_ds) + idletime = auto_ds->idle_time; dev_dbg(priv->adapter->dev, "cmd: PS Command: Enter Auto Deep Sleep\n"); auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); @@ -1239,7 +1235,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, */ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_pm_cfg *pm_cfg) { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_ps_mode_enh *ps_mode = @@ -1282,10 +1278,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap); - if (data_buf) { + if (pm_cfg) { /* This section is for get power save mode */ - struct mwifiex_ds_pm_cfg *pm_cfg = - (struct mwifiex_ds_pm_cfg *)data_buf; if (ps_bitmap & BITMAP_STA_PS) pm_cfg->param.ps_mode = 1; else diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 5eab3dc29b1..644e2e405cb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -364,10 +364,9 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, */ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf) + struct mwifiex_bssdescriptor *bss_desc) { struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate; - struct mwifiex_bssdescriptor *bss_desc; struct mwifiex_ie_types_ssid_param_set *ssid_tlv; struct mwifiex_ie_types_phy_param_set *phy_tlv; struct mwifiex_ie_types_ss_param_set *ss_tlv; @@ -380,7 +379,6 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, u8 *pos; int rsn_ie_len = 0; - bss_desc = (struct mwifiex_bssdescriptor *) data_buf; pos = (u8 *) assoc; mwifiex_cfg_tx_buf(priv, bss_desc); @@ -748,7 +746,8 @@ done: */ int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) + struct host_cmd_ds_command *cmd, + struct mwifiex_802_11_ssid *req_ssid) { int rsn_ie_len = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -786,20 +785,15 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN); - memcpy(adhoc_start->ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); + memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", adhoc_start->ssid); memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); - memcpy(bss_desc->ssid.ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); + memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); - bss_desc->ssid.ssid_len = - ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len; + bss_desc->ssid.ssid_len = req_ssid->ssid_len; /* Set the BSS mode */ adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS; @@ -1036,13 +1030,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, */ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) + struct host_cmd_ds_command *cmd, + struct mwifiex_bssdescriptor *bss_desc) { int rsn_ie_len = 0; struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = &cmd->params.adhoc_join; - struct mwifiex_bssdescriptor *bss_desc = - (struct mwifiex_bssdescriptor *) data_buf; struct mwifiex_ie_types_chan_list_param_set *chan_tlv; u32 cmd_append_size = 0; u16 tmp_cap; diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 054a5c348a2..e5fc53dc688 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -553,7 +553,7 @@ static int mwifiex_set_mac_address(struct net_device *dev, void *addr) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - struct sockaddr *hw_addr = (struct sockaddr *) addr; + struct sockaddr *hw_addr = addr; int ret; memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index db201cc1473..03691c02a6e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -736,10 +736,10 @@ void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *, u8 *, int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, uint16_t ps_bitmap, - void *data_buf); + struct mwifiex_ds_auto_ds *auto_ds); int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf); + struct mwifiex_ds_pm_cfg *pm_cfg); void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); void mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated); @@ -751,7 +751,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, void *cmd_buf); int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, - void *cmd_buf); + struct host_cmd_ds_command *resp); int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, struct sk_buff *skb); int mwifiex_process_sta_event(struct mwifiex_private *); @@ -760,7 +760,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); int mwifiex_scan_networks(struct mwifiex_private *priv, const struct mwifiex_user_scan_cfg *user_scan_in); int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, - void *data_buf); + struct mwifiex_scan_cmd_config *scan_cfg); void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, @@ -777,8 +777,8 @@ s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, int mwifiex_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, - struct host_cmd_ds_command - *cmd, void *data_buf); + struct host_cmd_ds_command *cmd, + struct mwifiex_bssdescriptor *bss_desc); int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); void mwifiex_reset_connect_state(struct mwifiex_private *priv); @@ -791,10 +791,10 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf); + struct mwifiex_802_11_ssid *req_ssid); int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf); + struct mwifiex_bssdescriptor *bss_desc); int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 5c22860fb40..6f88c8ab5de 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -2357,12 +2357,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, * - Setting command ID, and proper size * - Ensuring correct endian-ness */ -int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, + struct mwifiex_scan_cmd_config *scan_cfg) { struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; - struct mwifiex_scan_cmd_config *scan_cfg; - - scan_cfg = (struct mwifiex_scan_cmd_config *) data_buf; /* Set fixed field variables in scan command */ scan_cmd->bss_mode = scan_cfg->bss_mode; diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 8af3a78d272..d85a0a60aa6 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -67,10 +67,9 @@ mwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv, */ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *action) { struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl; - u16 action = *((u16 *) data_buf); if (cmd_action != HostCmd_ACT_GEN_SET) { dev_err(priv->adapter->dev, @@ -81,7 +80,7 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN); - mac_ctrl->action = cpu_to_le16(action); + mac_ctrl->action = cpu_to_le16(*action); return 0; } @@ -104,10 +103,9 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, u32 cmd_oid, - void *data_buf) + u32 *ul_temp) { struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; - u32 ul_temp; dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); @@ -127,9 +125,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = *((u32 *) data_buf); *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -139,9 +136,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = *((u32 *) data_buf); *(__le16 *) (snmp_mib->value) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -152,9 +148,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = (*(u32 *) data_buf); *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -164,9 +159,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = *(u32 *) data_buf; *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -209,13 +203,11 @@ mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd) */ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *pbitmap_rates) { struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; struct mwifiex_rate_drop_pattern *rate_drop; - u16 *pbitmap_rates = (u16 *) data_buf; - u32 i; cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG); @@ -272,10 +264,10 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, + struct host_cmd_ds_txpwr_cfg *txp) { struct mwifiex_types_power_group *pg_tlv; - struct host_cmd_ds_txpwr_cfg *txp; struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg; cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG); @@ -283,12 +275,11 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg)); switch (cmd_action) { case HostCmd_ACT_GEN_SET: - txp = (struct host_cmd_ds_txpwr_cfg *) data_buf; if (txp->mode) { pg_tlv = (struct mwifiex_types_power_group - *) ((unsigned long) data_buf + + *) ((unsigned long) txp + sizeof(struct host_cmd_ds_txpwr_cfg)); - memmove(cmd_txp_cfg, data_buf, + memmove(cmd_txp_cfg, txp, sizeof(struct host_cmd_ds_txpwr_cfg) + sizeof(struct mwifiex_types_power_group) + pg_tlv->length); @@ -300,8 +291,7 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, sizeof(struct mwifiex_types_power_group) + pg_tlv->length); } else { - memmove(cmd_txp_cfg, data_buf, - sizeof(struct host_cmd_ds_txpwr_cfg)); + memmove(cmd_txp_cfg, txp, sizeof(*txp)); } cmd_txp_cfg->action = cpu_to_le16(cmd_action); break; @@ -322,22 +312,23 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, * (as required) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - u16 cmd_action, - struct mwifiex_hs_config_param *data_buf) +static int +mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, + struct mwifiex_hs_config_param *hscfg_param) { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg; u16 hs_activate = false; - if (data_buf == NULL) + if (!hscfg_param) /* New Activate command */ hs_activate = true; cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); if (!hs_activate && - (data_buf->conditions + (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && ((adapter->arp_filter_size > 0) && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { @@ -359,9 +350,9 @@ static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED; } else { hs_cfg->action = cpu_to_le16(HS_CONFIGURE); - hs_cfg->params.hs_config.conditions = data_buf->conditions; - hs_cfg->params.hs_config.gpio = data_buf->gpio; - hs_cfg->params.hs_config.gap = data_buf->gap; + hs_cfg->params.hs_config.conditions = hscfg_param->conditions; + hs_cfg->params.hs_config.gpio = hscfg_param->gpio; + hs_cfg->params.hs_config.gap = hscfg_param->gap; dev_dbg(adapter->dev, "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n", hs_cfg->params.hs_config.conditions, @@ -405,11 +396,11 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, * - Setting MAC multicast address * - Ensuring correct endian-ness */ -static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) +static int +mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, + u16 cmd_action, + struct mwifiex_multicast_list *mcast_list) { - struct mwifiex_multicast_list *mcast_list = - (struct mwifiex_multicast_list *) data_buf; struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr; cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) + @@ -435,7 +426,7 @@ static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, */ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf) + u8 *mac) { struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth; @@ -444,7 +435,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, + S_DS_GEN); /* Set AP MAC address */ - memcpy(deauth->mac_addr, (u8 *) data_buf, ETH_ALEN); + memcpy(deauth->mac_addr, mac, ETH_ALEN); dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr); @@ -543,15 +534,14 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, * encryption (TKIP, AES) (as required) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - u16 cmd_action, - u32 cmd_oid, void *data_buf) +static int +mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, u32 cmd_oid, + struct mwifiex_ds_encrypt_key *enc_key) { struct host_cmd_ds_802_11_key_material *key_material = &cmd->params.key_material; - struct mwifiex_ds_encrypt_key *enc_key = - (struct mwifiex_ds_encrypt_key *) data_buf; u16 key_param_len = 0; int ret = 0; const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -741,7 +731,7 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, */ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *channel) { struct host_cmd_ds_802_11_rf_channel *rf_chan = &cmd->params.rf_channel; @@ -759,7 +749,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, rf_type = le16_to_cpu(rf_chan->rf_type); SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset); - rf_chan->current_channel = cpu_to_le16(*((u16 *) data_buf)); + rf_chan->current_channel = cpu_to_le16(*channel); } rf_chan->action = cpu_to_le16(cmd_action); return 0; @@ -774,11 +764,10 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *enable) { struct host_cmd_ds_802_11_ibss_status *ibss_coal = &(cmd->params.ibss_coalescing); - u16 enable = 0; cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) + @@ -788,9 +777,8 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, switch (cmd_action) { case HostCmd_ACT_GEN_SET: - if (data_buf != NULL) - enable = *(u16 *) data_buf; - ibss_coal->enable = cpu_to_le16(enable); + if (enable) + ibss_coal->enable = cpu_to_le16(*enable); break; /* In other case.. Nothing to do */ @@ -822,9 +810,8 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { - struct mwifiex_ds_reg_rw *reg_rw; + struct mwifiex_ds_reg_rw *reg_rw = data_buf; - reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; switch (le16_to_cpu(cmd->command)) { case HostCmd_CMD_MAC_REG_ACCESS: { @@ -893,8 +880,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, } case HostCmd_CMD_802_11_EEPROM_ACCESS: { - struct mwifiex_ds_read_eeprom *rd_eeprom = - (struct mwifiex_ds_read_eeprom *) data_buf; + struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf; struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = (struct host_cmd_ds_802_11_eeprom_access *) &cmd->params.eeprom; @@ -923,8 +909,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, void *cmd_buf) { - struct host_cmd_ds_command *cmd_ptr = - (struct host_cmd_ds_command *) cmd_buf; + struct host_cmd_ds_command *cmd_ptr = cmd_buf; int ret = 0; /* Prepare command */ @@ -1181,7 +1166,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) /* Send request to firmware */ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, HostCmd_ACT_GEN_SET, 0, - (void *) &amsdu_aggr_ctrl); + &amsdu_aggr_ctrl); if (ret) return -1; /* MAC Control must be the last command in init_fw */ diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index d08f76429a0..ad64c87b91d 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -120,11 +120,10 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_get_signal *signal) { struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = &resp->params.rssi_info_rsp; - struct mwifiex_ds_get_signal *signal; priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); @@ -139,9 +138,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg); /* Need to indicate IOCTL complete */ - if (data_buf) { - signal = (struct mwifiex_ds_get_signal *) data_buf; - memset(signal, 0, sizeof(struct mwifiex_ds_get_signal)); + if (signal) { + memset(signal, 0, sizeof(*signal)); signal->selector = ALL_RSSI_INFO_MASK; @@ -185,32 +183,30 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + u32 *ul_temp) { struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; u16 oid = le16_to_cpu(smib->oid); u16 query_type = le16_to_cpu(smib->query_type); - u32 ul_temp; dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," " query_type = %#x, buf size = %#x\n", oid, query_type, le16_to_cpu(smib->buf_size)); if (query_type == HostCmd_ACT_GEN_GET) { - ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); - if (data_buf) - *(u32 *)data_buf = ul_temp; + if (ul_temp) + *ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); switch (oid) { case FRAG_THRESH_I: dev_dbg(priv->adapter->dev, - "info: SNMP_RESP: FragThsd =%u\n", ul_temp); + "info: SNMP_RESP: FragThsd =%u\n", *ul_temp); break; case RTS_THRESH_I: dev_dbg(priv->adapter->dev, - "info: SNMP_RESP: RTSThsd =%u\n", ul_temp); + "info: SNMP_RESP: RTSThsd =%u\n", *ul_temp); break; case SHORT_RETRY_LIM_I: dev_dbg(priv->adapter->dev, - "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp); + "info: SNMP_RESP: TxRetryCount=%u\n", *ul_temp); break; default: break; @@ -228,14 +224,12 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, */ static int mwifiex_ret_get_log(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_get_stats *stats) { struct host_cmd_ds_802_11_get_log *get_log = (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; - struct mwifiex_ds_get_stats *stats; - if (data_buf) { - stats = (struct mwifiex_ds_get_stats *) data_buf; + if (stats) { stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); stats->failed = le32_to_cpu(get_log->failed); stats->retry = le32_to_cpu(get_log->retry); @@ -278,9 +272,8 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, */ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_rate_cfg *ds_rate) { - struct mwifiex_rate_cfg *ds_rate; struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; struct mwifiex_ie_types_header *head; @@ -329,8 +322,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, HostCmd_CMD_802_11_TX_RATE_QUERY, HostCmd_ACT_GEN_GET, 0, NULL); - if (data_buf) { - ds_rate = (struct mwifiex_rate_cfg *) data_buf; + if (ds_rate) { if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { if (priv->is_data_rate_auto) { ds_rate->is_rate_auto = 1; @@ -413,8 +405,7 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) * and saving the current Tx power level in driver. */ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *data_buf) + struct host_cmd_ds_command *resp) { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg; @@ -631,21 +622,21 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + u16 *new_channel) { struct host_cmd_ds_802_11_rf_channel *rf_channel = &resp->params.rf_channel; - u16 new_channel = le16_to_cpu(rf_channel->current_channel); - if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { + if (new_channel) + *new_channel = le16_to_cpu(rf_channel->current_channel); + + if (priv->curr_bss_params.bss_descriptor.channel != *new_channel) { dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", priv->curr_bss_params.bss_descriptor.channel, - new_channel); + *new_channel); /* Update the channel again */ - priv->curr_bss_params.bss_descriptor.channel = new_channel; + priv->curr_bss_params.bss_descriptor.channel = *new_channel; } - if (data_buf) - *((u16 *)data_buf) = new_channel; return 0; } @@ -658,13 +649,11 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, */ static int mwifiex_ret_ver_ext(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct host_cmd_ds_version_ext *version_ext) { struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext; - struct host_cmd_ds_version_ext *version_ext; - if (data_buf) { - version_ext = (struct host_cmd_ds_version_ext *)data_buf; + if (version_ext) { version_ext->version_str_sel = ver_ext->version_str_sel; memcpy(version_ext->version_str, ver_ext->version_str, sizeof(char) * 128); @@ -686,8 +675,8 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, struct mwifiex_ds_read_eeprom *eeprom; if (data_buf) { - reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; - eeprom = (struct mwifiex_ds_read_eeprom *) data_buf; + reg_rw = data_buf; + eeprom = data_buf; switch (type) { case HostCmd_CMD_MAC_REG_ACCESS: { @@ -825,13 +814,11 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, * This is a generic function, which calls command specific * response handlers based on the command ID. */ -int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, - u16 cmdresp_no, void *cmd_buf) +int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, + struct host_cmd_ds_command *resp) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; - struct host_cmd_ds_command *resp = - (struct host_cmd_ds_command *) cmd_buf; void *data_buf = adapter->curr_cmd->data_buf; /* If the command is not successful, cleanup and return failure */ @@ -865,7 +852,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, "info: CMD_RESP: BG_SCAN result is ready!\n"); break; case HostCmd_CMD_TXPWR_CFG: - ret = mwifiex_ret_tx_power_cfg(priv, resp, data_buf); + ret = mwifiex_ret_tx_power_cfg(priv, resp); break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 1fdddece747..27430512f7c 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -187,7 +187,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num, local_rx_pd->priority, ta, (u8) local_rx_pd->rx_pkt_type, - (void *) skb); + skb); if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { if (priv && (ret == -1)) diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index aaa50c07419..6190b2fa57a 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -71,7 +71,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, u8 *head_ptr; struct txpd *local_tx_pd = NULL; - head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb); + head_ptr = mwifiex_process_sta_txpd(priv, skb); if (head_ptr) { if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) local_tx_pd = -- cgit v1.2.3-70-g09d2 From 7952ca5b20e1d54a3bfdfd976086c6f9df5873a2 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 21 Jun 2011 14:51:46 +0530 Subject: ath9k_hw: Fix calculation of PAPRD training power at 5Ghz higher the chainmask, lesser the power_delta to be added to the paprd_training_power Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index fc9c08f513c..8f6d11dfa37 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -83,7 +83,23 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah) if (delta > scale) return -1; - power += 2 * get_streams(common->tx_chainmask); + switch (get_streams(common->tx_chainmask)) { + case 1: + delta = 6; + break; + case 2: + delta = 4; + break; + case 3: + delta = 2; + break; + default: + delta = 0; + ath_dbg(common, ATH_DBG_CALIBRATE, + "Invalid tx-chainmask: %u\n", common->tx_chainmask); + } + + power += delta; return power; } -- cgit v1.2.3-70-g09d2 From 2c8e59379a02c5c2a478e8ce6ebc481793076792 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:21 +0200 Subject: ath9k: define mac version for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 5 ++++- drivers/net/wireless/ath/ath9k/reg.h | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6de2655e07d..a3881b64f76 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -551,6 +551,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) case AR_SREV_VERSION_9287: case AR_SREV_VERSION_9271: case AR_SREV_VERSION_9300: + case AR_SREV_VERSION_9330: case AR_SREV_VERSION_9485: case AR_SREV_VERSION_9340: break; @@ -561,7 +562,8 @@ static int __ath9k_hw_init(struct ath_hw *ah) return -EOPNOTSUPP; } - if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah)) + if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) || + AR_SREV_9330(ah)) ah->is_pciexpress = false; ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); @@ -2574,6 +2576,7 @@ static struct { { AR_SREV_VERSION_9287, "9287" }, { AR_SREV_VERSION_9271, "9271" }, { AR_SREV_VERSION_9300, "9300" }, + { AR_SREV_VERSION_9330, "9330" }, { AR_SREV_VERSION_9485, "9485" }, }; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index c18ee9921fb..a4833880acc 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -788,6 +788,10 @@ #define AR_SREV_REVISION_9271_11 1 #define AR_SREV_VERSION_9300 0x1c0 #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ +#define AR_SREV_VERSION_9330 0x200 +#define AR_SREV_REVISION_9330_10 0 +#define AR_SREV_REVISION_9330_11 1 +#define AR_SREV_REVISION_9330_12 2 #define AR_SREV_VERSION_9485 0x240 #define AR_SREV_REVISION_9485_10 0 #define AR_SREV_REVISION_9485_11 1 @@ -862,6 +866,18 @@ #define AR_SREV_9300_20_OR_LATER(_ah) \ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) +#define AR_SREV_9330(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330)) +#define AR_SREV_9330_10(_ah) \ + (AR_SREV_9330((_ah)) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_10)) +#define AR_SREV_9330_11(_ah) \ + (AR_SREV_9330((_ah)) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_11)) +#define AR_SREV_9330_12(_ah) \ + (AR_SREV_9330((_ah)) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12)) + #define AR_SREV_9485(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) #define AR_SREV_9485_10(_ah) \ -- cgit v1.2.3-70-g09d2 From 03689301da71fa80957a166e211431bb6e2904e3 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:22 +0200 Subject: ath9k: define device id for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 66d2225b95f..14c5857a020 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -45,6 +45,7 @@ #define AR9300_DEVID_PCIE 0x0030 #define AR9300_DEVID_AR9340 0x0031 #define AR9300_DEVID_AR9485_PCIE 0x0032 +#define AR9300_DEVID_AR9330 0x0035 #define AR5416_AR9100_DEVID 0x000b -- cgit v1.2.3-70-g09d2 From 3762561aa8afb0bd9fb60d3d847961f9945f8143 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:23 +0200 Subject: ath9k: add MAC revision detection for AR9330 The AR9330 1.0 and 1.1 are using the same revision, thus it is not possible to distinguish the two chips. The platform setup code can distinguish the chips based on the SoC revision. Add a callback function to ath9k_platform_data in order to allow getting the revision number from the platform code. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 9 +++++++++ drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/init.c | 1 + include/linux/ath9k_platform.h | 1 + 4 files changed, 12 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a3881b64f76..9840e005108 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -251,6 +251,15 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) case AR5416_AR9100_DEVID: ah->hw_version.macVersion = AR_SREV_VERSION_9100; break; + case AR9300_DEVID_AR9330: + ah->hw_version.macVersion = AR_SREV_VERSION_9330; + if (ah->get_mac_revision) { + ah->hw_version.macRev = ah->get_mac_revision(); + } else { + val = REG_READ(ah, AR_SREV); + ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); + } + return; case AR9300_DEVID_AR9340: ah->hw_version.macVersion = AR_SREV_VERSION_9340; val = REG_READ(ah, AR_SREV); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 14c5857a020..0749fa8c3a5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -862,6 +862,7 @@ struct ath_hw { u32 ent_mode; bool is_clk_25mhz; + int (*get_mac_revision)(void); }; struct ath_bus_ops { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d4b166cfdf6..66121129177 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -574,6 +574,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, sc->sc_ah->gpio_val = pdata->gpio_val; sc->sc_ah->led_pin = pdata->led_pin; ah->is_clk_25mhz = pdata->is_clk_25mhz; + ah->get_mac_revision = pdata->get_mac_revision; } common = ath9k_hw_common(ah); diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index 60a7c49dcb4..c207607acad 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -30,6 +30,7 @@ struct ath9k_platform_data { u32 gpio_val; bool is_clk_25mhz; + int (*get_mac_revision)(void); }; #endif /* _LINUX_ATH9K_PLATFORM_H */ -- cgit v1.2.3-70-g09d2 From e9b7c5914d4f3a066efcab272b1431d1dbb77297 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:24 +0200 Subject: ath9k: add platform device id for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ahb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 5b49cd03bfd..0b36fcf8a28 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -26,6 +26,10 @@ static const struct platform_device_id ath9k_platform_id_table[] = { .name = "ath9k", .driver_data = AR5416_AR9100_DEVID, }, + { + .name = "ar933x_wmac", + .driver_data = AR9300_DEVID_AR9330, + }, { .name = "ar934x_wmac", .driver_data = AR9300_DEVID_AR9340, -- cgit v1.2.3-70-g09d2 From 70722ea4344410b99abcedc7309c54db971308fd Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:25 +0200 Subject: ath9k: add AR9330 initvals Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9330_1p1_initvals.h | 1147 ++++++++++++++++++++ .../net/wireless/ath/ath9k/ar9330_1p2_initvals.h | 1080 ++++++++++++++++++ 2 files changed, 2227 insertions(+) create mode 100644 drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h create mode 100644 drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h new file mode 100644 index 00000000000..f11d9b2677f --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h @@ -0,0 +1,1147 @@ +/* + * Copyright (c) 2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INITVALS_9330_1P1_H +#define INITVALS_9330_1P1_H + +static const u32 ar9331_1p1_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, + {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, + {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00003221, 0x00003221}, + {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x0000a234, 0x00000fff, 0x00000fff, 0x10000fff, 0x00000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, + {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, + {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, + {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, + {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2d000a20, 0x2d000a20}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000a22, 0x31000a22}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000a24, 0x35000a24}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000a43, 0x38000a43}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3b000e42, 0x3b000e42}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x3f000e44, 0x3f000e44}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x42000e64, 0x42000e64}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46000e66, 0x46000e66}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x4a000ea6, 0x4a000ea6}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, + {0x0000a624, 0x03010a03, 0x03010a03, 0x03010a03, 0x03010a03}, + {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a62c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a630, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a634, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a638, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a63c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x00016044, 0x034922db, 0x034922db, 0x034922db, 0x034922db}, + {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, +}; + +static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, + {0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52}, + {0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84}, + {0x0000a2e4, 0xff43e000, 0xff43e000, 0xff43e000, 0xff43e000}, + {0x0000a2e8, 0xfffc0000, 0xfffc0000, 0xfffc0000, 0xfffc0000}, + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3d001620, 0x3d001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x3f001621, 0x3f001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x42001640, 0x42001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x44001641, 0x44001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x46001642, 0x46001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49001644, 0x49001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4c001a81, 0x4c001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4f001a83, 0x4f001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x52001c84, 0x52001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001ce3, 0x55001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x59001ce5, 0x59001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5d001ce9, 0x5d001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x64001eec, 0x64001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x64001eec, 0x64001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x64001eec, 0x64001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, + {0x0000a624, 0x0280ca03, 0x0280ca03, 0x0280ca03, 0x0280ca03}, + {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a62c, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, + {0x0000a630, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, + {0x0000a634, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, + {0x0000a638, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, +}; + +static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, + {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, + {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, + {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, + {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2d000a20, 0x2d000a20}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000a22, 0x31000a22}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000a24, 0x35000a24}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000a43, 0x38000a43}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3b000e42, 0x3b000e42}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x3f000e44, 0x3f000e44}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x42000e64, 0x42000e64}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46000e66, 0x46000e66}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x4a000ea6, 0x4a000ea6}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, + {0x0000a624, 0x03010a03, 0x03010a03, 0x03010a03, 0x03010a03}, + {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a62c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a630, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a634, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a638, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a63c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x00016044, 0x034922db, 0x034922db, 0x034922db, 0x034922db}, + {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, +}; + +static const u32 ar9331_1p1_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; + +static const u32 ar9331_1p1_xtal_25M[][2] = { + /* Addr allmodes */ + {0x00007038, 0x000002f8}, + {0x00008244, 0x0010f3d7}, + {0x0000824c, 0x0001e7ae}, + {0x0001609c, 0x0f508f29}, +}; + +static const u32 ar9331_1p1_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73800000}, + {0x0001600c, 0x00000000}, + {0x00016040, 0x7f80fff8}, + {0x00016044, 0x03db62db}, + {0x00016048, 0x6c924268}, + {0x0001604c, 0x000f0278}, + {0x00016050, 0x4db6db8c}, + {0x00016054, 0x6db60000}, + {0x00016080, 0x00080000}, + {0x00016084, 0x0e48048c}, + {0x00016088, 0x14214514}, + {0x0001608c, 0x119f081c}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd411eb84}, + {0x000160a0, 0xc2108ffe}, + {0x000160a4, 0x812fc370}, + {0x000160a8, 0x423c8000}, + {0x000160ac, 0x24651800}, + {0x000160b0, 0x03284f3e}, + {0x000160b4, 0x92480040}, + {0x000160c0, 0x006db6db}, + {0x000160c4, 0x0186db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x6de6c300}, + {0x000160d0, 0x14500820}, + {0x00016100, 0x04cb0001}, + {0x00016104, 0xfff80015}, + {0x00016108, 0x00080010}, + {0x0001610c, 0x00170000}, + {0x00016140, 0x10804000}, + {0x00016144, 0x01884080}, + {0x00016148, 0x000080c0}, + {0x00016280, 0x01000015}, + {0x00016284, 0x14d20000}, + {0x00016288, 0x00318000}, + {0x0001628c, 0x50000000}, + {0x00016290, 0x4b96210f}, + {0x00016380, 0x00000000}, + {0x00016384, 0x00000000}, + {0x00016388, 0x00800700}, + {0x0001638c, 0x00800700}, + {0x00016390, 0x00800700}, + {0x00016394, 0x00000000}, + {0x00016398, 0x00000000}, + {0x0001639c, 0x00000000}, + {0x000163a0, 0x00000001}, + {0x000163a4, 0x00000001}, + {0x000163a8, 0x00000000}, + {0x000163ac, 0x00000000}, + {0x000163b0, 0x00000000}, + {0x000163b4, 0x00000000}, + {0x000163b8, 0x00000000}, + {0x000163bc, 0x00000000}, + {0x000163c0, 0x000000a0}, + {0x000163c4, 0x000c0000}, + {0x000163c8, 0x14021402}, + {0x000163cc, 0x00001402}, + {0x000163d0, 0x00000000}, + {0x000163d4, 0x00000000}, +}; + +static const u32 ar9331_1p1_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, +}; + +static const u32 ar9331_common_wo_xlna_rx_gain_1p1[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x22072208}, + {0x0000a0c4, 0x22052206}, + {0x0000a0c8, 0x22032204}, + {0x0000a0cc, 0x22012202}, + {0x0000a0d0, 0x221f2200}, + {0x0000a0d4, 0x221d221e}, + {0x0000a0d8, 0x33023303}, + {0x0000a0dc, 0x33003301}, + {0x0000a0e0, 0x331e331f}, + {0x0000a0e4, 0x4402331d}, + {0x0000a0e8, 0x44004401}, + {0x0000a0ec, 0x441e441f}, + {0x0000a0f0, 0x55025503}, + {0x0000a0f4, 0x55005501}, + {0x0000a0f8, 0x551e551f}, + {0x0000a0fc, 0x6602551d}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + +static const u32 ar9331_1p1_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x5f3ca3de}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x32840bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0x00000000}, + {0x00009c08, 0x03200000}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038233c}, + {0x00009e24, 0x9927b515}, + {0x00009e28, 0x12ef0200}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009fc0, 0x803e4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x0000a20c, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739ce}, + {0x0000a418, 0x2d001dce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x04000000}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a458, 0x00000000}, + {0x0000a640, 0x00000000}, + {0x0000a644, 0x3fad9d74}, + {0x0000a648, 0x0048060a}, + {0x0000a64c, 0x00003c37}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, + {0x0000a67c, 0x13121110}, + {0x0000a680, 0x31301514}, + {0x0000a684, 0x35343332}, + {0x0000a688, 0x00000036}, + {0x0000a690, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, +}; + +static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, + {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, + {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, + {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, + {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2d000a20, 0x2d000a20}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000a22, 0x31000a22}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000a24, 0x35000a24}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000a43, 0x38000a43}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3b000e42, 0x3b000e42}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x3f000e44, 0x3f000e44}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x42000e64, 0x42000e64}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46000e66, 0x46000e66}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x4a000ea6, 0x4a000ea6}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x4a000ea6, 0x4a000ea6}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, + {0x0000a624, 0x03010a03, 0x03010a03, 0x03010a03, 0x03010a03}, + {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a62c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a630, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a634, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a638, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x0000a63c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, + {0x00016044, 0x034922db, 0x034922db, 0x034922db, 0x034922db}, + {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, +}; + +static const u32 ar9331_1p1_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; + +static const u32 ar9331_1p1_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000002f8}, +}; + +static const u32 ar9331_1p1_xtal_40M[][2] = { + /* Addr allmodes */ + {0x00007038, 0x000004c2}, + {0x00008244, 0x0010f400}, + {0x0000824c, 0x0001e800}, + {0x0001609c, 0x0b283f31}, +}; + +static const u32 ar9331_1p1_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00020085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c20}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00000}, + {0x000080d8, 0x00400000}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008248, 0x00000800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9d400010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xaa48105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; + +static const u32 ar9331_common_rx_gain_1p1[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x01910190}, + {0x0000a030, 0x01930192}, + {0x0000a034, 0x01950194}, + {0x0000a038, 0x038a0196}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x22222229}, + {0x0000a084, 0x1d1d1d1d}, + {0x0000a088, 0x1d1d1d1d}, + {0x0000a08c, 0x1d1d1d1d}, + {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, +}; + +static const u32 ar9331_common_tx_gain_offset1_1[][1] = { + {0}, + {3}, + {0}, + {0}, +}; + +static const u32 ar9331_1p1_chansel_xtal_25M[] = { + 0x0101479e, + 0x0101d027, + 0x010258af, + 0x0102e138, + 0x010369c0, + 0x0103f249, + 0x01047ad1, + 0x0105035a, + 0x01058be2, + 0x0106146b, + 0x01069cf3, + 0x0107257c, + 0x0107ae04, + 0x0108f5b2, +}; + +static const u32 ar9331_1p1_chansel_xtal_40M[] = { + 0x00a0ccbe, + 0x00a12213, + 0x00a17769, + 0x00a1ccbe, + 0x00a22213, + 0x00a27769, + 0x00a2ccbe, + 0x00a32213, + 0x00a37769, + 0x00a3ccbe, + 0x00a42213, + 0x00a47769, + 0x00a4ccbe, + 0x00a5998b, +}; + +#endif /* INITVALS_9330_1P1_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h new file mode 100644 index 00000000000..0e6ca0834b3 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h @@ -0,0 +1,1080 @@ +/* + * Copyright (c) 2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INITVALS_9330_1P2_H +#define INITVALS_9330_1P2_H + +static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, + {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, +}; + +static const u32 ar9331_1p2_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, + {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, + {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00003221, 0x00003221}, + {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x0000a234, 0x00000fff, 0x00000fff, 0x10000fff, 0x00000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, + {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, +}; + +static const u32 ar9331_modes_low_ob_db_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, + {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, +}; + +static const u32 ar9331_1p2_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; + +static const u32 ar9331_1p2_xtal_25M[][2] = { + /* Addr allmodes */ + {0x00007038, 0x000002f8}, + {0x00008244, 0x0010f3d7}, + {0x0000824c, 0x0001e7ae}, + {0x0001609c, 0x0f508f29}, +}; + +static const u32 ar9331_1p2_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73800000}, + {0x0001600c, 0x00000000}, + {0x00016040, 0x7f80fff8}, + {0x00016044, 0x03d6d2db}, + {0x00016048, 0x6c924268}, + {0x0001604c, 0x000f0278}, + {0x00016050, 0x4db6db8c}, + {0x00016054, 0x6db60000}, + {0x00016080, 0x00080000}, + {0x00016084, 0x0e48048c}, + {0x00016088, 0x14214514}, + {0x0001608c, 0x119f081c}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd411eb84}, + {0x000160a0, 0xc2108ffe}, + {0x000160a4, 0x812fc370}, + {0x000160a8, 0x423c8000}, + {0x000160ac, 0x24651800}, + {0x000160b0, 0x03284f3e}, + {0x000160b4, 0x92480040}, + {0x000160c0, 0x006db6db}, + {0x000160c4, 0x0186db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x6de6c300}, + {0x000160d0, 0x14500820}, + {0x00016100, 0x04cb0001}, + {0x00016104, 0xfff80015}, + {0x00016108, 0x00080010}, + {0x0001610c, 0x00170000}, + {0x00016140, 0x10804000}, + {0x00016144, 0x01884080}, + {0x00016148, 0x000080c0}, + {0x00016280, 0x01000015}, + {0x00016284, 0x14d20000}, + {0x00016288, 0x00318000}, + {0x0001628c, 0x50000000}, + {0x00016290, 0x4b96210f}, + {0x00016380, 0x00000000}, + {0x00016384, 0x00000000}, + {0x00016388, 0x00800700}, + {0x0001638c, 0x00800700}, + {0x00016390, 0x00800700}, + {0x00016394, 0x00000000}, + {0x00016398, 0x00000000}, + {0x0001639c, 0x00000000}, + {0x000163a0, 0x00000001}, + {0x000163a4, 0x00000001}, + {0x000163a8, 0x00000000}, + {0x000163ac, 0x00000000}, + {0x000163b0, 0x00000000}, + {0x000163b4, 0x00000000}, + {0x000163b8, 0x00000000}, + {0x000163bc, 0x00000000}, + {0x000163c0, 0x000000a0}, + {0x000163c4, 0x000c0000}, + {0x000163c8, 0x14021402}, + {0x000163cc, 0x00001402}, + {0x000163d0, 0x00000000}, + {0x000163d4, 0x00000000}, +}; + +static const u32 ar9331_1p2_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, +}; + +static const u32 ar9331_common_wo_xlna_rx_gain_1p2[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x22072208}, + {0x0000a0c4, 0x22052206}, + {0x0000a0c8, 0x22032204}, + {0x0000a0cc, 0x22012202}, + {0x0000a0d0, 0x221f2200}, + {0x0000a0d4, 0x221d221e}, + {0x0000a0d8, 0x33023303}, + {0x0000a0dc, 0x33003301}, + {0x0000a0e0, 0x331e331f}, + {0x0000a0e4, 0x4402331d}, + {0x0000a0e8, 0x44004401}, + {0x0000a0ec, 0x441e441f}, + {0x0000a0f0, 0x55025503}, + {0x0000a0f4, 0x55005501}, + {0x0000a0f8, 0x551e551f}, + {0x0000a0fc, 0x6602551d}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + +static const u32 ar9331_1p2_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x5f3ca3de}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x32840bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0x00000000}, + {0x00009c08, 0x03200000}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038233c}, + {0x00009e24, 0x9927b515}, + {0x00009e28, 0x12ef0200}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009fc0, 0x803e4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x0000a20c, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739ce}, + {0x0000a418, 0x2d001dce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x04000000}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a458, 0x00000000}, + {0x0000a640, 0x00000000}, + {0x0000a644, 0x3fad9d74}, + {0x0000a648, 0x0048060a}, + {0x0000a64c, 0x00003c37}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, + {0x0000a67c, 0x13121110}, + {0x0000a680, 0x31301514}, + {0x0000a684, 0x35343332}, + {0x0000a688, 0x00000036}, + {0x0000a690, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, +}; + +static const u32 ar9331_modes_high_power_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, + {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, +}; + +static const u32 ar9331_1p2_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; + +static const u32 ar9331_1p2_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000002f8}, +}; + +static const u32 ar9331_1p2_xtal_40M[][2] = { + /* Addr allmodes */ + {0x00007038, 0x000004c2}, + {0x00008244, 0x0010f400}, + {0x0000824c, 0x0001e800}, + {0x0001609c, 0x0b283f31}, +}; + +static const u32 ar9331_1p2_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00020085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c20}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00000}, + {0x000080d8, 0x00400000}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008248, 0x00000800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9d400010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xaa48105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; + +static const u32 ar9331_common_rx_gain_1p2[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x01800082}, + {0x0000a014, 0x01820181}, + {0x0000a018, 0x01840183}, + {0x0000a01c, 0x01880185}, + {0x0000a020, 0x018a0189}, + {0x0000a024, 0x02850284}, + {0x0000a028, 0x02890288}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x21212128}, + {0x0000a098, 0x171c1c1c}, + {0x0000a09c, 0x02020212}, + {0x0000a0a0, 0x00000202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x111f1100}, + {0x0000a0c8, 0x111d111e}, + {0x0000a0cc, 0x111b111c}, + {0x0000a0d0, 0x22032204}, + {0x0000a0d4, 0x22012202}, + {0x0000a0d8, 0x221f2200}, + {0x0000a0dc, 0x221d221e}, + {0x0000a0e0, 0x33013302}, + {0x0000a0e4, 0x331f3300}, + {0x0000a0e8, 0x4402331e}, + {0x0000a0ec, 0x44004401}, + {0x0000a0f0, 0x441e441f}, + {0x0000a0f4, 0x55015502}, + {0x0000a0f8, 0x551f5500}, + {0x0000a0fc, 0x6602551e}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + +#endif /* INITVALS_9330_1P2_H */ -- cgit v1.2.3-70-g09d2 From 172805ad46b78717a738ca5c7908c68f0326d3a9 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:26 +0200 Subject: ath9k: initialize mode registers for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 110 +++++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 3 + 2 files changed, 112 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 392bf0f8ff1..dc0ad4a21d5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -19,6 +19,8 @@ #include "ar9003_2p2_initvals.h" #include "ar9485_initvals.h" #include "ar9340_initvals.h" +#include "ar9330_1p1_initvals.h" +#include "ar9330_1p2_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -29,7 +31,113 @@ */ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { - if (AR_SREV_9340(ah)) { + if (AR_SREV_9330_11(ah)) { + /* mac */ + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9331_1p1_mac_core, + ARRAY_SIZE(ar9331_1p1_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9331_1p1_mac_postamble, + ARRAY_SIZE(ar9331_1p1_mac_postamble), 5); + + /* bb */ + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9331_1p1_baseband_core, + ARRAY_SIZE(ar9331_1p1_baseband_core), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9331_1p1_baseband_postamble, + ARRAY_SIZE(ar9331_1p1_baseband_postamble), 5); + + /* radio */ + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9331_1p1_radio_core, + ARRAY_SIZE(ar9331_1p1_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0); + + /* soc */ + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9331_1p1_soc_preamble, + ARRAY_SIZE(ar9331_1p1_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], + ar9331_1p1_soc_postamble, + ARRAY_SIZE(ar9331_1p1_soc_postamble), 2); + + /* rx/tx gain */ + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_rx_gain_1p1, + ARRAY_SIZE(ar9331_common_rx_gain_1p1), 2); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_lowest_ob_db_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), + 5); + + /* additional clock settings */ + if (ah->is_clk_25mhz) + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9331_1p1_xtal_25M, + ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); + else + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9331_1p1_xtal_40M, + ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); + } else if (AR_SREV_9330_12(ah)) { + /* mac */ + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9331_1p2_mac_core, + ARRAY_SIZE(ar9331_1p2_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9331_1p2_mac_postamble, + ARRAY_SIZE(ar9331_1p2_mac_postamble), 5); + + /* bb */ + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9331_1p2_baseband_core, + ARRAY_SIZE(ar9331_1p2_baseband_core), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9331_1p2_baseband_postamble, + ARRAY_SIZE(ar9331_1p2_baseband_postamble), 5); + + /* radio */ + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9331_1p2_radio_core, + ARRAY_SIZE(ar9331_1p2_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0); + + /* soc */ + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9331_1p2_soc_preamble, + ARRAY_SIZE(ar9331_1p2_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], + ar9331_1p2_soc_postamble, + ARRAY_SIZE(ar9331_1p2_soc_postamble), 2); + + /* rx/tx gain */ + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_rx_gain_1p2, + ARRAY_SIZE(ar9331_common_rx_gain_1p2), 2); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_lowest_ob_db_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), + 5); + + /* additional clock settings */ + if (ah->is_clk_25mhz) + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9331_1p2_xtal_25M, + ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); + else + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9331_1p2_xtal_40M, + ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); + } else if (AR_SREV_9340(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 892c48b1543..48893f16e3b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -659,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); + if (AR_SREV_9300(ah)) + REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); + if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); -- cgit v1.2.3-70-g09d2 From a208db944142db1700c6676dc724454213986bed Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:27 +0200 Subject: ath9k: initialize tx gain table for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 48 +++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index dc0ad4a21d5..264a7eae822 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -328,7 +328,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_tx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9340(ah)) + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_lowest_ob_db_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_lowest_ob_db_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9340Modes_lowest_ob_db_tx_gain_table_1p0, ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), @@ -345,7 +355,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 5); break; case 1: - if (AR_SREV_9340(ah)) + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_ob_db_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_ob_db_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9340Modes_lowest_ob_db_tx_gain_table_1p0, ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), @@ -362,7 +382,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 5); break; case 2: - if (AR_SREV_9340(ah)) + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_low_ob_db_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_low_ob_db_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9340Modes_lowest_ob_db_tx_gain_table_1p0, ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), @@ -379,7 +409,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 5); break; case 3: - if (AR_SREV_9340(ah)) + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_power_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_power_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9340Modes_lowest_ob_db_tx_gain_table_1p0, ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), -- cgit v1.2.3-70-g09d2 From 77a27da38916626aaaa994e716514dfa990290f7 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:28 +0200 Subject: ath9k: initialize rx gain table for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 264a7eae822..8efdec247c0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -443,7 +443,17 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_rx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9340(ah)) + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_rx_gain_1p2, + ARRAY_SIZE(ar9331_common_rx_gain_1p2), + 2); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_rx_gain_1p1, + ARRAY_SIZE(ar9331_common_rx_gain_1p1), + 2); + else if (AR_SREV_9340(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9340Common_rx_gain_table_1p0, ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), @@ -460,7 +470,17 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) 2); break; case 1: - if (AR_SREV_9340(ah)) + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_wo_xlna_rx_gain_1p2, + ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2), + 2); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_wo_xlna_rx_gain_1p1, + ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1), + 2); + else if (AR_SREV_9340(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9340Common_wo_xlna_rx_gain_table_1p0, ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), -- cgit v1.2.3-70-g09d2 From a5415d625d35871dd8eaf3784a402f36c028c29d Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:29 +0200 Subject: ath9k: add AR9330 specific PLL initialization Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9840e005108..99c90f71576 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -733,6 +733,39 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_BB_DPLL2_PLL_PWD, 0x0); udelay(1000); + } else if (AR_SREV_9330(ah)) { + u32 ddr_dpll2, pll_control2, kd; + + if (ah->is_clk_25mhz) { + ddr_dpll2 = 0x18e82f01; + pll_control2 = 0xe04a3d; + kd = 0x1d; + } else { + ddr_dpll2 = 0x19e82f01; + pll_control2 = 0x886666; + kd = 0x3d; + } + + /* program DDR PLL ki and kd value */ + REG_WRITE(ah, AR_CH0_DDR_DPLL2, ddr_dpll2); + + /* program DDR PLL phase_shift */ + REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, + AR_CH0_DPLL3_PHASE_SHIFT, 0x1); + + REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); + udelay(1000); + + /* program refdiv, nint, frac to RTC register */ + REG_WRITE(ah, AR_RTC_PLL_CONTROL2, pll_control2); + + /* program BB PLL kd and ki value */ + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KD, kd); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KI, 0x06); + + /* program BB PLL phase_shift */ + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, + AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); } else if (AR_SREV_9340(ah)) { u32 regval, pll2_divint, pll2_divfrac, refdiv; @@ -774,7 +807,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); - if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) + if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) udelay(1000); /* Switch the core clock for ar9271 to 117Mhz */ -- cgit v1.2.3-70-g09d2 From 88e641df19a8f9f36e4ca18f8cdff000be8d5ef9 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:30 +0200 Subject: ath9k: use different BB watchdog timeout value for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 99c90f71576..b06fa6f8398 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -615,7 +615,10 @@ static int __ath9k_hw_init(struct ath_hw *ah) else ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); - ah->bb_watchdog_timeout_ms = 25; + if (AR_SREV_9330(ah)) + ah->bb_watchdog_timeout_ms = 85; + else + ah->bb_watchdog_timeout_ms = 25; common->state = ATH_HW_INITIALIZED; -- cgit v1.2.3-70-g09d2 From 0e707a9473bf981111d09ced796e79aad4b4fbca Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:31 +0200 Subject: ath9k: don't enable LDPC for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b06fa6f8398..93c91f218ca 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2030,7 +2030,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9300_20_OR_LATER(ah)) { pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; - if (!AR_SREV_9485(ah)) + if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah)) pCap->hw_caps |= ATH9K_HW_CAP_LDPC; pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; -- cgit v1.2.3-70-g09d2 From c1acfbe8637069864b515907025efbbfb577a43c Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:32 +0200 Subject: ath9k: read spur frequency information from eeprom for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 48893f16e3b..2df72cbaf55 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -168,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, * is out-of-band and can be ignored. */ - if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) { + if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) { spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, IS_CHAN_2GHZ(chan)); if (spur_fbin_ptr[0] == 0) /* No spur */ @@ -193,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, for (i = 0; i < max_spur_cnts; i++) { negative = 0; - if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) + if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], IS_CHAN_2GHZ(chan)) - synth_freq; else -- cgit v1.2.3-70-g09d2 From dbb204e39fec2dc4800f19eae321ad7e1b95f2fa Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:33 +0200 Subject: ath9k: fix channel frequency calculation for AR9340 A multiplication is missing from the current formula. Cc: Vasanthakumar Thiagarajan Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 2df72cbaf55..1194eeb6963 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -104,7 +104,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) u32 chan_frac; channelSel = (freq * 2) / 75; - chan_frac = ((freq % 75) * 0x20000) / 75; + chan_frac = (((freq * 2) % 75) * 0x20000) / 75; channelSel = (channelSel << 17) | chan_frac; } else { channelSel = CHANSEL_5G(freq); -- cgit v1.2.3-70-g09d2 From 5acb4b9366b77d27f79706cb99b4d34e5076b953 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:34 +0200 Subject: ath9k: configure RF channel frequency for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 1194eeb6963..a0ca1ebe298 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -75,7 +75,19 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) freq = centers.synth_center; if (freq < 4800) { /* 2 GHz, fractional mode */ - if (AR_SREV_9485(ah)) { + if (AR_SREV_9330(ah)) { + u32 chan_frac; + u32 div; + + if (ah->is_clk_25mhz) + div = 75; + else + div = 120; + + channelSel = (freq * 4) / div; + chan_frac = (((freq * 4) % div) * 0x20000) / div; + channelSel = (channelSel << 17) | chan_frac; + } else if (AR_SREV_9485(ah)) { u32 chan_frac; /* -- cgit v1.2.3-70-g09d2 From 4033bdad63a871da4c406a4a16d01b6de0a7e56e Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:35 +0200 Subject: ath9k: enable TX/RX data byte swap for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 93c91f218ca..2df369ffb13 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1592,7 +1592,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); } #ifdef __BIG_ENDIAN - else if (AR_SREV_9340(ah)) + else if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); else REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); -- cgit v1.2.3-70-g09d2 From 7dc5966d5c4a1bc48f1eca01403b187960ad72f4 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:36 +0200 Subject: ath9k: skip internal regulator configuration for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 2e370c668d4..c5e031d8777 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3795,7 +3795,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); ar9003_hw_drive_strength_apply(ah); ar9003_hw_atten_apply(ah, chan); - if (!AR_SREV_9340(ah)) + if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) ar9003_hw_internal_regulator_apply(ah); if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) ar9003_hw_apply_tuning_caps(ah); -- cgit v1.2.3-70-g09d2 From 7d790a21e5d4674fb25da62f560453bc3c248a93 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:37 +0200 Subject: ath9k: enable tuning capacitance configuration for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c5e031d8777..83c33a583e2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3797,7 +3797,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, ar9003_hw_atten_apply(ah, chan); if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) ar9003_hw_internal_regulator_apply(ah); - if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) + if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) ar9003_hw_apply_tuning_caps(ah); } -- cgit v1.2.3-70-g09d2 From 5b5c033b59e74392442eb4b052f0b874a0a31c7d Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:38 +0200 Subject: ath9k: use correct EEPROM base for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 83c33a583e2..5457bd6e524 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3324,6 +3324,8 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, read = ar9300_read_eeprom; if (AR_SREV_9485(ah)) cptr = AR9300_BASE_ADDR_4K; + else if (AR_SREV_9330(ah)) + cptr = AR9300_BASE_ADDR_512; else cptr = AR9300_BASE_ADDR; ath_dbg(common, ATH_DBG_EEPROM, -- cgit v1.2.3-70-g09d2 From dc9aa5fc283c79e9aa8d9d1c537d203081634bb1 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:39 +0200 Subject: ath9k: configure xpa bias level for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 5457bd6e524..7ea5105764d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3444,7 +3444,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) { int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); - if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) + if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); else { REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); -- cgit v1.2.3-70-g09d2 From 0c453732a757d8160e99a23e9b551de8dc7e642c Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:40 +0200 Subject: ath9k: set NF limits for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 5 ++++- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index a0ca1ebe298..5e987c7aacd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1089,7 +1089,10 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah) { ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; - ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ; + if (AR_SREV_9330(ah)) + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ; + else + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ; ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 443090d278e..d259278fcc8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -332,6 +332,8 @@ #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 +#define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118 + /* * AGC Field Definitions */ -- cgit v1.2.3-70-g09d2 From 431da56a814959753f7ad6962f0bd5fa0430e508 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:41 +0200 Subject: ath9k: enable antenna diversity for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2df369ffb13..4da5284c777 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2072,7 +2072,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) } - if (AR_SREV_9485(ah)) { + if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); /* * enable the diversity-combining algorithm only when -- cgit v1.2.3-70-g09d2 From 7216198d31450e273fefcb94b4eb3ea07da99131 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:42 +0200 Subject: ath9k: use correct max_streams for AR9330 The AR9330 is a single stream chip. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 66121129177..1851c222fff 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -245,7 +245,7 @@ static void setup_ht_cap(struct ath_softc *sc, ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; - if (AR_SREV_9485(ah)) + if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) max_streams = 1; else if (AR_SREV_9300_20_OR_LATER(ah)) max_streams = 3; -- cgit v1.2.3-70-g09d2 From 66ce235a9d6ea8a7b7089d29000eb715c66a6221 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:43 +0200 Subject: ath9k: add a missing case statement to ath_ant_div_comb_alt_check The 'ar9003_hw_antdiv_comb_conf_get' function sets div_group to 2 however that value is not used in 'ath_ant_div_comb_alt_check'. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 07e35e59c9e..d0af2f277f2 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -39,6 +39,7 @@ static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, result = true; break; case 1: + case 2: if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && (alt_rssi_avg >= (main_rssi_avg - 5))) || -- cgit v1.2.3-70-g09d2 From cd0ed1b5fc06cea30a97b131ff4570f8dca3cbd2 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:44 +0200 Subject: ath9k: fix antenna diversity configuration for non AR9485 chips The current values must be used only on AR9485 chips. Other chips requires different values. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 5e987c7aacd..e788fa0d5af 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1214,8 +1214,14 @@ static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, AR_PHY_9485_ANT_DIV_ALT_LNACONF_S; antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >> AR_PHY_9485_ANT_FAST_DIV_BIAS_S; - antconf->lna1_lna2_delta = -9; - antconf->div_group = 2; + + if (AR_SREV_9485(ah)) { + antconf->lna1_lna2_delta = -9; + antconf->div_group = 2; + } else { + antconf->lna1_lna2_delta = -3; + antconf->div_group = 0; + } } static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah, -- cgit v1.2.3-70-g09d2 From 223c5a87851369de99fa6e6f22c443ed08a0332b Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:45 +0200 Subject: ath9k: remove superfluous parentheses Also remove two empty lines. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 62 +++++++++++++++++------------------ 1 file changed, 30 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index d0af2f277f2..99f55b3f84e 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1076,39 +1076,39 @@ static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, antcomb->rssi_lna1 = main_rssi_avg; switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { - case (0x10): /* LNA2 A-B */ + case 0x10: /* LNA2 A-B */ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; antcomb->first_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; break; - case (0x20): /* LNA1 A-B */ + case 0x20: /* LNA1 A-B */ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; antcomb->first_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; break; - case (0x21): /* LNA1 LNA2 */ + case 0x21: /* LNA1 LNA2 */ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; antcomb->first_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; break; - case (0x12): /* LNA2 LNA1 */ + case 0x12: /* LNA2 LNA1 */ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; antcomb->first_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; break; - case (0x13): /* LNA2 A+B */ + case 0x13: /* LNA2 A+B */ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; antcomb->first_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; break; - case (0x23): /* LNA1 A+B */ + case 0x23: /* LNA1 A+B */ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; antcomb->first_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; @@ -1325,40 +1325,40 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, /* Adjust the fast_div_bias based on main and alt lna conf */ switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { - case (0x01): /* A-B LNA2 */ + case 0x01: /* A-B LNA2 */ ant_conf->fast_div_bias = 0x3b; break; - case (0x02): /* A-B LNA1 */ + case 0x02: /* A-B LNA1 */ ant_conf->fast_div_bias = 0x3d; break; - case (0x03): /* A-B A+B */ + case 0x03: /* A-B A+B */ ant_conf->fast_div_bias = 0x1; break; - case (0x10): /* LNA2 A-B */ + case 0x10: /* LNA2 A-B */ ant_conf->fast_div_bias = 0x7; break; - case (0x12): /* LNA2 LNA1 */ + case 0x12: /* LNA2 LNA1 */ ant_conf->fast_div_bias = 0x2; break; - case (0x13): /* LNA2 A+B */ + case 0x13: /* LNA2 A+B */ ant_conf->fast_div_bias = 0x7; break; - case (0x20): /* LNA1 A-B */ + case 0x20: /* LNA1 A-B */ ant_conf->fast_div_bias = 0x6; break; - case (0x21): /* LNA1 LNA2 */ + case 0x21: /* LNA1 LNA2 */ ant_conf->fast_div_bias = 0x0; break; - case (0x23): /* LNA1 A+B */ + case 0x23: /* LNA1 A+B */ ant_conf->fast_div_bias = 0x6; break; - case (0x30): /* A+B A-B */ + case 0x30: /* A+B A-B */ ant_conf->fast_div_bias = 0x1; break; - case (0x31): /* A+B LNA2 */ + case 0x31: /* A+B LNA2 */ ant_conf->fast_div_bias = 0x3b; break; - case (0x32): /* A+B LNA1 */ + case 0x32: /* A+B LNA1 */ ant_conf->fast_div_bias = 0x3d; break; default: @@ -1368,22 +1368,22 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, /* Adjust the fast_div_bias based on main and alt_lna_conf */ switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { - case (0x01): /* A-B LNA2 */ + case 0x01: /* A-B LNA2 */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x02): /* A-B LNA1 */ + case 0x02: /* A-B LNA1 */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x03): /* A-B A+B */ + case 0x03: /* A-B A+B */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x10): /* LNA2 A-B */ + case 0x10: /* LNA2 A-B */ if (!(antcomb->scan) && (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) ant_conf->fast_div_bias = 0x1; @@ -1392,12 +1392,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x12): /* LNA2 LNA1 */ + case 0x12: /* LNA2 LNA1 */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x13): /* LNA2 A+B */ + case 0x13: /* LNA2 A+B */ if (!(antcomb->scan) && (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) ant_conf->fast_div_bias = 0x1; @@ -1406,7 +1406,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x20): /* LNA1 A-B */ + case 0x20: /* LNA1 A-B */ if (!(antcomb->scan) && (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) ant_conf->fast_div_bias = 0x1; @@ -1415,12 +1415,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x21): /* LNA1 LNA2 */ + case 0x21: /* LNA1 LNA2 */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x23): /* LNA1 A+B */ + case 0x23: /* LNA1 A+B */ if (!(antcomb->scan) && (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) ant_conf->fast_div_bias = 0x1; @@ -1429,17 +1429,17 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x30): /* A+B A-B */ + case 0x30: /* A+B A-B */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x31): /* A+B LNA2 */ + case 0x31: /* A+B LNA2 */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; break; - case (0x32): /* A+B LNA1 */ + case 0x32: /* A+B LNA1 */ ant_conf->fast_div_bias = 0x1; ant_conf->main_gaintb = 0; ant_conf->alt_gaintb = 0; @@ -1447,9 +1447,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, default: break; } - } - } /* Antenna diversity and combining */ -- cgit v1.2.3-70-g09d2 From e7ef5bc079672058dcb791a378dc3beb134bd84e Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:46 +0200 Subject: ath9k: add fast_div_bias configuration for diversity group 1 The patch adds the missing configuration code for diversity group 1. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 99f55b3f84e..80bb04f950e 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1364,6 +1364,89 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, default: break; } + } else if (ant_conf->div_group == 1) { + /* Adjust the fast_div_bias based on main and alt_lna_conf */ + switch ((ant_conf->main_lna_conf << 4) | + ant_conf->alt_lna_conf) { + case 0x01: /* A-B LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x02: /* A-B LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x03: /* A-B A+B */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x10: /* LNA2 A-B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x12: /* LNA2 LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x13: /* LNA2 A+B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x20: /* LNA1 A-B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x21: /* LNA1 LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x23: /* LNA1 A+B */ + if (!(antcomb->scan) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) + ant_conf->fast_div_bias = 0x3f; + else + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x30: /* A+B A-B */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x31: /* A+B LNA2 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + case 0x32: /* A+B LNA1 */ + ant_conf->fast_div_bias = 0x1; + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + break; + default: + break; + } } else if (ant_conf->div_group == 2) { /* Adjust the fast_div_bias based on main and alt_lna_conf */ switch ((ant_conf->main_lna_conf << 4) | -- cgit v1.2.3-70-g09d2 From c4cf2c589ddf7526fa1a3f28580ce8e4e611dd3d Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:47 +0200 Subject: ath9k: set diversity group for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index e788fa0d5af..1baca8e4715 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1215,7 +1215,10 @@ static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >> AR_PHY_9485_ANT_FAST_DIV_BIAS_S; - if (AR_SREV_9485(ah)) { + if (AR_SREV_9330_11(ah)) { + antconf->lna1_lna2_delta = -9; + antconf->div_group = 1; + } else if (AR_SREV_9485(ah)) { antconf->lna1_lna2_delta = -9; antconf->div_group = 2; } else { -- cgit v1.2.3-70-g09d2 From dfc3a7b66c963dfadcd0103c71b6bdaab9b2f738 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:48 +0200 Subject: ath9k: fix few register offsets for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index d259278fcc8..9eb3aa21168 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -625,11 +625,11 @@ #define AR_PHY_65NM_CH2_RXTX1 0x16900 #define AR_PHY_65NM_CH2_RXTX2 0x16904 -#define AR_CH0_TOP2 (AR_SREV_9485(ah) ? 0x00016284 : 0x0001628c) +#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : 0x16284) #define AR_CH0_TOP2_XPABIASLVL 0xf000 #define AR_CH0_TOP2_XPABIASLVL_S 12 -#define AR_CH0_XTAL (AR_SREV_9485(ah) ? 0x16290 : 0x16294) +#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : 0x16290) #define AR_CH0_XTAL_CAPINDAC 0x7f000000 #define AR_CH0_XTAL_CAPINDAC_S 24 #define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 -- cgit v1.2.3-70-g09d2 From 7b09e49ec822fe2bee34b45af89c72beed254a23 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:49 +0200 Subject: ath9k: configure diversity based on eeprom contents for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 7ea5105764d..666a1743801 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3525,7 +3525,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) } } - if (AR_SREV_9485(ah)) { + if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); /* * main_lnaconf, alt_lnaconf, main_tb, alt_tb -- cgit v1.2.3-70-g09d2 From 4187afa29a73fec1f68243c03437e7c1b37f315d Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:50 +0200 Subject: ath9k: configure internal regulator for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 666a1743801..1d09f22fee4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3712,7 +3712,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); if (internal_regulator) { - if (AR_SREV_9485(ah)) { + if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { int reg_pmu_set; reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM; @@ -3720,9 +3720,24 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) return; - reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) | - (2 << 14) | (6 << 17) | (1 << 20) | - (3 << 24) | (1 << 28); + if (AR_SREV_9330(ah)) { + if (ah->is_clk_25mhz) { + reg_pmu_set = (3 << 1) | (8 << 4) | + (3 << 8) | (1 << 14) | + (6 << 17) | (1 << 20) | + (3 << 24); + } else { + reg_pmu_set = (4 << 1) | (7 << 4) | + (3 << 8) | (1 << 14) | + (6 << 17) | (1 << 20) | + (3 << 24); + } + } else { + reg_pmu_set = (5 << 1) | (7 << 4) | + (1 << 8) | (2 << 14) | + (6 << 17) | (1 << 20) | + (3 << 24) | (1 << 28); + } REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set); if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set)) @@ -3753,7 +3768,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) AR_RTC_REG_CONTROL1_SWREG_PROGRAM); } } else { - if (AR_SREV_9485(ah)) { + if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0); while (REG_READ_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM)) -- cgit v1.2.3-70-g09d2 From 7d95847c9b3631d31f657d8cede153b518ed9e2e Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:51 +0200 Subject: ath9k: add external_reset callback to ath9k_platfom_data for AR9330 The patch adds a callback to ath9k_platform_data. If the callback is provided by the platform code, then it can be used to hard reset the WMAC device. The callback is required for doing a hard reset of the AR9330 chips to get them working again after a hang. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 35 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/init.c | 1 + include/linux/ath9k_platform.h | 1 + 4 files changed, 38 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 4da5284c777..839ba64c9e4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1161,6 +1161,41 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) rst_flags |= AR_RTC_RC_MAC_COLD; } + if (AR_SREV_9330(ah)) { + int npend = 0; + int i; + + /* AR9330 WAR: + * call external reset function to reset WMAC if: + * - doing a cold reset + * - we have pending frames in the TX queues + */ + + for (i = 0; i < AR_NUM_QCU; i++) { + npend = ath9k_hw_numtxpending(ah, i); + if (npend) + break; + } + + if (ah->external_reset && + (npend || type == ATH9K_RESET_COLD)) { + int reset_err = 0; + + ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, + "reset MAC via external reset\n"); + + reset_err = ah->external_reset(); + if (reset_err) { + ath_err(ath9k_hw_common(ah), + "External reset failed, err=%d\n", + reset_err); + return false; + } + + REG_WRITE(ah, AR_RTC_RESET, 1); + } + } + REG_WRITE(ah, AR_RTC_RC, rst_flags); REGWRITE_BUFFER_FLUSH(ah); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 0749fa8c3a5..818acdd1ba9 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -863,6 +863,7 @@ struct ath_hw { bool is_clk_25mhz; int (*get_mac_revision)(void); + int (*external_reset)(void); }; struct ath_bus_ops { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 1851c222fff..50103b2792b 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -575,6 +575,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, sc->sc_ah->led_pin = pdata->led_pin; ah->is_clk_25mhz = pdata->is_clk_25mhz; ah->get_mac_revision = pdata->get_mac_revision; + ah->external_reset = pdata->external_reset; } common = ath9k_hw_common(ah); diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index c207607acad..6e3f54f3784 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -31,6 +31,7 @@ struct ath9k_platform_data { bool is_clk_25mhz; int (*get_mac_revision)(void); + int (*external_reset)(void); }; #endif /* _LINUX_ATH9K_PLATFORM_H */ -- cgit v1.2.3-70-g09d2 From 999a7a88f1b062af5617fa55df317446af86a3da Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 21 Jun 2011 11:23:52 +0200 Subject: ath9k: enable support for AR9330 Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 839ba64c9e4..07827b55e84 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -644,6 +644,7 @@ int ath9k_hw_init(struct ath_hw *ah) case AR2427_DEVID_PCIE: case AR9300_DEVID_PCIE: case AR9300_DEVID_AR9485_PCIE: + case AR9300_DEVID_AR9330: case AR9300_DEVID_AR9340: break; default: -- cgit v1.2.3-70-g09d2 From cd15598707aff52da4302d9b6a3fc878bca27383 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 21 Jun 2011 20:57:16 +0200 Subject: ssb: add __devinit to some functions Two functions in ssb are using register_pci_controller() which is __devinit. The functions ssb_pcicore_init_hostmode() and ssb_gige_probe() should also be __devinit. This fixes the following warning: WARNING: vmlinux.o(.text+0x2727b8): Section mismatch in reference from the function ssb_pcicore_init_hostmode() to the function .devinit.text:register_pci_controller() The function ssb_pcicore_init_hostmode() references the function __devinit register_pci_controller(). This is often because ssb_pcicore_init_hostmode lacks a __devinit annotation or the annotation of register_pci_controller is wrong. WARNING: vmlinux.o(.text+0x273398): Section mismatch in reference from the function ssb_gige_probe() to the function .devinit.text:register_pci_controller() The function ssb_gige_probe() references the function __devinit register_pci_controller(). This is often because ssb_gige_probe lacks a __devinit annotation or the annotation of register_pci_controller is wrong. Reported-by: Ralf Baechle Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/b44.c | 4 ++-- drivers/net/wireless/b43/sdio.c | 6 +++--- drivers/ssb/driver_gige.c | 13 ++++++++----- drivers/ssb/driver_pcicore.c | 10 +++++----- drivers/ssb/main.c | 29 +++++++++++++++-------------- drivers/ssb/pcihost_wrapper.c | 6 +++--- 6 files changed, 36 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index a69331e06b8..91f7e6a0d4f 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2335,7 +2335,7 @@ static struct ssb_driver b44_ssb_driver = { .resume = b44_resume, }; -static inline int b44_pci_init(void) +static inline int __init b44_pci_init(void) { int err = 0; #ifdef CONFIG_B44_PCI @@ -2344,7 +2344,7 @@ static inline int b44_pci_init(void) return err; } -static inline void b44_pci_exit(void) +static inline void __exit b44_pci_exit(void) { #ifdef CONFIG_B44_PCI ssb_pcihost_unregister(&b44_pci_driver); diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index e6c733d37c9..4fd6775b8c3 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c @@ -93,8 +93,8 @@ void b43_sdio_free_irq(struct b43_wldev *dev) sdio->irq_handler = NULL; } -static int b43_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) +static int __devinit b43_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) { struct b43_sdio *sdio; struct sdio_func_tuple *tuple; @@ -171,7 +171,7 @@ out: return error; } -static void b43_sdio_remove(struct sdio_func *func) +static void __devexit b43_sdio_remove(struct sdio_func *func) { struct b43_sdio *sdio = sdio_get_drvdata(func); diff --git a/drivers/ssb/driver_gige.c b/drivers/ssb/driver_gige.c index 5ba92a2719a..d7589090922 100644 --- a/drivers/ssb/driver_gige.c +++ b/drivers/ssb/driver_gige.c @@ -106,8 +106,9 @@ void gige_pcicfg_write32(struct ssb_gige *dev, gige_write32(dev, SSB_GIGE_PCICFG + offset, value); } -static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn, - int reg, int size, u32 *val) +static int __devinit ssb_gige_pci_read_config(struct pci_bus *bus, + unsigned int devfn, int reg, + int size, u32 *val) { struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); unsigned long flags; @@ -136,8 +137,9 @@ static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } -static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn, - int reg, int size, u32 val) +static int __devinit ssb_gige_pci_write_config(struct pci_bus *bus, + unsigned int devfn, int reg, + int size, u32 val) { struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); unsigned long flags; @@ -166,7 +168,8 @@ static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } -static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id) +static int __devinit ssb_gige_probe(struct ssb_device *sdev, + const struct ssb_device_id *id) { struct ssb_gige *dev; u32 base, tmslow, tmshigh; diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 2a20dabec76..21b9465f71a 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -314,7 +314,7 @@ int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return ssb_mips_irq(extpci_core->dev) + 2; } -static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) +static void __devinit ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) { u32 val; @@ -379,7 +379,7 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) register_pci_controller(&ssb_pcicore_controller); } -static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) +static int __devinit pcicore_is_in_hostmode(struct ssb_pcicore *pc) { struct ssb_bus *bus = pc->dev->bus; u16 chipid_top; @@ -412,7 +412,7 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) * Workarounds. **************************************************/ -static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc) +static void __devinit ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc) { u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0)); if (((tmp & 0xF000) >> 12) != pc->dev->core_index) { @@ -514,13 +514,13 @@ static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) * Generic and Clientmode operation code. **************************************************/ -static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) +static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) { /* Disable PCI interrupts. */ ssb_write32(pc->dev, SSB_INTVEC, 0); } -void ssb_pcicore_init(struct ssb_pcicore *pc) +void __devinit ssb_pcicore_init(struct ssb_pcicore *pc) { struct ssb_device *dev = pc->dev; diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index f8a13f86321..e568664f8b9 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -557,7 +557,7 @@ error: } /* Needs ssb_buses_lock() */ -static int ssb_attach_queued_buses(void) +static int __devinit ssb_attach_queued_buses(void) { struct ssb_bus *bus, *n; int err = 0; @@ -768,9 +768,9 @@ out: return err; } -static int ssb_bus_register(struct ssb_bus *bus, - ssb_invariants_func_t get_invariants, - unsigned long baseaddr) +static int __devinit ssb_bus_register(struct ssb_bus *bus, + ssb_invariants_func_t get_invariants, + unsigned long baseaddr) { int err; @@ -851,8 +851,8 @@ err_disable_xtal: } #ifdef CONFIG_SSB_PCIHOST -int ssb_bus_pcibus_register(struct ssb_bus *bus, - struct pci_dev *host_pci) +int __devinit ssb_bus_pcibus_register(struct ssb_bus *bus, + struct pci_dev *host_pci) { int err; @@ -875,9 +875,9 @@ EXPORT_SYMBOL(ssb_bus_pcibus_register); #endif /* CONFIG_SSB_PCIHOST */ #ifdef CONFIG_SSB_PCMCIAHOST -int ssb_bus_pcmciabus_register(struct ssb_bus *bus, - struct pcmcia_device *pcmcia_dev, - unsigned long baseaddr) +int __devinit ssb_bus_pcmciabus_register(struct ssb_bus *bus, + struct pcmcia_device *pcmcia_dev, + unsigned long baseaddr) { int err; @@ -897,8 +897,9 @@ EXPORT_SYMBOL(ssb_bus_pcmciabus_register); #endif /* CONFIG_SSB_PCMCIAHOST */ #ifdef CONFIG_SSB_SDIOHOST -int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func, - unsigned int quirks) +int __devinit ssb_bus_sdiobus_register(struct ssb_bus *bus, + struct sdio_func *func, + unsigned int quirks) { int err; @@ -918,9 +919,9 @@ int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func, EXPORT_SYMBOL(ssb_bus_sdiobus_register); #endif /* CONFIG_SSB_PCMCIAHOST */ -int ssb_bus_ssbbus_register(struct ssb_bus *bus, - unsigned long baseaddr, - ssb_invariants_func_t get_invariants) +int __devinit ssb_bus_ssbbus_register(struct ssb_bus *bus, + unsigned long baseaddr, + ssb_invariants_func_t get_invariants) { int err; diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c index f6c8c81a002..d7a98131ebf 100644 --- a/drivers/ssb/pcihost_wrapper.c +++ b/drivers/ssb/pcihost_wrapper.c @@ -53,8 +53,8 @@ static int ssb_pcihost_resume(struct pci_dev *dev) # define ssb_pcihost_resume NULL #endif /* CONFIG_PM */ -static int ssb_pcihost_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int __devinit ssb_pcihost_probe(struct pci_dev *dev, + const struct pci_device_id *id) { struct ssb_bus *ssb; int err = -ENOMEM; @@ -110,7 +110,7 @@ static void ssb_pcihost_remove(struct pci_dev *dev) pci_set_drvdata(dev, NULL); } -int ssb_pcihost_register(struct pci_driver *driver) +int __devinit ssb_pcihost_register(struct pci_driver *driver) { driver->probe = ssb_pcihost_probe; driver->remove = ssb_pcihost_remove; -- cgit v1.2.3-70-g09d2 From 655f8919d549ad1872e24d826b6ce42530516d2e Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 22 Jun 2011 09:54:39 +0000 Subject: bonding: add min links parameter to 802.3ad This adds support for a configuring the minimum number of links that must be active before asserting carrier. It is similar to the Cisco EtherChannel min-links feature. This allows setting the minimum number of member ports that must be up (link-up state) before marking the bond device as up (carrier on). This is useful for situations where higher level services such as clustering want to ensure a minimum number of low bandwidth links are active before switchover. See: http://bugzilla.vyatta.com/show_bug.cgi?id=7196 Signed-off-by: Stephen Hemminger Signed-off-by: Flavio Leitner Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 13 +++++++++++-- drivers/net/bonding/bond_main.c | 5 +++++ drivers/net/bonding/bond_procfs.c | 1 + drivers/net/bonding/bond_sysfs.c | 33 +++++++++++++++++++++++++++++++++ drivers/net/bonding/bonding.h | 1 + 5 files changed, 51 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 77da2e84962..a047eb973e3 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2342,8 +2342,17 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) */ int bond_3ad_set_carrier(struct bonding *bond) { - if (__get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator))) { - if (!netif_carrier_ok(bond->dev)) { + struct aggregator *active; + + active = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator)); + if (active) { + /* are enough slaves available to consider link up? */ + if (active->num_of_ports < bond->params.min_links) { + if (netif_carrier_ok(bond->dev)) { + netif_carrier_off(bond->dev); + return 1; + } + } else if (!netif_carrier_ok(bond->dev)) { netif_carrier_on(bond->dev); return 1; } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ebb1d219b45..61265f74ed3 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -98,6 +98,7 @@ static char *mode; static char *primary; static char *primary_reselect; static char *lacp_rate; +static int min_links; static char *ad_select; static char *xmit_hash_policy; static int arp_interval = BOND_LINK_ARP_INTERV; @@ -150,6 +151,9 @@ module_param(ad_select, charp, 0); MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic; " "0 for stable (default), 1 for bandwidth, " "2 for count"); +module_param(min_links, int, 0); +MODULE_PARM_DESC(min_links, "Minimum number of available links before turning on carrier"); + module_param(xmit_hash_policy, charp, 0); MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; " "0 for layer 2 (default), 1 for layer 3+4, " @@ -4798,6 +4802,7 @@ static int bond_check_params(struct bond_params *params) params->tx_queues = tx_queues; params->all_slaves_active = all_slaves_active; params->resend_igmp = resend_igmp; + params->min_links = min_links; if (primary) { strncpy(params->primary, primary, IFNAMSIZ); diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index c97307ddd1c..95de93b9038 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -125,6 +125,7 @@ static void bond_info_show_master(struct seq_file *seq) seq_puts(seq, "\n802.3ad info\n"); seq_printf(seq, "LACP rate: %s\n", (bond->params.lacp_fast) ? "fast" : "slow"); + seq_printf(seq, "Min links: %d\n", bond->params.min_links); seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", ad_select_tbl[bond->params.ad_select].modename); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 03d1196b844..b60835f5865 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -819,6 +819,38 @@ out: static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp); +static ssize_t bonding_show_min_links(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct bonding *bond = to_bond(d); + + return sprintf(buf, "%d\n", bond->params.min_links); +} + +static ssize_t bonding_store_min_links(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct bonding *bond = to_bond(d); + int ret; + unsigned int new_value; + + ret = kstrtouint(buf, 0, &new_value); + if (ret < 0) { + pr_err("%s: Ignoring invalid min links value %s.\n", + bond->dev->name, buf); + return ret; + } + + pr_info("%s: Setting min links value to %u\n", + bond->dev->name, new_value); + bond->params.min_links = new_value; + return count; +} +static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR, + bonding_show_min_links, bonding_store_min_links); + static ssize_t bonding_show_ad_select(struct device *d, struct device_attribute *attr, char *buf) @@ -1601,6 +1633,7 @@ static struct attribute *per_bond_attrs[] = { &dev_attr_queue_id.attr, &dev_attr_all_slaves_active.attr, &dev_attr_resend_igmp.attr, + &dev_attr_min_links.attr, NULL, }; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 382903f0562..2936171f533 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -147,6 +147,7 @@ struct bond_params { int updelay; int downdelay; int lacp_fast; + unsigned int min_links; int ad_select; char primary[IFNAMSIZ]; int primary_reselect; -- cgit v1.2.3-70-g09d2 From b29a21694f7d12e40537e1e587ec47725849769b Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 11 May 2011 07:18:26 +0000 Subject: ixgbe: remove ntuple filtering Due to numerous issues in ntuple filters it has been decided to move the interface over to the network flow classification interface. As a first step to achieving this I first need to remove the old ntuple interface. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 136 -------------------------------------- 1 file changed, 136 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 4950d03d3ef..e41dd242cfc 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2336,141 +2336,6 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) return 0; } -static int ixgbe_set_rx_ntuple(struct net_device *dev, - struct ethtool_rx_ntuple *cmd) -{ - struct ixgbe_adapter *adapter = netdev_priv(dev); - struct ethtool_rx_ntuple_flow_spec *fs = &cmd->fs; - union ixgbe_atr_input input_struct; - struct ixgbe_atr_input_masks input_masks; - int target_queue; - int err; - - if (adapter->hw.mac.type == ixgbe_mac_82598EB) - return -EOPNOTSUPP; - - /* - * Don't allow programming if the action is a queue greater than - * the number of online Tx queues. - */ - if ((fs->action >= adapter->num_tx_queues) || - (fs->action < ETHTOOL_RXNTUPLE_ACTION_DROP)) - return -EINVAL; - - memset(&input_struct, 0, sizeof(union ixgbe_atr_input)); - memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks)); - - /* record flow type */ - switch (fs->flow_type) { - case IPV4_FLOW: - input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_IPV4; - break; - case TCP_V4_FLOW: - input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4; - break; - case UDP_V4_FLOW: - input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4; - break; - case SCTP_V4_FLOW: - input_struct.formatted.flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4; - break; - default: - return -1; - } - - /* copy vlan tag minus the CFI bit */ - if ((fs->vlan_tag & 0xEFFF) || (~fs->vlan_tag_mask & 0xEFFF)) { - input_struct.formatted.vlan_id = htons(fs->vlan_tag & 0xEFFF); - if (!fs->vlan_tag_mask) { - input_masks.vlan_id_mask = htons(0xEFFF); - } else { - switch (~fs->vlan_tag_mask & 0xEFFF) { - /* all of these are valid vlan-mask values */ - case 0xEFFF: - case 0xE000: - case 0x0FFF: - case 0x0000: - input_masks.vlan_id_mask = - htons(~fs->vlan_tag_mask); - break; - /* exit with error if vlan-mask is invalid */ - default: - e_err(drv, "Partial VLAN ID or " - "priority mask in vlan-mask is not " - "supported by hardware\n"); - return -1; - } - } - } - - /* make sure we only use the first 2 bytes of user data */ - if ((fs->data & 0xFFFF) || (~fs->data_mask & 0xFFFF)) { - input_struct.formatted.flex_bytes = htons(fs->data & 0xFFFF); - if (!(fs->data_mask & 0xFFFF)) { - input_masks.flex_mask = 0xFFFF; - } else if (~fs->data_mask & 0xFFFF) { - e_err(drv, "Partial user-def-mask is not " - "supported by hardware\n"); - return -1; - } - } - - /* - * Copy input into formatted structures - * - * These assignments are based on the following logic - * If neither input or mask are set assume value is masked out. - * If input is set, but mask is not mask should default to accept all. - * If input is not set, but mask is set then mask likely results in 0. - * If input is set and mask is set then assign both. - */ - if (fs->h_u.tcp_ip4_spec.ip4src || ~fs->m_u.tcp_ip4_spec.ip4src) { - input_struct.formatted.src_ip[0] = fs->h_u.tcp_ip4_spec.ip4src; - if (!fs->m_u.tcp_ip4_spec.ip4src) - input_masks.src_ip_mask[0] = 0xFFFFFFFF; - else - input_masks.src_ip_mask[0] = - ~fs->m_u.tcp_ip4_spec.ip4src; - } - if (fs->h_u.tcp_ip4_spec.ip4dst || ~fs->m_u.tcp_ip4_spec.ip4dst) { - input_struct.formatted.dst_ip[0] = fs->h_u.tcp_ip4_spec.ip4dst; - if (!fs->m_u.tcp_ip4_spec.ip4dst) - input_masks.dst_ip_mask[0] = 0xFFFFFFFF; - else - input_masks.dst_ip_mask[0] = - ~fs->m_u.tcp_ip4_spec.ip4dst; - } - if (fs->h_u.tcp_ip4_spec.psrc || ~fs->m_u.tcp_ip4_spec.psrc) { - input_struct.formatted.src_port = fs->h_u.tcp_ip4_spec.psrc; - if (!fs->m_u.tcp_ip4_spec.psrc) - input_masks.src_port_mask = 0xFFFF; - else - input_masks.src_port_mask = ~fs->m_u.tcp_ip4_spec.psrc; - } - if (fs->h_u.tcp_ip4_spec.pdst || ~fs->m_u.tcp_ip4_spec.pdst) { - input_struct.formatted.dst_port = fs->h_u.tcp_ip4_spec.pdst; - if (!fs->m_u.tcp_ip4_spec.pdst) - input_masks.dst_port_mask = 0xFFFF; - else - input_masks.dst_port_mask = ~fs->m_u.tcp_ip4_spec.pdst; - } - - /* determine if we need to drop or route the packet */ - if (fs->action == ETHTOOL_RXNTUPLE_ACTION_DROP) - target_queue = MAX_RX_QUEUES - 1; - else - target_queue = fs->action; - - spin_lock(&adapter->fdir_perfect_lock); - err = ixgbe_fdir_add_perfect_filter_82599(&adapter->hw, - &input_struct, - &input_masks, 0, - target_queue); - spin_unlock(&adapter->fdir_perfect_lock); - - return err ? -1 : 0; -} - static const struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, .set_settings = ixgbe_set_settings, @@ -2506,7 +2371,6 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .set_coalesce = ixgbe_set_coalesce, .get_flags = ethtool_op_get_flags, .set_flags = ixgbe_set_flags, - .set_rx_ntuple = ixgbe_set_rx_ntuple, }; void ixgbe_set_ethtool_ops(struct net_device *netdev) -- cgit v1.2.3-70-g09d2 From 03ecf91aae757eeb70763a3393227c4597c87b23 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 20 May 2011 07:36:17 +0000 Subject: ixgbe: fix flags relating to perfect filters to support coexistence I am removing the requirement that Ntuple filters have the same number of queues and requirements as ATR. As a result this change will make it so that all the Ntuple flag does is disable ATR for now. This change fixes an issue in which we were incorrectly re-enabling ATR when we exited perfect filter mode. This was due to the fact that the logic assumed RSS and DCB were mutually exclusive which is no longer the case. To correct this we just need to add a check to guarantee DCB is disabled before re-enabling ATR. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 13 ++++++------- drivers/net/ixgbe/ixgbe_ethtool.c | 24 ++++++++++++------------ drivers/net/ixgbe/ixgbe_main.c | 34 ++++++++++++---------------------- 3 files changed, 30 insertions(+), 41 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 08c7aebe99f..bd2d7526538 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -114,11 +114,12 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) u8 err = 0; struct ixgbe_adapter *adapter = netdev_priv(netdev); + /* verify there is something to do, if not then exit */ + if (!!state != !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + return err; + if (state > 0) { /* Turn on DCB */ - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) - goto out; - if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { e_err(drv, "Enable failed, needs MSI-X\n"); err = 1; @@ -143,9 +144,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS); } else { /* Turn off DCB */ - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - goto out; - adapter->hw.fc.requested_mode = adapter->last_lfc_mode; adapter->temp_dcb_cfg.pfc_mode_enable = false; adapter->dcb_cfg.pfc_mode_enable = false; @@ -153,7 +151,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: - adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; break; default: break; diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index e41dd242cfc..a2d8ed50605 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2310,20 +2310,20 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) * Check if Flow Director n-tuple support was enabled or disabled. If * the state changed, we need to reset. */ - if ((adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) && - (!(data & ETH_FLAG_NTUPLE))) { - /* turn off Flow Director perfect, set hash and reset */ + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { + /* turn off ATR, enable perfect filters and reset */ + if (data & ETH_FLAG_NTUPLE) { + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + need_reset = true; + } + } else if (!(data & ETH_FLAG_NTUPLE)) { + /* turn off Flow Director, set ATR and reset */ adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; - need_reset = true; - } else if ((!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) && - (data & ETH_FLAG_NTUPLE)) { - /* turn off Flow Director hash, enable perfect and reset */ - adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) && + !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; need_reset = true; - } else { - /* no state change */ } if (need_reset) { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 4cd66ae70cc..5483b9c3e2c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1555,9 +1555,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) q_vector->eitr = adapter->rx_eitr_param; ixgbe_write_eitr(q_vector); - /* If Flow Director is enabled, set interrupt affinity */ - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { + /* If ATR is enabled, set interrupt affinity */ + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { /* * Allocate the affinity_hint cpumask, assign the mask * for this vector, and set our affinity_hint for @@ -2468,8 +2467,7 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, default: break; } - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) mask |= IXGBE_EIMS_FLOW_DIR; IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); @@ -3767,8 +3765,6 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) adapter->tx_ring[i]->atr_sample_rate = adapter->atr_sample_rate; ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc); - } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { - ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc); } ixgbe_configure_virtualization(adapter); @@ -4334,15 +4330,13 @@ static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter) f_fdir->mask = 0; /* Flow Director must have RSS enabled */ - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED && - ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)))) { + if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) && + (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE)) { adapter->num_tx_queues = f_fdir->indices; adapter->num_rx_queues = f_fdir->indices; ret = true; } else { adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; } return ret; } @@ -4372,12 +4366,12 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { e_info(probe, "FCoE enabled with RSS\n"); - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ixgbe_set_fdir_queues(adapter); else ixgbe_set_rss_queues(adapter); } + /* adding FCoE rx rings to the end */ f->mask = adapter->num_rx_queues; adapter->num_rx_queues += f->indices; @@ -4670,9 +4664,8 @@ static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) int i; bool ret = false; - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED && - ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))) { + if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) && + (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE)) { for (i = 0; i < adapter->num_rx_queues; i++) adapter->rx_ring[i]->reg_idx = i; for (i = 0; i < adapter->num_tx_queues; i++) @@ -4701,8 +4694,7 @@ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) return false; if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ixgbe_cache_ring_fdir(adapter); else ixgbe_cache_ring_rss(adapter); @@ -4882,14 +4874,12 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; - if (adapter->flags & (IXGBE_FLAG_FDIR_HASH_CAPABLE | - IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { e_err(probe, - "Flow Director is not supported while multiple " + "ATR is not supported while multiple " "queues are disabled. Disabling Flow Director\n"); } adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; adapter->atr_sample_rate = 0; if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) ixgbe_disable_sriov(adapter); -- cgit v1.2.3-70-g09d2 From c04f6ca84866ef207e009a08e4c34ca241df7aa2 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 11 May 2011 07:18:36 +0000 Subject: ixgbe: update perfect filter framework to support retaining filters This change is meant to update the internal framework of ixgbe so that perfect filters can be stored and tracked via software. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 18 +- drivers/net/ixgbe/ixgbe_82599.c | 603 +++++++++++++++++++++++----------------- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbe/ixgbe_type.h | 25 +- 4 files changed, 368 insertions(+), 280 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index d5674fc8bc0..5ea5b4c08fe 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -543,16 +543,22 @@ extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); -extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); -extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); +extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl); +extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl); extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, union ixgbe_atr_hash_dword input, union ixgbe_atr_hash_dword common, u8 queue); -extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, - union ixgbe_atr_input *input, - struct ixgbe_atr_input_masks *input_masks, - u16 soft_id, u8 queue); +extern s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input_mask); +extern s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id, u8 queue); +extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id); +extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, + union ixgbe_atr_input *mask); extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring); extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 4a6826bf933..3b3dd4df4c5 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1107,115 +1107,87 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) } /** - * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters + * ixgbe_set_fdir_rxpba_82599 - Initialize Flow Director Rx packet buffer * @hw: pointer to hardware structure * @pballoc: which mode to allocate filters with **/ -s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) +static s32 ixgbe_set_fdir_rxpba_82599(struct ixgbe_hw *hw, const u32 pballoc) { - u32 fdirctrl = 0; + u32 fdir_pbsize = hw->mac.rx_pb_size << IXGBE_RXPBSIZE_SHIFT; + u32 current_rxpbsize = 0; int i; - /* Send interrupt when 64 filters are left */ - fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; - - /* Set the maximum length per hash bucket to 0xA filters */ - fdirctrl |= 0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT; - + /* reserve space for Flow Director filters */ switch (pballoc) { - case IXGBE_FDIR_PBALLOC_64K: - /* 8k - 1 signature filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K; + case IXGBE_FDIR_PBALLOC_256K: + fdir_pbsize -= 256 << IXGBE_RXPBSIZE_SHIFT; break; case IXGBE_FDIR_PBALLOC_128K: - /* 16k - 1 signature filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K; + fdir_pbsize -= 128 << IXGBE_RXPBSIZE_SHIFT; break; - case IXGBE_FDIR_PBALLOC_256K: - /* 32k - 1 signature filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K; + case IXGBE_FDIR_PBALLOC_64K: + fdir_pbsize -= 64 << IXGBE_RXPBSIZE_SHIFT; break; + case IXGBE_FDIR_PBALLOC_NONE: default: - /* bad value */ - return IXGBE_ERR_CONFIG; + return IXGBE_ERR_PARAM; } - /* Move the flexible bytes to use the ethertype - shift 6 words */ - fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT); + /* determine current RX packet buffer size */ + for (i = 0; i < 8; i++) + current_rxpbsize += IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); + /* if there is already room for the filters do nothing */ + if (current_rxpbsize <= fdir_pbsize) + return 0; - /* Prime the keys for hashing */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY); - IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY); - - /* - * Poll init-done after we write the register. Estimated times: - * 10G: PBALLOC = 11b, timing is 60us - * 1G: PBALLOC = 11b, timing is 600us - * 100M: PBALLOC = 11b, timing is 6ms - * - * Multiple these timings by 4 if under full Rx load - * - * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for - * 1 msec per poll time. If we're at line rate and drop to 100M, then - * this might not finish in our poll time, but we can live with that - * for now. - */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); - IXGBE_WRITE_FLUSH(hw); - for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { - if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & - IXGBE_FDIRCTRL_INIT_DONE) - break; - usleep_range(1000, 2000); + if (current_rxpbsize > hw->mac.rx_pb_size) { + /* + * if rxpbsize is greater than max then HW max the Rx buffer + * sizes are unconfigured or misconfigured since HW default is + * to give the full buffer to each traffic class resulting in + * the total size being buffer size 8x actual size + * + * This assumes no DCB since the RXPBSIZE registers appear to + * be unconfigured. + */ + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), fdir_pbsize); + for (i = 1; i < 8; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); + } else { + /* + * Since the Rx packet buffer appears to have already been + * configured we need to shrink each packet buffer by enough + * to make room for the filters. As such we take each rxpbsize + * value and multiply it by a fraction representing the size + * needed over the size we currently have. + * + * We need to reduce fdir_pbsize and current_rxpbsize to + * 1/1024 of their original values in order to avoid + * overflowing the u32 being used to store rxpbsize. + */ + fdir_pbsize >>= IXGBE_RXPBSIZE_SHIFT; + current_rxpbsize >>= IXGBE_RXPBSIZE_SHIFT; + for (i = 0; i < 8; i++) { + u32 rxpbsize = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); + rxpbsize *= fdir_pbsize; + rxpbsize /= current_rxpbsize; + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpbsize); + } } - if (i >= IXGBE_FDIR_INIT_DONE_POLL) - hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); return 0; } /** - * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters + * ixgbe_fdir_enable_82599 - Initialize Flow Director control registers * @hw: pointer to hardware structure - * @pballoc: which mode to allocate filters with + * @fdirctrl: value to write to flow director control register **/ -s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) +static void ixgbe_fdir_enable_82599(struct ixgbe_hw *hw, u32 fdirctrl) { - u32 fdirctrl = 0; int i; - /* Send interrupt when 64 filters are left */ - fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; - - /* Initialize the drop queue to Rx queue 127 */ - fdirctrl |= (127 << IXGBE_FDIRCTRL_DROP_Q_SHIFT); - - switch (pballoc) { - case IXGBE_FDIR_PBALLOC_64K: - /* 2k - 1 perfect filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K; - break; - case IXGBE_FDIR_PBALLOC_128K: - /* 4k - 1 perfect filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K; - break; - case IXGBE_FDIR_PBALLOC_256K: - /* 8k - 1 perfect filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K; - break; - default: - /* bad value */ - return IXGBE_ERR_CONFIG; - } - - /* Turn perfect match filtering on */ - fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH; - fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS; - - /* Move the flexible bytes to use the ethertype - shift 6 words */ - fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT); - /* Prime the keys for hashing */ IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY); IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY); @@ -1233,10 +1205,6 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) * this might not finish in our poll time, but we can live with that * for now. */ - - /* Set the maximum length per hash bucket to 0xA filters */ - fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT); - IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); IXGBE_WRITE_FLUSH(hw); for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { @@ -1245,101 +1213,77 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) break; usleep_range(1000, 2000); } - if (i >= IXGBE_FDIR_INIT_DONE_POLL) - hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n"); - return 0; + if (i >= IXGBE_FDIR_INIT_DONE_POLL) + hw_dbg(hw, "Flow Director poll time exceeded!\n"); } - /** - * ixgbe_atr_compute_hash_82599 - Compute the hashes for SW ATR - * @stream: input bitstream to compute the hash on - * @key: 32-bit hash key + * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters + * @hw: pointer to hardware structure + * @fdirctrl: value to write to flow director control register, initially + * contains just the value of the Rx packet buffer allocation **/ -static u32 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input, - u32 key) +s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl) { - /* - * The algorithm is as follows: - * Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350 - * where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n] - * and A[n] x B[n] is bitwise AND between same length strings - * - * K[n] is 16 bits, defined as: - * for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15] - * for n modulo 32 < 15, K[n] = - * K[(n % 32:0) | (31:31 - (14 - (n % 32)))] - * - * S[n] is 16 bits, defined as: - * for n >= 15, S[n] = S[n:n - 15] - * for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))] - * - * To simplify for programming, the algorithm is implemented - * in software this way: - * - * key[31:0], hi_hash_dword[31:0], lo_hash_dword[31:0], hash[15:0] - * - * for (i = 0; i < 352; i+=32) - * hi_hash_dword[31:0] ^= Stream[(i+31):i]; - * - * lo_hash_dword[15:0] ^= Stream[15:0]; - * lo_hash_dword[15:0] ^= hi_hash_dword[31:16]; - * lo_hash_dword[31:16] ^= hi_hash_dword[15:0]; - * - * hi_hash_dword[31:0] ^= Stream[351:320]; - * - * if(key[0]) - * hash[15:0] ^= Stream[15:0]; - * - * for (i = 0; i < 16; i++) { - * if (key[i]) - * hash[15:0] ^= lo_hash_dword[(i+15):i]; - * if (key[i + 16]) - * hash[15:0] ^= hi_hash_dword[(i+15):i]; - * } - * - */ - __be32 common_hash_dword = 0; - u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan; - u32 hash_result = 0; - u8 i; + s32 err; - /* record the flow_vm_vlan bits as they are a key part to the hash */ - flow_vm_vlan = ntohl(atr_input->dword_stream[0]); + /* Before enabling Flow Director, verify the Rx Packet Buffer size */ + err = ixgbe_set_fdir_rxpba_82599(hw, fdirctrl); + if (err) + return err; - /* generate common hash dword */ - for (i = 10; i; i -= 2) - common_hash_dword ^= atr_input->dword_stream[i] ^ - atr_input->dword_stream[i - 1]; + /* + * Continue setup of fdirctrl register bits: + * Move the flexible bytes to use the ethertype - shift 6 words + * Set the maximum length per hash bucket to 0xA filters + * Send interrupt when 64 filters are left + */ + fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) | + (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) | + (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT); - hi_hash_dword = ntohl(common_hash_dword); + /* write hashes and fdirctrl register, poll for completion */ + ixgbe_fdir_enable_82599(hw, fdirctrl); - /* low dword is word swapped version of common */ - lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16); + return 0; +} - /* apply flow ID/VM pool/VLAN ID bits to hash words */ - hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16); +/** + * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters + * @hw: pointer to hardware structure + * @fdirctrl: value to write to flow director control register, initially + * contains just the value of the Rx packet buffer allocation + **/ +s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl) +{ + s32 err; - /* Process bits 0 and 16 */ - if (key & 0x0001) hash_result ^= lo_hash_dword; - if (key & 0x00010000) hash_result ^= hi_hash_dword; + /* Before enabling Flow Director, verify the Rx Packet Buffer size */ + err = ixgbe_set_fdir_rxpba_82599(hw, fdirctrl); + if (err) + return err; /* - * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to - * delay this because bit 0 of the stream should not be processed - * so we do not add the vlan until after bit 0 was processed + * Continue setup of fdirctrl register bits: + * Turn perfect match filtering on + * Report hash in RSS field of Rx wb descriptor + * Initialize the drop queue + * Move the flexible bytes to use the ethertype - shift 6 words + * Set the maximum length per hash bucket to 0xA filters + * Send interrupt when 64 (0x4 * 16) filters are left */ - lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16); + fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH | + IXGBE_FDIRCTRL_REPORT_STATUS | + (IXGBE_FDIR_DROP_QUEUE << IXGBE_FDIRCTRL_DROP_Q_SHIFT) | + (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) | + (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) | + (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT); + /* write hashes and fdirctrl register, poll for completion */ + ixgbe_fdir_enable_82599(hw, fdirctrl); - /* process the remaining 30 bits in the key 2 bits at a time */ - for (i = 15; i; i-- ) { - if (key & (0x0001 << i)) hash_result ^= lo_hash_dword >> i; - if (key & (0x00010000 << i)) hash_result ^= hi_hash_dword >> i; - } - - return hash_result & IXGBE_ATR_HASH_MASK; + return 0; } /* @@ -1476,7 +1420,6 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, */ fdirhashcmd = (u64)fdircmd << 32; fdirhashcmd |= ixgbe_atr_compute_sig_hash_82599(input, common); - IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd); hw_dbg(hw, "Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd); @@ -1484,6 +1427,101 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, return 0; } +#define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) \ +do { \ + u32 n = (_n); \ + if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \ + bucket_hash ^= lo_hash_dword >> n; \ + if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \ + bucket_hash ^= hi_hash_dword >> n; \ +} while (0); + +/** + * ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash + * @atr_input: input bitstream to compute the hash on + * @input_mask: mask for the input bitstream + * + * This function serves two main purposes. First it applys the input_mask + * to the atr_input resulting in a cleaned up atr_input data stream. + * Secondly it computes the hash and stores it in the bkt_hash field at + * the end of the input byte stream. This way it will be available for + * future use without needing to recompute the hash. + **/ +void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, + union ixgbe_atr_input *input_mask) +{ + + u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan; + u32 bucket_hash = 0; + + /* Apply masks to input data */ + input->dword_stream[0] &= input_mask->dword_stream[0]; + input->dword_stream[1] &= input_mask->dword_stream[1]; + input->dword_stream[2] &= input_mask->dword_stream[2]; + input->dword_stream[3] &= input_mask->dword_stream[3]; + input->dword_stream[4] &= input_mask->dword_stream[4]; + input->dword_stream[5] &= input_mask->dword_stream[5]; + input->dword_stream[6] &= input_mask->dword_stream[6]; + input->dword_stream[7] &= input_mask->dword_stream[7]; + input->dword_stream[8] &= input_mask->dword_stream[8]; + input->dword_stream[9] &= input_mask->dword_stream[9]; + input->dword_stream[10] &= input_mask->dword_stream[10]; + + /* record the flow_vm_vlan bits as they are a key part to the hash */ + flow_vm_vlan = ntohl(input->dword_stream[0]); + + /* generate common hash dword */ + hi_hash_dword = ntohl(input->dword_stream[1] ^ + input->dword_stream[2] ^ + input->dword_stream[3] ^ + input->dword_stream[4] ^ + input->dword_stream[5] ^ + input->dword_stream[6] ^ + input->dword_stream[7] ^ + input->dword_stream[8] ^ + input->dword_stream[9] ^ + input->dword_stream[10]); + + /* low dword is word swapped version of common */ + lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16); + + /* apply flow ID/VM pool/VLAN ID bits to hash words */ + hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16); + + /* Process bits 0 and 16 */ + IXGBE_COMPUTE_BKT_HASH_ITERATION(0); + + /* + * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to + * delay this because bit 0 of the stream should not be processed + * so we do not add the vlan until after bit 0 was processed + */ + lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16); + + /* Process remaining 30 bit of the key */ + IXGBE_COMPUTE_BKT_HASH_ITERATION(1); + IXGBE_COMPUTE_BKT_HASH_ITERATION(2); + IXGBE_COMPUTE_BKT_HASH_ITERATION(3); + IXGBE_COMPUTE_BKT_HASH_ITERATION(4); + IXGBE_COMPUTE_BKT_HASH_ITERATION(5); + IXGBE_COMPUTE_BKT_HASH_ITERATION(6); + IXGBE_COMPUTE_BKT_HASH_ITERATION(7); + IXGBE_COMPUTE_BKT_HASH_ITERATION(8); + IXGBE_COMPUTE_BKT_HASH_ITERATION(9); + IXGBE_COMPUTE_BKT_HASH_ITERATION(10); + IXGBE_COMPUTE_BKT_HASH_ITERATION(11); + IXGBE_COMPUTE_BKT_HASH_ITERATION(12); + IXGBE_COMPUTE_BKT_HASH_ITERATION(13); + IXGBE_COMPUTE_BKT_HASH_ITERATION(14); + IXGBE_COMPUTE_BKT_HASH_ITERATION(15); + + /* + * Limit hash to 13 bits since max bucket count is 8K. + * Store result at the end of the input stream. + */ + input->formatted.bkt_hash = bucket_hash & 0x1FFF; +} + /** * ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks * @input_mask: mask to be bit swapped @@ -1493,11 +1531,11 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, * generate a correctly swapped value we need to bit swap the mask and that * is what is accomplished by this function. **/ -static u32 ixgbe_get_fdirtcpm_82599(struct ixgbe_atr_input_masks *input_masks) +static u32 ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input *input_mask) { - u32 mask = ntohs(input_masks->dst_port_mask); + u32 mask = ntohs(input_mask->formatted.dst_port); mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT; - mask |= ntohs(input_masks->src_port_mask); + mask |= ntohs(input_mask->formatted.src_port); mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1); mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2); mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4); @@ -1519,52 +1557,14 @@ static u32 ixgbe_get_fdirtcpm_82599(struct ixgbe_atr_input_masks *input_masks) IXGBE_WRITE_REG((a), (reg), IXGBE_STORE_AS_BE32(ntohl(value))) #define IXGBE_STORE_AS_BE16(_value) \ - (((u16)(_value) >> 8) | ((u16)(_value) << 8)) + ntohs(((u16)(_value) >> 8) | ((u16)(_value) << 8)) -/** - * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter - * @hw: pointer to hardware structure - * @input: input bitstream - * @input_masks: bitwise masks for relevant fields - * @soft_id: software index into the silicon hash tables for filter storage - * @queue: queue index to direct traffic to - * - * Note that the caller to this function must lock before calling, since the - * hardware writes must be protected from one another. - **/ -s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, - union ixgbe_atr_input *input, - struct ixgbe_atr_input_masks *input_masks, - u16 soft_id, u8 queue) +s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input_mask) { - u32 fdirhash; - u32 fdircmd; - u32 fdirport, fdirtcpm; - u32 fdirvlan; - /* start with VLAN, flex bytes, VM pool, and IPv6 destination masked */ - u32 fdirm = IXGBE_FDIRM_VLANID | IXGBE_FDIRM_VLANP | IXGBE_FDIRM_FLEX | - IXGBE_FDIRM_POOL | IXGBE_FDIRM_DIPv6; - - /* - * Check flow_type formatting, and bail out before we touch the hardware - * if there's a configuration issue - */ - switch (input->formatted.flow_type) { - case IXGBE_ATR_FLOW_TYPE_IPV4: - /* use the L4 protocol mask for raw IPv4/IPv6 traffic */ - fdirm |= IXGBE_FDIRM_L4P; - case IXGBE_ATR_FLOW_TYPE_SCTPV4: - if (input_masks->dst_port_mask || input_masks->src_port_mask) { - hw_dbg(hw, " Error on src/dst port mask\n"); - return IXGBE_ERR_CONFIG; - } - case IXGBE_ATR_FLOW_TYPE_TCPV4: - case IXGBE_ATR_FLOW_TYPE_UDPV4: - break; - default: - hw_dbg(hw, " Error on flow type input\n"); - return IXGBE_ERR_CONFIG; - } + /* mask IPv6 since it is currently not supported */ + u32 fdirm = IXGBE_FDIRM_DIPv6; + u32 fdirtcpm; /* * Program the relevant mask registers. If src/dst_port or src/dst_addr @@ -1576,41 +1576,71 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, * point in time. */ - /* Program FDIRM */ - switch (ntohs(input_masks->vlan_id_mask) & 0xEFFF) { - case 0xEFFF: - /* Unmask VLAN ID - bit 0 and fall through to unmask prio */ - fdirm &= ~IXGBE_FDIRM_VLANID; - case 0xE000: - /* Unmask VLAN prio - bit 1 */ - fdirm &= ~IXGBE_FDIRM_VLANP; + /* verify bucket hash is cleared on hash generation */ + if (input_mask->formatted.bkt_hash) + hw_dbg(hw, " bucket hash should always be 0 in mask\n"); + + /* Program FDIRM and verify partial masks */ + switch (input_mask->formatted.vm_pool & 0x7F) { + case 0x0: + fdirm |= IXGBE_FDIRM_POOL; + case 0x7F: break; - case 0x0FFF: - /* Unmask VLAN ID - bit 0 */ - fdirm &= ~IXGBE_FDIRM_VLANID; + default: + hw_dbg(hw, " Error on vm pool mask\n"); + return IXGBE_ERR_CONFIG; + } + + switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) { + case 0x0: + fdirm |= IXGBE_FDIRM_L4P; + if (input_mask->formatted.dst_port || + input_mask->formatted.src_port) { + hw_dbg(hw, " Error on src/dst port mask\n"); + return IXGBE_ERR_CONFIG; + } + case IXGBE_ATR_L4TYPE_MASK: break; + default: + hw_dbg(hw, " Error on flow type mask\n"); + return IXGBE_ERR_CONFIG; + } + + switch (ntohs(input_mask->formatted.vlan_id) & 0xEFFF) { case 0x0000: - /* do nothing, vlans already masked */ + /* mask VLAN ID, fall through to mask VLAN priority */ + fdirm |= IXGBE_FDIRM_VLANID; + case 0x0FFF: + /* mask VLAN priority */ + fdirm |= IXGBE_FDIRM_VLANP; + break; + case 0xE000: + /* mask VLAN ID only, fall through */ + fdirm |= IXGBE_FDIRM_VLANID; + case 0xEFFF: + /* no VLAN fields masked */ break; default: hw_dbg(hw, " Error on VLAN mask\n"); return IXGBE_ERR_CONFIG; } - if (input_masks->flex_mask & 0xFFFF) { - if ((input_masks->flex_mask & 0xFFFF) != 0xFFFF) { - hw_dbg(hw, " Error on flexible byte mask\n"); - return IXGBE_ERR_CONFIG; - } - /* Unmask Flex Bytes - bit 4 */ - fdirm &= ~IXGBE_FDIRM_FLEX; + switch (input_mask->formatted.flex_bytes & 0xFFFF) { + case 0x0000: + /* Mask Flex Bytes, fall through */ + fdirm |= IXGBE_FDIRM_FLEX; + case 0xFFFF: + break; + default: + hw_dbg(hw, " Error on flexible byte mask\n"); + return IXGBE_ERR_CONFIG; } /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm); /* store the TCP/UDP port masks, bit reversed from port layout */ - fdirtcpm = ixgbe_get_fdirtcpm_82599(input_masks); + fdirtcpm = ixgbe_get_fdirtcpm_82599(input_mask); /* write both the same so that UDP and TCP use the same mask */ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm); @@ -1618,24 +1648,32 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, /* store source and destination IP masks (big-enian) */ IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M, - ~input_masks->src_ip_mask[0]); + ~input_mask->formatted.src_ip[0]); IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M, - ~input_masks->dst_ip_mask[0]); + ~input_mask->formatted.dst_ip[0]); - /* Apply masks to input data */ - input->formatted.vlan_id &= input_masks->vlan_id_mask; - input->formatted.flex_bytes &= input_masks->flex_mask; - input->formatted.src_port &= input_masks->src_port_mask; - input->formatted.dst_port &= input_masks->dst_port_mask; - input->formatted.src_ip[0] &= input_masks->src_ip_mask[0]; - input->formatted.dst_ip[0] &= input_masks->dst_ip_mask[0]; + return 0; +} - /* record vlan (little-endian) and flex_bytes(big-endian) */ - fdirvlan = - IXGBE_STORE_AS_BE16(ntohs(input->formatted.flex_bytes)); - fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT; - fdirvlan |= ntohs(input->formatted.vlan_id); - IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan); +s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id, u8 queue) +{ + u32 fdirport, fdirvlan, fdirhash, fdircmd; + + /* currently IPv6 is not supported, must be programmed with 0 */ + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0), + input->formatted.src_ip[0]); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1), + input->formatted.src_ip[1]); + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2), + input->formatted.src_ip[2]); + + /* record the source address (big-endian) */ + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]); + + /* record the first 32 bits of the destination address (big-endian) */ + IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, input->formatted.dst_ip[0]); /* record source and destination port (little-endian)*/ fdirport = ntohs(input->formatted.dst_port); @@ -1643,29 +1681,80 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, fdirport |= ntohs(input->formatted.src_port); IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport); - /* record the first 32 bits of the destination address (big-endian) */ - IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, input->formatted.dst_ip[0]); + /* record vlan (little-endian) and flex_bytes(big-endian) */ + fdirvlan = IXGBE_STORE_AS_BE16(input->formatted.flex_bytes); + fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT; + fdirvlan |= ntohs(input->formatted.vlan_id); + IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan); - /* record the source address (big-endian) */ - IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]); + /* configure FDIRHASH register */ + fdirhash = input->formatted.bkt_hash; + fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); + + /* + * flush all previous writes to make certain registers are + * programmed prior to issuing the command + */ + IXGBE_WRITE_FLUSH(hw); /* configure FDIRCMD register */ fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN; + if (queue == IXGBE_FDIR_DROP_QUEUE) + fdircmd |= IXGBE_FDIRCMD_DROP; fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; + fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT; - /* we only want the bucket hash so drop the upper 16 bits */ - fdirhash = ixgbe_atr_compute_hash_82599(input, - IXGBE_ATR_BUCKET_HASH_KEY); - fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT; - - IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd); return 0; } +s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, + union ixgbe_atr_input *input, + u16 soft_id) +{ + u32 fdirhash; + u32 fdircmd = 0; + u32 retry_count; + s32 err = 0; + + /* configure FDIRHASH register */ + fdirhash = input->formatted.bkt_hash; + fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); + + /* flush hash to HW */ + IXGBE_WRITE_FLUSH(hw); + + /* Query if filter is present */ + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT); + + for (retry_count = 10; retry_count; retry_count--) { + /* allow 10us for query to process */ + udelay(10); + /* verify query completed successfully */ + fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD); + if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK)) + break; + } + + if (!retry_count) + err = IXGBE_ERR_FDIR_REINIT_FAILED; + + /* if filter exists in hardware then remove it */ + if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) { + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); + IXGBE_WRITE_FLUSH(hw); + IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, + IXGBE_FDIRCMD_CMD_REMOVE_FLOW); + } + + return err; +} + /** * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5483b9c3e2c..e177b5d061f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5130,7 +5130,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->atr_sample_rate = 20; adapter->ring_feature[RING_F_FDIR].indices = IXGBE_MAX_FDIR_INDICES; - adapter->fdir_pballoc = 0; + adapter->fdir_pballoc = IXGBE_FDIR_PBALLOC_64K; #ifdef IXGBE_FCOE adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 9a499a61d14..8b1abd47056 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2056,9 +2056,10 @@ enum { #define IXGBE_VFLREC(_i) (0x00700 + (_i * 4)) enum ixgbe_fdir_pballoc_type { - IXGBE_FDIR_PBALLOC_64K = 0, - IXGBE_FDIR_PBALLOC_128K, - IXGBE_FDIR_PBALLOC_256K, + IXGBE_FDIR_PBALLOC_NONE = 0, + IXGBE_FDIR_PBALLOC_64K = 1, + IXGBE_FDIR_PBALLOC_128K = 2, + IXGBE_FDIR_PBALLOC_256K = 3, }; #define IXGBE_FDIR_PBALLOC_SIZE_SHIFT 16 @@ -2112,7 +2113,7 @@ enum ixgbe_fdir_pballoc_type { #define IXGBE_FDIRCMD_CMD_ADD_FLOW 0x00000001 #define IXGBE_FDIRCMD_CMD_REMOVE_FLOW 0x00000002 #define IXGBE_FDIRCMD_CMD_QUERY_REM_FILT 0x00000003 -#define IXGBE_FDIRCMD_CMD_QUERY_REM_HASH 0x00000007 +#define IXGBE_FDIRCMD_FILTER_VALID 0x00000004 #define IXGBE_FDIRCMD_FILTER_UPDATE 0x00000008 #define IXGBE_FDIRCMD_IPv6DMATCH 0x00000010 #define IXGBE_FDIRCMD_L4TYPE_UDP 0x00000020 @@ -2131,6 +2132,8 @@ enum ixgbe_fdir_pballoc_type { #define IXGBE_FDIR_INIT_DONE_POLL 10 #define IXGBE_FDIRCMD_CMD_POLL 10 +#define IXGBE_FDIR_DROP_QUEUE 127 + /* Manageablility Host Interface defines */ #define IXGBE_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */ #define IXGBE_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */ @@ -2350,7 +2353,7 @@ union ixgbe_atr_input { * src_port - 2 bytes * dst_port - 2 bytes * flex_bytes - 2 bytes - * rsvd0 - 2 bytes - space reserved must be 0. + * bkt_hash - 2 bytes */ struct { u8 vm_pool; @@ -2361,7 +2364,7 @@ union ixgbe_atr_input { __be16 src_port; __be16 dst_port; __be16 flex_bytes; - __be16 rsvd0; + __be16 bkt_hash; } formatted; __be32 dword_stream[11]; }; @@ -2382,16 +2385,6 @@ union ixgbe_atr_hash_dword { __be32 dword; }; -struct ixgbe_atr_input_masks { - __be16 rsvd0; - __be16 vlan_id_mask; - __be32 dst_ip_mask[4]; - __be32 src_ip_mask[4]; - __be16 src_port_mask; - __be16 dst_port_mask; - __be16 flex_mask; -}; - enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, ixgbe_eeprom_spi, -- cgit v1.2.3-70-g09d2 From 91cd94bfe4f00fccf692e32dfa86a9fad0d61280 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 11 May 2011 07:18:41 +0000 Subject: ixgbe: add basic support for setting and getting nfc controls This change adds basic support for the obtaining of RSS ring counts. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index a2d8ed50605..837324429f5 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2336,6 +2336,24 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) return 0; } +static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + void *rule_locs) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = adapter->num_rx_queues; + ret = 0; + break; + default: + break; + } + + return ret; +} + static const struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, .set_settings = ixgbe_set_settings, @@ -2371,6 +2389,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .set_coalesce = ixgbe_set_coalesce, .get_flags = ethtool_op_get_flags, .set_flags = ixgbe_set_flags, + .get_rxnfc = ixgbe_get_rxnfc, }; void ixgbe_set_ethtool_ops(struct net_device *netdev) -- cgit v1.2.3-70-g09d2 From 3e05334f8be83e8529f1cbf4f4dea06a4d51d676 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 11 May 2011 07:18:47 +0000 Subject: ixgbe: add support for displaying ntuple filters via the nfc interface This code adds support for displaying the filters that were added via the nfc interface. This is primarily to test the interface for now, but I am also looking into the feasibility of moving all of the ntuple filter code in ixgbe over to the nfc interface since it seems to be better implemented. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 11 ++++ drivers/net/ixgbe/ixgbe_ethtool.c | 102 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 5ea5b4c08fe..d6bfb2f6ba8 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -482,6 +482,17 @@ struct ixgbe_adapter { struct vf_macvlans vf_mvs; struct vf_macvlans *mv_list; bool antispoofing_enabled; + + struct hlist_head fdir_filter_list; + union ixgbe_atr_input fdir_mask; + int fdir_filter_count; +}; + +struct ixgbe_fdir_filter { + struct hlist_node fdir_node; + union ixgbe_atr_input filter; + u16 sw_idx; + u16 action; }; enum ixbge_state_t { diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 837324429f5..649e5960f24 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2336,6 +2336,97 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) return 0; } +static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + union ixgbe_atr_input *mask = &adapter->fdir_mask; + struct ethtool_rx_flow_spec *fsp = + (struct ethtool_rx_flow_spec *)&cmd->fs; + struct hlist_node *node, *node2; + struct ixgbe_fdir_filter *rule = NULL; + + /* report total rule count */ + cmd->data = (1024 << adapter->fdir_pballoc) - 2; + + hlist_for_each_entry_safe(rule, node, node2, + &adapter->fdir_filter_list, fdir_node) { + if (fsp->location <= rule->sw_idx) + break; + } + + if (!rule || fsp->location != rule->sw_idx) + return -EINVAL; + + /* fill out the flow spec entry */ + + /* set flow type field */ + switch (rule->filter.formatted.flow_type) { + case IXGBE_ATR_FLOW_TYPE_TCPV4: + fsp->flow_type = TCP_V4_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_UDPV4: + fsp->flow_type = UDP_V4_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_SCTPV4: + fsp->flow_type = SCTP_V4_FLOW; + break; + case IXGBE_ATR_FLOW_TYPE_IPV4: + fsp->flow_type = IP_USER_FLOW; + fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4; + fsp->h_u.usr_ip4_spec.proto = 0; + fsp->m_u.usr_ip4_spec.proto = 0; + break; + default: + return -EINVAL; + } + + fsp->h_u.tcp_ip4_spec.psrc = rule->filter.formatted.src_port; + fsp->m_u.tcp_ip4_spec.psrc = mask->formatted.src_port; + fsp->h_u.tcp_ip4_spec.pdst = rule->filter.formatted.dst_port; + fsp->m_u.tcp_ip4_spec.pdst = mask->formatted.dst_port; + fsp->h_u.tcp_ip4_spec.ip4src = rule->filter.formatted.src_ip[0]; + fsp->m_u.tcp_ip4_spec.ip4src = mask->formatted.src_ip[0]; + fsp->h_u.tcp_ip4_spec.ip4dst = rule->filter.formatted.dst_ip[0]; + fsp->m_u.tcp_ip4_spec.ip4dst = mask->formatted.dst_ip[0]; + fsp->h_ext.vlan_tci = rule->filter.formatted.vlan_id; + fsp->m_ext.vlan_tci = mask->formatted.vlan_id; + fsp->h_ext.vlan_etype = rule->filter.formatted.flex_bytes; + fsp->m_ext.vlan_etype = mask->formatted.flex_bytes; + fsp->h_ext.data[1] = htonl(rule->filter.formatted.vm_pool); + fsp->m_ext.data[1] = htonl(mask->formatted.vm_pool); + fsp->flow_type |= FLOW_EXT; + + /* record action */ + if (rule->action == IXGBE_FDIR_DROP_QUEUE) + fsp->ring_cookie = RX_CLS_FLOW_DISC; + else + fsp->ring_cookie = rule->action; + + return 0; +} + +static int ixgbe_get_ethtool_fdir_all(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd, + u32 *rule_locs) +{ + struct hlist_node *node, *node2; + struct ixgbe_fdir_filter *rule; + int cnt = 0; + + /* report total rule count */ + cmd->data = (1024 << adapter->fdir_pballoc) - 2; + + hlist_for_each_entry_safe(rule, node, node2, + &adapter->fdir_filter_list, fdir_node) { + if (cnt == cmd->rule_cnt) + return -EMSGSIZE; + rule_locs[cnt] = rule->sw_idx; + cnt++; + } + + return 0; +} + static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, void *rule_locs) { @@ -2347,6 +2438,17 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, cmd->data = adapter->num_rx_queues; ret = 0; break; + case ETHTOOL_GRXCLSRLCNT: + cmd->rule_cnt = adapter->fdir_filter_count; + ret = 0; + break; + case ETHTOOL_GRXCLSRULE: + ret = ixgbe_get_ethtool_fdir_entry(adapter, cmd); + break; + case ETHTOOL_GRXCLSRLALL: + ret = ixgbe_get_ethtool_fdir_all(adapter, cmd, + (u32 *)rule_locs); + break; default: break; } -- cgit v1.2.3-70-g09d2 From e4911d57a45ca30771c64b56e552891fcd105070 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 11 May 2011 07:18:52 +0000 Subject: ixgbe: add support for nfc addition and removal of filters This change is meant to allow for nfc to insert and remove filters in order to test the ethtool interface which includes it's own rules manager. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 245 ++++++++++++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_main.c | 45 +++++++ 2 files changed, 290 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 649e5960f24..2965b6e7728 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2456,6 +2456,250 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, return ret; } +static int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ixgbe_fdir_filter *input, + u16 sw_idx) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct hlist_node *node, *node2, *parent; + struct ixgbe_fdir_filter *rule; + int err = -EINVAL; + + parent = NULL; + rule = NULL; + + hlist_for_each_entry_safe(rule, node, node2, + &adapter->fdir_filter_list, fdir_node) { + /* hash found, or no matching entry */ + if (rule->sw_idx >= sw_idx) + break; + parent = node; + } + + /* if there is an old rule occupying our place remove it */ + if (rule && (rule->sw_idx == sw_idx)) { + if (!input || (rule->filter.formatted.bkt_hash != + input->filter.formatted.bkt_hash)) { + err = ixgbe_fdir_erase_perfect_filter_82599(hw, + &rule->filter, + sw_idx); + } + + hlist_del(&rule->fdir_node); + kfree(rule); + adapter->fdir_filter_count--; + } + + /* + * If no input this was a delete, err should be 0 if a rule was + * successfully found and removed from the list else -EINVAL + */ + if (!input) + return err; + + /* initialize node and set software index */ + INIT_HLIST_NODE(&input->fdir_node); + + /* add filter to the list */ + if (parent) + hlist_add_after(parent, &input->fdir_node); + else + hlist_add_head(&input->fdir_node, + &adapter->fdir_filter_list); + + /* update counts */ + adapter->fdir_filter_count++; + + return 0; +} + +static int ixgbe_flowspec_to_flow_type(struct ethtool_rx_flow_spec *fsp, + u8 *flow_type) +{ + switch (fsp->flow_type & ~FLOW_EXT) { + case TCP_V4_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4; + break; + case UDP_V4_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4; + break; + case SCTP_V4_FLOW: + *flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4; + break; + case IP_USER_FLOW: + switch (fsp->h_u.usr_ip4_spec.proto) { + case IPPROTO_TCP: + *flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4; + break; + case IPPROTO_UDP: + *flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4; + break; + case IPPROTO_SCTP: + *flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4; + break; + case 0: + if (!fsp->m_u.usr_ip4_spec.proto) { + *flow_type = IXGBE_ATR_FLOW_TYPE_IPV4; + break; + } + default: + return 0; + } + break; + default: + return 0; + } + + return 1; +} + +static int ixgbe_add_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fsp = + (struct ethtool_rx_flow_spec *)&cmd->fs; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_fdir_filter *input; + union ixgbe_atr_input mask; + int err; + + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + return -EOPNOTSUPP; + + /* + * Don't allow programming if the action is a queue greater than + * the number of online Rx queues. + */ + if ((fsp->ring_cookie != RX_CLS_FLOW_DISC) && + (fsp->ring_cookie >= adapter->num_rx_queues)) + return -EINVAL; + + /* Don't allow indexes to exist outside of available space */ + if (fsp->location >= ((1024 << adapter->fdir_pballoc) - 2)) { + e_err(drv, "Location out of range\n"); + return -EINVAL; + } + + input = kzalloc(sizeof(*input), GFP_ATOMIC); + if (!input) + return -ENOMEM; + + memset(&mask, 0, sizeof(union ixgbe_atr_input)); + + /* set SW index */ + input->sw_idx = fsp->location; + + /* record flow type */ + if (!ixgbe_flowspec_to_flow_type(fsp, + &input->filter.formatted.flow_type)) { + e_err(drv, "Unrecognized flow type\n"); + goto err_out; + } + + mask.formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK | + IXGBE_ATR_L4TYPE_MASK; + + if (input->filter.formatted.flow_type == IXGBE_ATR_FLOW_TYPE_IPV4) + mask.formatted.flow_type &= IXGBE_ATR_L4TYPE_IPV6_MASK; + + /* Copy input into formatted structures */ + input->filter.formatted.src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src; + mask.formatted.src_ip[0] = fsp->m_u.tcp_ip4_spec.ip4src; + input->filter.formatted.dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst; + mask.formatted.dst_ip[0] = fsp->m_u.tcp_ip4_spec.ip4dst; + input->filter.formatted.src_port = fsp->h_u.tcp_ip4_spec.psrc; + mask.formatted.src_port = fsp->m_u.tcp_ip4_spec.psrc; + input->filter.formatted.dst_port = fsp->h_u.tcp_ip4_spec.pdst; + mask.formatted.dst_port = fsp->m_u.tcp_ip4_spec.pdst; + + if (fsp->flow_type & FLOW_EXT) { + input->filter.formatted.vm_pool = + (unsigned char)ntohl(fsp->h_ext.data[1]); + mask.formatted.vm_pool = + (unsigned char)ntohl(fsp->m_ext.data[1]); + input->filter.formatted.vlan_id = fsp->h_ext.vlan_tci; + mask.formatted.vlan_id = fsp->m_ext.vlan_tci; + input->filter.formatted.flex_bytes = + fsp->h_ext.vlan_etype; + mask.formatted.flex_bytes = fsp->m_ext.vlan_etype; + } + + /* determine if we need to drop or route the packet */ + if (fsp->ring_cookie == RX_CLS_FLOW_DISC) + input->action = IXGBE_FDIR_DROP_QUEUE; + else + input->action = fsp->ring_cookie; + + spin_lock(&adapter->fdir_perfect_lock); + + if (hlist_empty(&adapter->fdir_filter_list)) { + /* save mask and program input mask into HW */ + memcpy(&adapter->fdir_mask, &mask, sizeof(mask)); + err = ixgbe_fdir_set_input_mask_82599(hw, &mask); + if (err) { + e_err(drv, "Error writing mask\n"); + goto err_out_w_lock; + } + } else if (memcmp(&adapter->fdir_mask, &mask, sizeof(mask))) { + e_err(drv, "Only one mask supported per port\n"); + goto err_out_w_lock; + } + + /* apply mask and compute/store hash */ + ixgbe_atr_compute_perfect_hash_82599(&input->filter, &mask); + + /* program filters to filter memory */ + err = ixgbe_fdir_write_perfect_filter_82599(hw, + &input->filter, input->sw_idx, + adapter->rx_ring[input->action]->reg_idx); + if (err) + goto err_out_w_lock; + + ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); + + spin_unlock(&adapter->fdir_perfect_lock); + + return err; +err_out_w_lock: + spin_unlock(&adapter->fdir_perfect_lock); +err_out: + kfree(input); + return -EINVAL; +} + +static int ixgbe_del_ethtool_fdir_entry(struct ixgbe_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + struct ethtool_rx_flow_spec *fsp = + (struct ethtool_rx_flow_spec *)&cmd->fs; + int err; + + spin_lock(&adapter->fdir_perfect_lock); + err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, fsp->location); + spin_unlock(&adapter->fdir_perfect_lock); + + return err; +} + +static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + switch (cmd->cmd) { + case ETHTOOL_SRXCLSRLINS: + ret = ixgbe_add_ethtool_fdir_entry(adapter, cmd); + break; + case ETHTOOL_SRXCLSRLDEL: + ret = ixgbe_del_ethtool_fdir_entry(adapter, cmd); + break; + default: + break; + } + + return ret; +} + static const struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, .set_settings = ixgbe_set_settings, @@ -2492,6 +2736,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .get_flags = ethtool_op_get_flags, .set_flags = ixgbe_set_flags, .get_rxnfc = ixgbe_get_rxnfc, + .set_rxnfc = ixgbe_set_rxnfc, }; void ixgbe_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e177b5d061f..2886daec70a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3741,6 +3741,28 @@ static void ixgbe_configure_pb(struct ixgbe_adapter *adapter) hw->mac.ops.set_rxpba(&adapter->hw, num_tc, hdrm, PBA_STRATEGY_EQUAL); } +static void ixgbe_fdir_filter_restore(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct hlist_node *node, *node2; + struct ixgbe_fdir_filter *filter; + + spin_lock(&adapter->fdir_perfect_lock); + + if (!hlist_empty(&adapter->fdir_filter_list)) + ixgbe_fdir_set_input_mask_82599(hw, &adapter->fdir_mask); + + hlist_for_each_entry_safe(filter, node, node2, + &adapter->fdir_filter_list, fdir_node) { + ixgbe_fdir_write_perfect_filter_82599(hw, + &filter->filter, + filter->sw_idx, + filter->action); + } + + spin_unlock(&adapter->fdir_perfect_lock); +} + static void ixgbe_configure(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -3765,6 +3787,10 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) adapter->tx_ring[i]->atr_sample_rate = adapter->atr_sample_rate; ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc); + } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { + ixgbe_init_fdir_perfect_82599(&adapter->hw, + adapter->fdir_pballoc); + ixgbe_fdir_filter_restore(adapter); } ixgbe_configure_virtualization(adapter); @@ -4141,6 +4167,23 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) ixgbe_clean_tx_ring(adapter->tx_ring[i]); } +static void ixgbe_fdir_filter_exit(struct ixgbe_adapter *adapter) +{ + struct hlist_node *node, *node2; + struct ixgbe_fdir_filter *filter; + + spin_lock(&adapter->fdir_perfect_lock); + + hlist_for_each_entry_safe(filter, node, node2, + &adapter->fdir_filter_list, fdir_node) { + hlist_del(&filter->fdir_node); + kfree(filter); + } + adapter->fdir_filter_count = 0; + + spin_unlock(&adapter->fdir_perfect_lock); +} + void ixgbe_down(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -5527,6 +5570,8 @@ static int ixgbe_close(struct net_device *netdev) ixgbe_down(adapter); ixgbe_free_irq(adapter); + ixgbe_fdir_filter_exit(adapter); + ixgbe_free_all_tx_resources(adapter); ixgbe_free_all_rx_resources(adapter); -- cgit v1.2.3-70-g09d2 From 3a28926451a22a2b699962e738c8540da642c319 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 13 May 2011 02:22:40 +0000 Subject: ixgbe: move setting RSC into a separate function Move setting RSC into a separate function to allow for reuse in other parts of the code. Signed-off-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 2965b6e7728..405c5ba1d56 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -459,6 +459,21 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) return 0; } +static void ixgbe_set_rsc(struct ixgbe_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + set_ring_rsc_enabled(ring); + ixgbe_configure_rscctl(adapter, ring); + } else { + ixgbe_clear_rscctl(adapter, ring); + } + } +} + static u32 ixgbe_get_tx_csum(struct net_device *netdev) { return (netdev->features & NETIF_F_IP_CSUM) != 0; @@ -2281,25 +2296,12 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) } else { adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + ixgbe_set_rsc(adapter); + break; case ixgbe_mac_82599EB: need_reset = true; break; - case ixgbe_mac_X540: { - int i; - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = - adapter->rx_ring[i]; - if (adapter->flags2 & - IXGBE_FLAG2_RSC_ENABLED) { - ixgbe_configure_rscctl(adapter, - ring); - } else { - ixgbe_clear_rscctl(adapter, - ring); - } - } - } - break; default: break; } -- cgit v1.2.3-70-g09d2 From c988ee829074073d3cd80090ef56a6e370b5c9b4 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 13 May 2011 02:22:45 +0000 Subject: ixgbe: move reset code into a separate function Move reset code into a separate function to allow for reuse in other parts of the code. Signed-off-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 405c5ba1d56..bb8441e3990 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -442,6 +442,16 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, return 0; } +static void ixgbe_do_reset(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); +} + static u32 ixgbe_get_rx_csum(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -2249,12 +2259,8 @@ static int ixgbe_set_coalesce(struct net_device *netdev, * correctly w.r.t stopping tx, and changing TXDCTL.WTHRESH settings * also locks in RSC enable/disable which requires reset */ - if (need_reset) { - if (netif_running(netdev)) - ixgbe_reinit_locked(adapter); - else - ixgbe_reset(adapter); - } + if (need_reset) + ixgbe_do_reset(netdev); return 0; } @@ -2328,12 +2334,8 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) need_reset = true; } - if (need_reset) { - if (netif_running(netdev)) - ixgbe_reinit_locked(adapter); - else - ixgbe_reset(adapter); - } + if (need_reset) + ixgbe_do_reset(netdev); return 0; } -- cgit v1.2.3-70-g09d2 From 2ba279e2f72a9112a2536eabc8fae5413bbbdfb6 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 13 May 2011 02:22:50 +0000 Subject: ixgbe: disable RSC when Rx checksum is off Disabling Rx checksumming leads to performance degradation due to RSC causing packets to have incorrect checksums. Signed-off-by: Emil Tantilov Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 44 +++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index bb8441e3990..596d7943024 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -458,17 +458,6 @@ static u32 ixgbe_get_rx_csum(struct net_device *netdev) return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED; } -static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - if (data) - adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; - else - adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; - - return 0; -} - static void ixgbe_set_rsc(struct ixgbe_adapter *adapter) { int i; @@ -484,6 +473,39 @@ static void ixgbe_set_rsc(struct ixgbe_adapter *adapter) } } +static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool need_reset = false; + + if (data) { + adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; + } else { + adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; + + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) { + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + netdev->features &= ~NETIF_F_LRO; + } + + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + ixgbe_set_rsc(adapter); + break; + case ixgbe_mac_82599EB: + need_reset = true; + break; + default: + break; + } + } + + if (need_reset) + ixgbe_do_reset(netdev); + + return 0; +} + static u32 ixgbe_get_tx_csum(struct net_device *netdev) { return (netdev->features & NETIF_F_IP_CSUM) != 0; -- cgit v1.2.3-70-g09d2 From 1f4d51836f5e49f2e5201f1daf90239c04b3faf2 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 14 May 2011 01:16:02 +0000 Subject: ixgbe: fix ring assignment issues for SR-IOV and drop cases This change fixes the fact that we would trigger a null pointer dereference or specify the wrong ring if the rings were restored. This change makes certain that the DROP queue is a static value, and all other rings are based on the ring offsets for the PF. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 2 ++ drivers/net/ixgbe/ixgbe_main.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 596d7943024..074e9baf069 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2677,6 +2677,8 @@ static int ixgbe_add_ethtool_fdir_entry(struct ixgbe_adapter *adapter, /* program filters to filter memory */ err = ixgbe_fdir_write_perfect_filter_82599(hw, &input->filter, input->sw_idx, + (input->action == IXGBE_FDIR_DROP_QUEUE) ? + IXGBE_FDIR_DROP_QUEUE : adapter->rx_ring[input->action]->reg_idx); if (err) goto err_out_w_lock; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 2886daec70a..916a2b64e5f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3755,9 +3755,11 @@ static void ixgbe_fdir_filter_restore(struct ixgbe_adapter *adapter) hlist_for_each_entry_safe(filter, node, node2, &adapter->fdir_filter_list, fdir_node) { ixgbe_fdir_write_perfect_filter_82599(hw, - &filter->filter, - filter->sw_idx, - filter->action); + &filter->filter, + filter->sw_idx, + (filter->action == IXGBE_FDIR_DROP_QUEUE) ? + IXGBE_FDIR_DROP_QUEUE : + adapter->rx_ring[filter->action]->reg_idx); } spin_unlock(&adapter->fdir_perfect_lock); -- cgit v1.2.3-70-g09d2 From a38a104d7af27b7697bf7c4272f4be5d1ec6ef4c Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 20 May 2011 03:05:14 +0000 Subject: ixgbe: update driver version string Update the ixgbe driver version string to better match the Source Driver with similar device support. Likewise update to the current LAD Linux versioning scheme. Signed-of-by: Don Skidmore Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 8 ++++---- drivers/net/ixgbe/ixgbe_type.h | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 916a2b64e5f..2496a27b599 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -54,11 +54,10 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = "Intel(R) 10 Gigabit PCI Express Network Driver"; #define MAJ 3 -#define MIN 3 +#define MIN 4 #define BUILD 8 -#define KFIX 2 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ - __stringify(BUILD) "-k" __stringify(KFIX) + __stringify(BUILD) "-k" const char ixgbe_driver_version[] = DRV_VERSION; static const char ixgbe_copyright[] = "Copyright (c) 1999-2011 Intel Corporation."; @@ -7713,7 +7712,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* Inform firmware of driver version */ if (hw->mac.ops.set_fw_drv_ver) - hw->mac.ops.set_fw_drv_ver(hw, MAJ, MIN, BUILD, KFIX); + hw->mac.ops.set_fw_drv_ver(hw, MAJ, MIN, BUILD, + FW_CEM_UNUSED_VER); /* add san mac addr to netdev */ ixgbe_add_sanmac_netdev(netdev); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 8b1abd47056..1eefc0c6840 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2143,7 +2143,8 @@ enum ixgbe_fdir_pballoc_type { #define FW_CEM_HDR_LEN 0x4 #define FW_CEM_CMD_DRIVER_INFO 0xDD #define FW_CEM_CMD_DRIVER_INFO_LEN 0x5 -#define FW_CEM_CMD_RESERVED 0X0 +#define FW_CEM_CMD_RESERVED 0x0 +#define FW_CEM_UNUSED_VER 0x0 #define FW_CEM_MAX_RETRIES 3 #define FW_CEM_RESP_STATUS_SUCCESS 0x1 -- cgit v1.2.3-70-g09d2 From 602ca6f00a0d95a0d0cec84f492324ee71d14e09 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Wed, 22 Jun 2011 02:52:17 +0000 Subject: qlcnic: Add capability to take FW dump deterministically In presence of multiple functions, current driver implementation does not guarantee that the FW dump is taken by the same function that forces it. Change it by adding a fw reset owner flag that could be changed in the device reset path and only when a function determines that it needs to reset it. Signed-off-by: Sritej Velaga Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_ctx.c | 4 ++-- drivers/net/qlcnic/qlcnic_main.c | 32 ++++++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 480ef5cb6ef..194376e584e 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -895,6 +895,7 @@ struct qlcnic_ipaddr { #define QLCNIC_MAC_OVERRIDE_DISABLED 0x400 #define QLCNIC_PROMISC_DISABLED 0x800 #define QLCNIC_NEED_FLR 0x1000 +#define QLCNIC_FW_RESET_OWNER 0x2000 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index c77024f9007..be2dee155bd 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -95,8 +95,8 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) QLCNIC_CDRP_CMD_TEMP_SIZE); if (err != QLCNIC_RCODE_SUCCESS) { err = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); - dev_err(&adapter->pdev->dev, - "Failed to get template size %d\n", err); + dev_info(&adapter->pdev->dev, + "Can't get template size %d\n", err); err = -EIO; return err; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 347a4a8d126..0ddbb80eefc 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1590,10 +1590,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* This will be reset for mezz cards */ adapter->portnum = adapter->ahw->pci_func; - /* Get FW dump template and store it */ - if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC) - qlcnic_fw_cmd_get_minidump_temp(adapter); - err = qlcnic_get_board_info(adapter); if (err) { dev_err(&pdev->dev, "Error getting board config info.\n"); @@ -1612,6 +1608,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_decr_ref; } + /* Get FW dump template and store it */ + if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC) + if (!qlcnic_fw_cmd_get_minidump_temp(adapter)) + dev_info(&pdev->dev, + "Supports FW dump capability\n"); + if (qlcnic_read_mac_addr(adapter)) dev_warn(&pdev->dev, "failed to read mac addr\n"); @@ -2683,11 +2685,16 @@ err: static int qlcnic_check_drv_state(struct qlcnic_adapter *adapter) { - int act, state; + int act, state, active_mask; state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); + if (adapter->flags & QLCNIC_FW_RESET_OWNER) { + active_mask = (~(1 << (adapter->ahw->pci_func * 4))); + act = act & active_mask; + } + if (((state & 0x11111111) == (act & 0x11111111)) || ((act & 0x11111111) == ((state >> 1) & 0x11111111))) return 0; @@ -2826,6 +2833,11 @@ qlcnic_fwinit_work(struct work_struct *work) if (!qlcnic_check_drv_state(adapter)) { skip_ack_check: + if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) { + qlcnic_api_unlock(adapter); + goto wait_npar; + } + dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); if (dev_state == QLCNIC_DEV_NEED_RESET) { @@ -2836,6 +2848,7 @@ skip_ack_check: qlcnic_idc_debug_info(adapter, 0); QLCDB(adapter, DRV, "Take FW dump\n"); qlcnic_dump_fw(adapter); + adapter->flags &= ~QLCNIC_FW_RESET_OWNER; } qlcnic_api_unlock(adapter); @@ -2900,9 +2913,11 @@ qlcnic_detach_work(struct work_struct *work) if (adapter->temp == QLCNIC_TEMP_PANIC) goto err_ret; - - if (qlcnic_set_drv_state(adapter, adapter->dev_state)) - goto err_ret; + /* Dont ack if this instance is the reset owner */ + if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) { + if (qlcnic_set_drv_state(adapter, adapter->dev_state)) + goto err_ret; + } adapter->fw_wait_cnt = 0; @@ -2947,6 +2962,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) if (state == QLCNIC_DEV_READY) { QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); + adapter->flags |= QLCNIC_FW_RESET_OWNER; QLCDB(adapter, DRV, "NEED_RESET state set\n"); qlcnic_idc_debug_info(adapter, 0); } -- cgit v1.2.3-70-g09d2 From 287e38aa1adee01f63bb28e270afd3f738a6ab8c Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Wed, 22 Jun 2011 02:52:18 +0000 Subject: qlcnic: Remove holding api lock while taking the dump With the change in logic for taking FW dump across multiple drivers, there is no need to hold onto the api lock anymore in the fw dump path. Instead use rtnl_lock() to synchronize the access to FW dump data structs. Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 6 ------ drivers/net/qlcnic/qlcnic_main.c | 8 +++++--- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 8ea800192d5..e183ed2271b 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -986,8 +986,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; - if (qlcnic_api_lock(adapter)) - return -EIO; if (!fw_dump->clr) { netdev_info(netdev, "Dump not available\n"); qlcnic_api_unlock(adapter); @@ -1009,7 +1007,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, vfree(fw_dump->data); fw_dump->data = NULL; fw_dump->clr = 0; - qlcnic_api_unlock(adapter); return 0; } @@ -1032,10 +1029,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) ret = -EINVAL; goto out; } - if (qlcnic_api_lock(adapter)) - return -EIO; fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff; - qlcnic_api_unlock(adapter); netdev_info(netdev, "Driver mask changed to: 0x%x\n", fw_dump->tmpl_hdr->drv_cap_mask); } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 0ddbb80eefc..a656a12e24d 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2846,13 +2846,15 @@ skip_ack_check: set_bit(__QLCNIC_START_FW, &adapter->state); QLCDB(adapter, DRV, "Restarting fw\n"); qlcnic_idc_debug_info(adapter, 0); - QLCDB(adapter, DRV, "Take FW dump\n"); - qlcnic_dump_fw(adapter); - adapter->flags &= ~QLCNIC_FW_RESET_OWNER; } qlcnic_api_unlock(adapter); + rtnl_lock(); + QLCDB(adapter, DRV, "Take FW dump\n"); + qlcnic_dump_fw(adapter); + adapter->flags &= ~QLCNIC_FW_RESET_OWNER; + rtnl_unlock(); if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); adapter->fw_wait_cnt = 0; -- cgit v1.2.3-70-g09d2 From c40f4ef77e5123a1d4064d7a34f708483b32b8be Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Wed, 22 Jun 2011 02:52:19 +0000 Subject: qlcnic: Add code to tune FW dump To accommodate change in FW dump template, it is required to modify the FW dump routine that captures cache data. Also, the default mask is changed to capture a dump that would cover all the protocols that this FW supports. Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 5 ++--- drivers/net/qlcnic/qlcnic_hw.c | 14 +++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 194376e584e..e5bb33253f9 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1220,8 +1220,7 @@ struct __ctrl { struct __cache { __le32 addr; - u8 stride; - u8 rsvd; + __le16 stride; __le16 init_tag_val; __le32 size; __le32 no_ops; @@ -1319,7 +1318,7 @@ enum op_codes { #define QLCNIC_DUMP_SKIP BIT_7 #define QLCNIC_DUMP_MASK_MIN 3 -#define QLCNIC_DUMP_MASK_DEF 0x0f +#define QLCNIC_DUMP_MASK_DEF 0x7f #define QLCNIC_DUMP_MASK_MAX 0xff #define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 1947f817bf2..81de563ee96 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -1509,18 +1509,26 @@ qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter, for (i = 0; i < l2->no_ops; i++) { QLCNIC_WR_DUMP_REG(l2->addr, base, val); - do { + if (LSW(l2->ctrl_val)) QLCNIC_WR_DUMP_REG(l2->ctrl_addr, base, LSW(l2->ctrl_val)); + if (!poll_mask) + goto skip_poll; + do { QLCNIC_RD_DUMP_REG(l2->ctrl_addr, base, &data); if (!(data & poll_mask)) break; msleep(1); time_out++; } while (time_out <= poll_to); - if (time_out > poll_to) - return -EINVAL; + if (time_out > poll_to) { + dev_err(&adapter->pdev->dev, + "Timeout exceeded in %s, aborting dump\n", + __func__); + return -EINVAL; + } +skip_poll: addr = l2->read_addr; cnt = l2->read_addr_num; while (cnt) { -- cgit v1.2.3-70-g09d2 From 5f6ec29abe434676f940357bcd66536bbc69e9f8 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Wed, 22 Jun 2011 02:52:20 +0000 Subject: qlcnic: fix initial number of msix entries in adapter. Calculation of number of MSI-X vectors was wrong on uniprocessor systems. Signed-off-by: Sucheta Chakraborty Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 - drivers/net/qlcnic/qlcnic_main.c | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index e5bb33253f9..58d7616eaee 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -900,7 +900,6 @@ struct qlcnic_ipaddr { ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) #define QLCNIC_DEF_NUM_STS_DESC_RINGS 4 -#define QLCNIC_MIN_NUM_RSS_RINGS 2 #define QLCNIC_MSIX_TBL_SPACE 8192 #define QLCNIC_PCI_REG_MSIX_TBL 0x44 #define QLCNIC_MSIX_TBL_PGSIZE 4096 diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index a656a12e24d..a050746a512 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -418,10 +418,8 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter) int num_msix; if (adapter->msix_supported) { - num_msix = (num_online_cpus() >= - QLCNIC_DEF_NUM_STS_DESC_RINGS) ? - QLCNIC_DEF_NUM_STS_DESC_RINGS : - QLCNIC_MIN_NUM_RSS_RINGS; + num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(), + QLCNIC_DEF_NUM_STS_DESC_RINGS)); } else num_msix = 1; -- cgit v1.2.3-70-g09d2 From c55ad8e56b983f03589b38b4504b5d1f41161ff8 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Wed, 22 Jun 2011 02:52:21 +0000 Subject: qlcnic: fix default operating state of interface Currently interface shows status as RUNNING, even if there is no link. To fix this, netif_carrier_off should be called qlcnic_open(). Signed-off-by: Amit Kumar Salecha Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index a050746a512..5dcb853224c 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1485,8 +1485,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, netdev->irq = adapter->msix_entries[0].vector; - netif_carrier_off(netdev); - err = register_netdev(netdev); if (err) { dev_err(&pdev->dev, "failed to register net device\n"); @@ -1816,6 +1814,8 @@ static int qlcnic_open(struct net_device *netdev) struct qlcnic_adapter *adapter = netdev_priv(netdev); int err; + netif_carrier_off(netdev); + err = qlcnic_attach(adapter); if (err) return err; -- cgit v1.2.3-70-g09d2 From 9d6a6440fe30132e4d1f1aadd099345ced9178fb Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Wed, 22 Jun 2011 02:52:22 +0000 Subject: qlcnic: Add support to enable/disable FW dump capability In certain situations, it may be required to not enable FW dump capability. Add support to turn off/on FW dump capability. Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 3 +++ drivers/net/qlcnic/qlcnic_ctx.c | 1 + drivers/net/qlcnic/qlcnic_ethtool.c | 19 +++++++++++++++++++ drivers/net/qlcnic/qlcnic_main.c | 8 +++++--- 4 files changed, 28 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 58d7616eaee..0be84bdb55b 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -429,6 +429,7 @@ struct qlcnic_dump_template_hdr { struct qlcnic_fw_dump { u8 clr; /* flag to indicate if dump is cleared */ + u8 enable; /* enable/disable dump */ u32 size; /* total size of the dump */ void *data; /* dump data area */ struct qlcnic_dump_template_hdr *tmpl_hdr; @@ -1320,6 +1321,8 @@ enum op_codes { #define QLCNIC_DUMP_MASK_DEF 0x7f #define QLCNIC_DUMP_MASK_MAX 0xff #define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed +#define QLCNIC_ENABLE_FW_DUMP 0xaddfeed +#define QLCNIC_DISABLE_FW_DUMP 0xbadfeed struct qlcnic_dump_operations { enum op_codes opcode; diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index be2dee155bd..33f5c8a8b55 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -150,6 +150,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) tmpl_hdr->drv_cap_mask = tmpl_hdr->cap_mask; else tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF; + ahw->fw_dump.enable = 1; error: dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t); return err; diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index e183ed2271b..31f5cba6222 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -1019,8 +1019,27 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) { + if (!fw_dump->enable) { + netdev_info(netdev, "FW dump not enabled\n"); + return ret; + } + if (fw_dump->clr) { + dev_info(&adapter->pdev->dev, + "Previous dump not cleared, not forcing dump\n"); + return ret; + } netdev_info(netdev, "Forcing a FW dump\n"); qlcnic_dev_request_reset(adapter); + } else if (val->flag == QLCNIC_DISABLE_FW_DUMP) { + if (fw_dump->enable) { + netdev_info(netdev, "Disabling FW dump\n"); + fw_dump->enable = 0; + } + } else if (val->flag == QLCNIC_ENABLE_FW_DUMP) { + if (!fw_dump->enable && fw_dump->tmpl_hdr) { + netdev_info(netdev, "Enabling FW dump\n"); + fw_dump->enable = 1; + } } else { if (val->flag > QLCNIC_DUMP_MASK_MAX || val->flag < QLCNIC_DUMP_MASK_MIN) { diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 5dcb853224c..ac7f8a2f7d9 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2849,9 +2849,11 @@ skip_ack_check: qlcnic_api_unlock(adapter); rtnl_lock(); - QLCDB(adapter, DRV, "Take FW dump\n"); - qlcnic_dump_fw(adapter); - adapter->flags &= ~QLCNIC_FW_RESET_OWNER; + if (adapter->ahw->fw_dump.enable) { + QLCDB(adapter, DRV, "Take FW dump\n"); + qlcnic_dump_fw(adapter); + adapter->flags &= ~QLCNIC_FW_RESET_OWNER; + } rtnl_unlock(); if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); -- cgit v1.2.3-70-g09d2 From 22c8c9343258feda9ea9ebb9e5f8cbb727b69454 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Wed, 22 Jun 2011 02:52:23 +0000 Subject: qlcnic: multi protocol internal loopback support added. Driver will generate loopback traffic pattern and do the test. And returns result of the test to application. Updated driver version to 5.0.19. Signed-off-by: Sucheta Chakraborty Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 22 ++++++- drivers/net/qlcnic/qlcnic_ethtool.c | 123 ++++++++++++++++++++++++++++++++++- drivers/net/qlcnic/qlcnic_hw.c | 50 ++++++++++++++ drivers/net/qlcnic/qlcnic_init.c | 126 +++++++++++++++++++++++++++++++++++- drivers/net/qlcnic/qlcnic_main.c | 6 ++ 5 files changed, 322 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 0be84bdb55b..e5454502df6 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -36,8 +36,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 18 -#define QLCNIC_LINUX_VERSIONID "5.0.18" +#define _QLCNIC_LINUX_SUBVERSION 19 +#define QLCNIC_LINUX_VERSIONID "5.0.19" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -451,6 +451,7 @@ struct qlcnic_hardware_context { u8 revision_id; u8 pci_func; u8 linkup; + u8 loopback_state; u16 port_type; u16 board_type; @@ -780,6 +781,13 @@ struct qlcnic_mac_list_s { #define QLCNIC_IP_UP 2 #define QLCNIC_IP_DOWN 3 +#define QLCNIC_ILB_MODE 0x1 + +#define QLCNIC_LINKEVENT 0x1 +#define QLCNIC_LB_RESPONSE 0x2 +#define QLCNIC_IS_LB_CONFIGURED(VAL) \ + (VAL == (QLCNIC_LINKEVENT | QLCNIC_LB_RESPONSE)) + /* * Driver --> Firmware */ @@ -789,13 +797,17 @@ struct qlcnic_mac_list_s { #define QLCNIC_H2C_OPCODE_LRO_REQUEST 0x7 #define QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE 0xc #define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 0x12 + #define QLCNIC_H2C_OPCODE_GET_LINKEVENT 0x15 #define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING 0x17 #define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO 0x18 +#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK 0x13 + /* * Firmware --> Driver */ +#define QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK 0x8f #define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141 #define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */ @@ -1430,6 +1442,12 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, struct qlcnic_host_tx_ring *tx_ring); void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *); +void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); +void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter); +int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode); + +/* Functions from qlcnic_ethtool.c */ +int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]); /* Functions from qlcnic_main.c */ int qlcnic_reset_context(struct qlcnic_adapter *); diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 31f5cba6222..743035e4538 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -84,7 +84,8 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = { static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { "Register_Test_on_offline", "Link_Test_on_offline", - "Interrupt_Test_offline" + "Interrupt_Test_offline", + "Loopback_Test_offline" }; #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test) @@ -685,6 +686,123 @@ clear_it: return ret; } +#define QLCNIC_ILB_PKT_SIZE 64 +#define QLCNIC_NUM_ILB_PKT 16 +#define QLCNIC_ILB_MAX_RCV_LOOP 10 + +static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[]) +{ + unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00}; + + memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE); + + memcpy(data, mac, ETH_ALEN); + memcpy(data + ETH_ALEN, mac, ETH_ALEN); + + memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data)); +} + +int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]) +{ + unsigned char buff[QLCNIC_ILB_PKT_SIZE]; + qlcnic_create_loopback_buff(buff, mac); + return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE); +} + +static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) +{ + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; + struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; + struct sk_buff *skb; + int i, loop, cnt = 0; + + for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) { + skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE); + qlcnic_create_loopback_buff(skb->data, adapter->mac_addr); + skb_put(skb, QLCNIC_ILB_PKT_SIZE); + + adapter->diag_cnt = 0; + qlcnic_xmit_frame(skb, adapter->netdev); + + loop = 0; + do { + msleep(1); + qlcnic_process_rcv_ring_diag(sds_ring); + if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) + break; + } while (!adapter->diag_cnt); + + dev_kfree_skb_any(skb); + + if (!adapter->diag_cnt) + dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet" + " not recevied\n", i + 1); + else + cnt++; + } + if (cnt != i) { + dev_warn(&adapter->pdev->dev, "ILB Test failed\n"); + return -1; + } + return 0; +} + +static int qlcnic_iloopback_test(struct net_device *netdev) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + int max_sds_rings = adapter->max_sds_rings; + struct qlcnic_host_sds_ring *sds_ring; + int loop = 0; + int ret; + + netdev_info(netdev, "%s: in progress\n", __func__); + if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { + netdev_warn(netdev, "Loopback test not supported for non " + "privilege function\n"); + return 0; + } + + if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) + return -EIO; + + + ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); + if (ret) + goto clear_it; + + sds_ring = &adapter->recv_ctx->sds_rings[0]; + + ret = qlcnic_set_lb_mode(adapter, QLCNIC_ILB_MODE); + if (ret) + goto free_res; + + do { + msleep(500); + qlcnic_process_rcv_ring_diag(sds_ring); + if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) + break; + } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)); + + if (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)) { + netdev_info(netdev, "firmware didnt respond to loopback " + "configure request\n"); + ret = adapter->ahw->loopback_state; + goto free_res; + } + + ret = qlcnic_do_ilb_test(adapter); + + qlcnic_clear_lb_mode(adapter); + + free_res: + qlcnic_diag_free_res(netdev, max_sds_rings); + + clear_it: + adapter->max_sds_rings = max_sds_rings; + clear_bit(__QLCNIC_RESETTING, &adapter->state); + return ret; +} + static void qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, u64 *data) @@ -704,6 +822,9 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, if (data[2]) eth_test->flags |= ETH_TEST_FL_FAILED; + data[3] = qlcnic_iloopback_test(dev); + if (data[3]) + eth_test->flags |= ETH_TEST_FL_FAILED; } } diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 81de563ee96..0391a04695d 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -533,6 +533,56 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) } } +int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u8 flag) +{ + struct qlcnic_nic_req req; + int rv; + + memset(&req, 0, sizeof(struct qlcnic_nic_req)); + + req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); + req.req_hdr = cpu_to_le64(QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK | + ((u64) adapter->portnum << 16) | ((u64) 0x1 << 32)); + + req.words[0] = cpu_to_le64(flag); + + rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); + if (rv != 0) + dev_err(&adapter->pdev->dev, "%sting loopback mode failed\n", + flag ? "Set" : "Reset"); + return rv; +} + +int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) +{ + if (qlcnic_set_fw_loopback(adapter, mode)) + return -EIO; + + if (qlcnic_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL)) { + qlcnic_set_fw_loopback(adapter, mode); + return -EIO; + } + + msleep(1000); + return 0; +} + +void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter) +{ + int mode = VPORT_MISS_MODE_DROP; + struct net_device *netdev = adapter->netdev; + + qlcnic_set_fw_loopback(adapter, 0); + + if (netdev->flags & IFF_PROMISC) + mode = VPORT_MISS_MODE_ACCEPT_ALL; + else if (netdev->flags & IFF_ALLMULTI) + mode = VPORT_MISS_MODE_ACCEPT_MULTI; + + qlcnic_nic_set_promisc(adapter, mode); + msleep(1000); +} + /* * Send the interrupt coalescing parameter set by ethtool to the card. */ diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 5b8bbcf904d..9d5bee03a58 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1281,6 +1281,7 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, u16 cable_len; u16 link_speed; u8 link_status, module, duplex, autoneg; + u8 lb_status = 0; struct net_device *netdev = adapter->netdev; adapter->has_link_events = 1; @@ -1292,6 +1293,7 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, link_status = msg->body[2] & 0xff; duplex = (msg->body[2] >> 16) & 0xff; autoneg = (msg->body[2] >> 24) & 0xff; + lb_status = (msg->body[2] >> 32) & 0x3; module = (msg->body[2] >> 8) & 0xff; if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE) @@ -1301,6 +1303,9 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, dev_info(&netdev->dev, "unsupported cable length %d\n", cable_len); + if (!link_status && (lb_status == 1)) + adapter->ahw->loopback_state |= QLCNIC_LINKEVENT; + qlcnic_advert_link_change(adapter, link_status); if (duplex == LINKEVENT_FULL_DUPLEX) @@ -1319,7 +1324,9 @@ qlcnic_handle_fw_message(int desc_cnt, int index, { struct qlcnic_fw_msg msg; struct status_desc *desc; - int i = 0, opcode; + struct qlcnic_adapter *adapter; + struct device *dev; + int i = 0, opcode, ret; while (desc_cnt > 0 && i < 8) { desc = &sds_ring->desc_head[index]; @@ -1330,10 +1337,28 @@ qlcnic_handle_fw_message(int desc_cnt, int index, desc_cnt--; } + adapter = sds_ring->adapter; + dev = &adapter->pdev->dev; opcode = qlcnic_get_nic_msg_opcode(msg.body[0]); + switch (opcode) { case QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE: - qlcnic_handle_linkevent(sds_ring->adapter, &msg); + qlcnic_handle_linkevent(adapter, &msg); + break; + case QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK: + ret = (u32)(msg.body[1]); + switch (ret) { + case 0: + adapter->ahw->loopback_state |= QLCNIC_LB_RESPONSE; + break; + case 1: + dev_info(dev, "loopback already in progress\n"); + break; + default: + dev_info(dev, "loopback configure request failed," + " ret %x\n", ret); + break; + } break; default: break; @@ -1746,6 +1771,103 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, spin_unlock(&rds_ring->lock); } +static void dump_skb(struct sk_buff *skb) +{ + int i; + unsigned char *data = skb->data; + + printk(KERN_INFO "\n"); + for (i = 0; i < skb->len; i++) { + printk(KERN_INFO "%02x ", data[i]); + if ((i & 0x0f) == 8) + printk(KERN_INFO "\n"); + } +} + +void qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, + struct qlcnic_host_sds_ring *sds_ring, + int ring, u64 sts_data0) +{ + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; + struct sk_buff *skb; + struct qlcnic_host_rds_ring *rds_ring; + int index, length, cksum, pkt_offset; + + if (unlikely(ring >= adapter->max_rds_rings)) + return; + + rds_ring = &recv_ctx->rds_rings[ring]; + + index = qlcnic_get_sts_refhandle(sts_data0); + length = qlcnic_get_sts_totallength(sts_data0); + if (unlikely(index >= rds_ring->num_desc)) + return; + + cksum = qlcnic_get_sts_status(sts_data0); + pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0); + + skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum); + if (!skb) + return; + + if (length > rds_ring->skb_size) + skb_put(skb, rds_ring->skb_size); + else + skb_put(skb, length); + + if (pkt_offset) + skb_pull(skb, pkt_offset); + + if (!qlcnic_check_loopback_buff(skb->data, adapter->mac_addr)) + adapter->diag_cnt++; + else + dump_skb(skb); + + dev_kfree_skb_any(skb); + adapter->stats.rx_pkts++; + adapter->stats.rxbytes += length; + + return; +} + +void +qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) +{ + struct qlcnic_adapter *adapter = sds_ring->adapter; + struct status_desc *desc; + u64 sts_data0; + int ring, opcode, desc_cnt; + + u32 consumer = sds_ring->consumer; + + desc = &sds_ring->desc_head[consumer]; + sts_data0 = le64_to_cpu(desc->status_desc_data[0]); + + if (!(sts_data0 & STATUS_OWNER_HOST)) + return; + + desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0); + opcode = qlcnic_get_sts_opcode(sts_data0); + switch (opcode) { + case QLCNIC_RESPONSE_DESC: + qlcnic_handle_fw_message(desc_cnt, consumer, sds_ring); + break; + default: + ring = qlcnic_get_sts_type(sts_data0); + qlcnic_process_rcv_diag(adapter, sds_ring, ring, sts_data0); + break; + } + + for (; desc_cnt > 0; desc_cnt--) { + desc = &sds_ring->desc_head[consumer]; + desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM); + consumer = get_next_index(consumer, sds_ring->num_desc); + } + + sds_ring->consumer = consumer; + writel(consumer, sds_ring->crb_sts_consumer); +} + void qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2, u8 alt_mac, u8 *mac) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index ac7f8a2f7d9..357436be801 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1391,6 +1391,12 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) qlcnic_enable_int(sds_ring); } } + + if (adapter->diag_test == QLCNIC_LOOPBACK_TEST) { + adapter->ahw->loopback_state = 0; + qlcnic_linkevent_request(adapter, 1); + } + set_bit(__QLCNIC_DEV_UP, &adapter->state); return 0; -- cgit v1.2.3-70-g09d2 From 95cb3656c09fcf6577138337216c27744ebc91e2 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 24 Jun 2011 02:40:08 -0700 Subject: net: Remove unneeded version.h includes from drivers/net/ It was pointed out by 'make versioncheck' that some includes of linux/version.h are not needed in drivers/net/. This patch removes them. Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c.h | 1 - drivers/net/atl1e/atl1e.h | 1 - drivers/net/benet/be.h | 1 - drivers/net/bna/cna.h | 1 - drivers/net/caif/caif_serial.c | 1 - drivers/net/caif/caif_shm_u5500.c | 1 - drivers/net/caif/caif_spi.c | 1 - drivers/net/caif/caif_spi_slave.c | 1 - drivers/net/can/c_can/c_can.c | 1 - drivers/net/can/c_can/c_can_platform.c | 1 - drivers/net/can/softing/softing_main.c | 1 - drivers/net/cxgb4vf/cxgb4vf_main.c | 1 - drivers/net/cxgb4vf/t4vf_hw.c | 1 - drivers/net/davinci_emac.c | 1 - drivers/net/pptp.c | 1 - drivers/net/sfc/net_driver.h | 1 - drivers/net/usb/cdc_ncm.c | 1 - drivers/net/wireless/rtlwifi/wifi.h | 1 - 18 files changed, 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index dfe4370ccc9..0f481b983bc 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h @@ -22,7 +22,6 @@ #ifndef _ATL1C_H_ #define _ATL1C_H_ -#include #include #include #include diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index 9ac37e3ec8f..8c8181b5328 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h @@ -23,7 +23,6 @@ #ifndef _ATL1E_H_ #define _ATL1E_H_ -#include #include #include #include diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index a36f5a6a846..9aa1534c7d8 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/bna/cna.h b/drivers/net/bna/cna.h index 3c47dc52b42..01b4af73302 100644 --- a/drivers/net/bna/cna.h +++ b/drivers/net/bna/cna.h @@ -19,7 +19,6 @@ #ifndef __CNA_H__ #define __CNA_H__ -#include #include #include #include diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 1cd0b59d13c..23406e62c0b 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c index 5f771ab712c..89d76b7b325 100644 --- a/drivers/net/caif/caif_shm_u5500.c +++ b/drivers/net/caif/caif_shm_u5500.c @@ -7,7 +7,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt -#include #include #include #include diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 57e63937381..0f8defc7330 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -5,7 +5,6 @@ * License terms: GNU General Public License (GPL) version 2. */ -#include #include #include #include diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c index b009e03cda9..e139e133fc7 100644 --- a/drivers/net/caif/caif_spi_slave.c +++ b/drivers/net/caif/caif_spi_slave.c @@ -4,7 +4,6 @@ * Author: Daniel Martensson / Daniel.Martensson@stericsson.com * License terms: GNU General Public License (GPL) version 2. */ -#include #include #include #include diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 7e5cc0bd913..80adc83f796 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -26,7 +26,6 @@ */ #include -#include #include #include #include diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index cc90824f2c9..0e300cf840b 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -20,7 +20,6 @@ */ #include -#include #include #include #include diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 954b2959b6b..a79925e72d6 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index e71c08e547e..8a6f8911bc5 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -33,7 +33,6 @@ * SOFTWARE. */ -#include #include #include #include diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index 192db226ec7..fe3fd3dad6f 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c @@ -33,7 +33,6 @@ * SOFTWARE. */ -#include #include #include "t4vf_common.h" diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 55c8245b0cd..acef7e96c9f 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 1286fe212dc..eae542a7e98 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e8d5f03a89f..1affbf4d708 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -17,7 +17,6 @@ #define DEBUG #endif -#include #include #include #include diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index f33ca6aa29e..fd622a66ebb 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 9d003e0864f..75dff1e095f 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -32,7 +32,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 1e5cf9b0be4e8902c06bf9600ea0b256e731c862 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 21 Jun 2011 04:30:56 -0700 Subject: iwlagn: use PM ops macro Simplify the code and use SIMPLE_DEV_PM_OPS to define iwl_dev_pm_ops instead of doing the same thing manually. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-pci.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 7328fbff7f7..3927c802a5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -530,14 +530,7 @@ static int iwl_pci_resume(struct device *device) return iwl_resume(priv); } -static const struct dev_pm_ops iwl_dev_pm_ops = { - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, - .freeze = iwl_pci_suspend, - .thaw = iwl_pci_resume, - .poweroff = iwl_pci_suspend, - .restore = iwl_pci_resume, -}; +static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); #define IWL_PM_OPS (&iwl_dev_pm_ops) -- cgit v1.2.3-70-g09d2 From f8d651a56ef5c9e26a1cddd4f169f5bf4f8dfa9b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Jun 2011 04:25:57 -0700 Subject: iwlagn: fix cmd queue unmap When we stop the device while a command is in flight that uses multiple TBs, we can leak the DMA buffers for the second and higher TBs. Fix this by using iwlagn_unmap_tfd() as we do when we normally recover the entry. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-tx.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index fd8aee9972c..cf8fc9afa1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -309,10 +309,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) i = get_cmd_index(q, q->read_ptr); if (txq->meta[i].flags & CMD_MAPPED) { - dma_unmap_single(priv->bus.dev, - dma_unmap_addr(&txq->meta[i], mapping), - dma_unmap_len(&txq->meta[i], len), - DMA_BIDIRECTIONAL); + iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i]); txq->meta[i].flags = 0; } -- cgit v1.2.3-70-g09d2 From 81704d2db99386d718e277cd5ac92663abec8a66 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Jun 2011 06:39:43 -0700 Subject: iwlagn: extend host command timeout We've infrequently seen timeouts, make the wait time match the windows driver; hopefully our driver is just too impatient. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 7cdb1ec73b5..e3e5fb61417 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -113,7 +113,7 @@ const char *get_cmd_string(u8 cmd) } } -#define HOST_COMPLETE_TIMEOUT (HZ / 2) +#define HOST_COMPLETE_TIMEOUT (2 * HZ) static void iwl_generic_cmd_callback(struct iwl_priv *priv, struct iwl_device_cmd *cmd, -- cgit v1.2.3-70-g09d2 From 0b5b3ff15b301338ccec77ebc051308ac614d05d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Jun 2011 06:33:43 -0700 Subject: iwlagn: fill beacon TX rate properly Use the rate that mac80211 requested to fill the uCode TX command for the beacon. Unfortunately, the uCode is (currently?) ignoring it, but now at least fill it properly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 26 ++++++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-core.c | 13 ------------- drivers/net/wireless/iwlwifi/iwl-core.h | 7 ------- 3 files changed, 22 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 77ceb8deff7..e2f6b2ab0d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -132,6 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) struct iwl_host_cmd cmd = { .id = REPLY_TX_BEACON, }; + struct ieee80211_tx_info *info; u32 frame_size; u32 rate_flags; u32 rate; @@ -172,14 +173,31 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) frame_size); /* Set up packet rate and flags */ - rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx); + info = IEEE80211_SKB_CB(priv->beacon_skb); + + /* + * Let's set up the rate at least somewhat correctly; + * it will currently not actually be used by the uCode, + * it uses the broadcast station's rate instead. + */ + if (info->control.rates[0].idx < 0 || + info->control.rates[0].flags & IEEE80211_TX_RC_MCS) + rate = 0; + else + rate = info->control.rates[0].idx; + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, priv->hw_params.valid_tx_ant); rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); - if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE)) + + /* In mac80211, rates for 5 GHz start at 0 */ + if (info->band == IEEE80211_BAND_5GHZ) + rate += IWL_FIRST_OFDM_RATE; + else if (rate >= IWL_FIRST_CCK_RATE && rate <= IWL_LAST_CCK_RATE) rate_flags |= RATE_MCS_CCK_MSK; - tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate, - rate_flags); + + tx_beacon_cmd->tx.rate_n_flags = + iwl_hw_set_rate_n_flags(rate, rate_flags); /* Submit command */ cmd.len[0] = sizeof(*tx_beacon_cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index cde725326c3..f0eabbc07c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -526,19 +526,6 @@ int iwl_full_rxon_required(struct iwl_priv *priv, return 0; } -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - /* - * Assign the lowest rate -- should really get this from - * the beacon skb from mac80211. - */ - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) - return IWL_RATE_1M_PLCP; - else - return IWL_RATE_6M_PLCP; -} - static void _iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf, struct iwl_rxon_context *ctx) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index adf9f9b2efb..f881678be76 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -408,13 +408,6 @@ void iwl_setup_watchdog(struct iwl_priv *priv); ****************************************************/ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); -/******************************************************************************* - * Rate - ******************************************************************************/ - -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, - struct iwl_rxon_context *ctx); - /******************************************************************************* * Scanning ******************************************************************************/ -- cgit v1.2.3-70-g09d2 From f775aa06d2de583bd291d4bf5814784c9ff7b9cc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Jun 2011 06:34:09 -0700 Subject: iwlagn: don't use CCK rates for P2P interfaces P2P interfaces must not use CCK rates, only OFDM rates are allowed. To set this up, we need to set up the broadcast station to start with 6M instead of starting with 1M. Since the interface type can change, also reset the broadcast station when RXON changes. This will affect beacons as well. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 17 +++++++++++------ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a7c66c4e5f2..8fa43d42781 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -210,6 +210,8 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv, * keys, so we have to restore those afterwards. */ iwl_clear_ucode_stations(priv, ctx); + /* update -- might need P2P now */ + iwl_update_bcast_station(priv, ctx); iwl_restore_stations(priv, ctx); ret = iwl_restore_default_wep_keys(priv, ctx); if (ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 0bd722cee5a..9b32f83f0b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -35,7 +35,7 @@ #include "iwl-agn.h" static struct iwl_link_quality_cmd * -iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) +iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id) { int i, r; struct iwl_link_quality_cmd *link_cmd; @@ -47,10 +47,15 @@ iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); return NULL; } + + lockdep_assert_held(&priv->mutex); + /* Set up the rate scaling to start at selected rate, fall back * all the way down to 1M in IEEE order, and then spin on 1M */ if (priv->band == IEEE80211_BAND_5GHZ) r = IWL_RATE_6M_INDEX; + else if (ctx && ctx->vif && ctx->vif->p2p) + r = IWL_RATE_6M_INDEX; else r = IWL_RATE_1M_INDEX; @@ -115,7 +120,7 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx spin_unlock_irqrestore(&priv->sta_lock, flags); /* Set up default rate scaling table in device's station table */ - link_cmd = iwl_sta_alloc_lq(priv, sta_id); + link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n", addr); @@ -554,7 +559,7 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, priv->stations[sta_id].used |= IWL_STA_BCAST; spin_unlock_irqrestore(&priv->sta_lock, flags); - link_cmd = iwl_sta_alloc_lq(priv, sta_id); + link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); @@ -574,14 +579,14 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, * Only used by iwlagn. Placed here to have all bcast station management * code together. */ -static int iwl_update_bcast_station(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) +int iwl_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { unsigned long flags; struct iwl_link_quality_cmd *link_cmd; u8 sta_id = ctx->bcast_sta_id; - link_cmd = iwl_sta_alloc_lq(priv, sta_id); + link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); return -ENOMEM; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 6d5584ae5eb..dcdf2259520 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -304,6 +304,8 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid); void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); +int iwl_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int iwl_update_bcast_stations(struct iwl_priv *priv); void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- cgit v1.2.3-70-g09d2 From 4017dbdc14af1903dc9fcba4d08b89c02325069d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 24 Jun 2011 20:26:44 +0100 Subject: sfc: Fix loop condition for efx_filter_search() when !for_insert efx_filter_remove_filter() fails to remove inserted filters in some cases. For example: 1. Two filters A and B have specifications that result in an initial hash collision. 2. A is inserted first, followed by B. 3. An attempt to remove B first succeeds, but if A is removed first a subsequent attempt to remove B fails. When searching for an existing filter (!for_insert), efx_filter_search() must always continue to the maximum search depth for the given type rather than stopping at the first unused entry. Signed-off-by: Ben Hutchings --- drivers/net/sfc/filter.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index f2fc2587c09..054f0a3d45a 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -335,28 +335,35 @@ static int efx_filter_search(struct efx_filter_table *table, bool for_insert, int *depth_required) { unsigned hash, incr, filter_idx, depth, depth_max; - struct efx_filter_spec *cmp; hash = efx_filter_hash(key); incr = efx_filter_increment(key); - depth_max = (spec->priority <= EFX_FILTER_PRI_HINT ? - FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX); - - for (depth = 1, filter_idx = hash & (table->size - 1); - depth <= depth_max && test_bit(filter_idx, table->used_bitmap); - ++depth) { - cmp = &table->spec[filter_idx]; - if (efx_filter_equal(spec, cmp)) - goto found; + + filter_idx = hash & (table->size - 1); + depth = 1; + depth_max = (for_insert ? + (spec->priority <= EFX_FILTER_PRI_HINT ? + FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX) : + table->search_depth[spec->type]); + + for (;;) { + /* Return success if entry is used and matches this spec + * or entry is unused and we are trying to insert. + */ + if (test_bit(filter_idx, table->used_bitmap) ? + efx_filter_equal(spec, &table->spec[filter_idx]) : + for_insert) { + *depth_required = depth; + return filter_idx; + } + + /* Return failure if we reached the maximum search depth */ + if (depth == depth_max) + return for_insert ? -EBUSY : -ENOENT; + filter_idx = (filter_idx + incr) & (table->size - 1); + ++depth; } - if (!for_insert) - return -ENOENT; - if (depth > depth_max) - return -EBUSY; -found: - *depth_required = depth; - return filter_idx; } /* Construct/deconstruct external filter IDs */ -- cgit v1.2.3-70-g09d2 From a7d529ae2158b5300e4aa16c21f1828bc864449b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 24 Jun 2011 20:46:31 +0100 Subject: sfc: Allow resets to be upgraded; use atomic ops for safety Currently an attempt to schedule any reset is ignored if a reset is already pending. This ignores the relative scopes - if the requested reset is greater in scope then the scheduled reset should be upgraded accordingly. There are also some race conditions which could lead to a reset request being lost. Deal with them by using atomic operations on a bitmask. This also makes tests on reset_pending easier to get right. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 38 +++++++++++++++++--------------------- drivers/net/sfc/enum.h | 3 ++- drivers/net/sfc/falcon.c | 2 +- drivers/net/sfc/net_driver.h | 4 ++-- 4 files changed, 22 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index c914729f955..9b4cfdb0951 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -229,8 +229,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) struct efx_nic *efx = channel->efx; int spent; - if (unlikely(efx->reset_pending != RESET_TYPE_NONE || - !channel->enabled)) + if (unlikely(efx->reset_pending || !channel->enabled)) return 0; spent = efx_nic_process_eventq(channel, budget); @@ -1461,7 +1460,7 @@ static void efx_start_all(struct efx_nic *efx) * reset_pending [modified from an atomic context], we instead guarantee * that efx_mcdi_mode_poll() isn't reverted erroneously */ efx_mcdi_mode_event(efx); - if (efx->reset_pending != RESET_TYPE_NONE) + if (efx->reset_pending) efx_mcdi_mode_poll(efx); /* Start the hardware monitor if there is one. Otherwise (we're link @@ -2118,8 +2117,10 @@ int efx_reset(struct efx_nic *efx, enum reset_type method) goto out; } - /* Allow resets to be rescheduled. */ - efx->reset_pending = RESET_TYPE_NONE; + /* Clear flags for the scopes we covered. We assume the NIC and + * driver are now quiescent so that there is no race here. + */ + efx->reset_pending &= -(1 << (method + 1)); /* Reinitialise bus-mastering, which may have been turned off before * the reset was scheduled. This is still appropriate, even in the @@ -2154,12 +2155,13 @@ out: static void efx_reset_work(struct work_struct *data) { struct efx_nic *efx = container_of(data, struct efx_nic, reset_work); + unsigned long pending = ACCESS_ONCE(efx->reset_pending); - if (efx->reset_pending == RESET_TYPE_NONE) + if (!pending) return; /* If we're not RUNNING then don't reset. Leave the reset_pending - * flag set so that efx_pci_probe_main will be retried */ + * flags set so that efx_pci_probe_main will be retried */ if (efx->state != STATE_RUNNING) { netif_info(efx, drv, efx->net_dev, "scheduled reset quenched. NIC not RUNNING\n"); @@ -2167,7 +2169,7 @@ static void efx_reset_work(struct work_struct *data) } rtnl_lock(); - (void)efx_reset(efx, efx->reset_pending); + (void)efx_reset(efx, fls(pending) - 1); rtnl_unlock(); } @@ -2175,12 +2177,6 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) { enum reset_type method; - if (efx->reset_pending != RESET_TYPE_NONE) { - netif_info(efx, drv, efx->net_dev, - "quenching already scheduled reset\n"); - return; - } - switch (type) { case RESET_TYPE_INVISIBLE: case RESET_TYPE_ALL: @@ -2208,7 +2204,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n", RESET_TYPE(method)); - efx->reset_pending = method; + set_bit(method, &efx->reset_pending); /* efx_process_channel() will no longer read events once a * reset is scheduled. So switch back to poll'd MCDI completions. */ @@ -2288,7 +2284,6 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type, efx->pci_dev = pci_dev; efx->msg_enable = debug; efx->state = STATE_INIT; - efx->reset_pending = RESET_TYPE_NONE; strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); efx->net_dev = net_dev; @@ -2510,7 +2505,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, cancel_work_sync(&efx->reset_work); if (rc == 0) { - if (efx->reset_pending != RESET_TYPE_NONE) { + if (efx->reset_pending) { /* If there was a scheduled reset during * probe, the NIC is probably hosed anyway */ efx_pci_remove_main(efx); @@ -2521,11 +2516,12 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, } /* Retry if a recoverably reset event has been scheduled */ - if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && - (efx->reset_pending != RESET_TYPE_ALL)) + if (efx->reset_pending & + ~(1 << RESET_TYPE_INVISIBLE | 1 << RESET_TYPE_ALL) || + !efx->reset_pending) goto fail3; - efx->reset_pending = RESET_TYPE_NONE; + efx->reset_pending = 0; } if (rc) { @@ -2609,7 +2605,7 @@ static int efx_pm_poweroff(struct device *dev) efx->type->fini(efx); - efx->reset_pending = RESET_TYPE_NONE; + efx->reset_pending = 0; pci_save_state(pci_dev); return pci_set_power_state(pci_dev, PCI_D3hot); diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h index 384cfe3b1be..d725a8fbe1a 100644 --- a/drivers/net/sfc/enum.h +++ b/drivers/net/sfc/enum.h @@ -134,6 +134,8 @@ enum efx_loopback_mode { * other valuesspecify reasons, which efx_schedule_reset() will choose * a method for. * + * Reset methods are numbered in order of increasing scope. + * * @RESET_TYPE_INVISIBLE: don't reset the PHYs or interrupts * @RESET_TYPE_ALL: reset everything but PCI core blocks * @RESET_TYPE_WORLD: reset everything, save & restore PCI config @@ -147,7 +149,6 @@ enum efx_loopback_mode { * @RESET_TYPE_MC_FAILURE: MC reboot/assertion */ enum reset_type { - RESET_TYPE_NONE = -1, RESET_TYPE_INVISIBLE = 0, RESET_TYPE_ALL = 1, RESET_TYPE_WORLD = 2, diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 60176e873d6..a4c7830ec9b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -536,7 +536,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) efx_oword_t reg; int link_speed, isolate; - isolate = (efx->reset_pending != RESET_TYPE_NONE); + isolate = !!ACCESS_ONCE(efx->reset_pending); switch (link_state->speed) { case 10000: link_speed = 3; break; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e8d5f03a89f..c422eb2ce60 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -645,7 +645,7 @@ struct efx_filter_state; * @irq_rx_moderation: IRQ moderation time for RX event queues * @msg_enable: Log message enable flags * @state: Device state flag. Serialised by the rtnl_lock. - * @reset_pending: Pending reset method (normally RESET_TYPE_NONE) + * @reset_pending: Bitmask for pending resets * @tx_queue: TX DMA queues * @rx_queue: RX DMA queues * @channel: Channels @@ -728,7 +728,7 @@ struct efx_nic { u32 msg_enable; enum nic_state state; - enum reset_type reset_pending; + unsigned long reset_pending; struct efx_channel *channel[EFX_MAX_CHANNELS]; char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6]; -- cgit v1.2.3-70-g09d2 From 0e2a9c7cb941db993f481cdd6a99d70a302053e0 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 24 Jun 2011 20:50:07 +0100 Subject: sfc: Fix mapping of reset reasons and flags to methods There are certain hardware bugs that may occur on Falcon during normal operation, that require a reset to recover from. We try to minimise disruption by keeping the PHY running, following a reset sequence labelled as 'invisible'. Siena does not suffer from these hardware bugs, so we have not implemented an 'invisible' reset sequence. However, if a similar error does occur (due to a hardware fault or software bug) then the code shared with Falcon will wrongly assume that the PHY is not being reset. Since the mapping of reset reasons (internal) and flags (ethtool) to methods must differ significantly between NIC types, move it into per-NIC-type functions (replacing the insufficient reset_world_flags field). Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 20 +++++------------- drivers/net/sfc/ethtool.c | 27 +++++------------------- drivers/net/sfc/falcon.c | 49 ++++++++++++++++++++++++++++++++++++++++++-- drivers/net/sfc/net_driver.h | 7 ++++--- drivers/net/sfc/siena.c | 33 ++++++++++++++++++++++++++++- 5 files changed, 93 insertions(+), 43 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 9b4cfdb0951..ff162df06bd 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -2183,26 +2183,16 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) case RESET_TYPE_WORLD: case RESET_TYPE_DISABLE: method = type; + netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n", + RESET_TYPE(method)); break; - case RESET_TYPE_RX_RECOVERY: - case RESET_TYPE_RX_DESC_FETCH: - case RESET_TYPE_TX_DESC_FETCH: - case RESET_TYPE_TX_SKIP: - method = RESET_TYPE_INVISIBLE; - break; - case RESET_TYPE_MC_FAILURE: default: - method = RESET_TYPE_ALL; - break; - } - - if (method != type) + method = efx->type->map_reset_reason(type); netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset for %s\n", RESET_TYPE(method), RESET_TYPE(type)); - else - netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n", - RESET_TYPE(method)); + break; + } set_bit(method, &efx->reset_pending); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index d229027dc36..bc4643af6dd 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -796,30 +796,13 @@ static int efx_ethtool_set_wol(struct net_device *net_dev, static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) { struct efx_nic *efx = netdev_priv(net_dev); - enum reset_type method; - enum { - ETH_RESET_EFX_INVISIBLE = (ETH_RESET_DMA | ETH_RESET_FILTER | - ETH_RESET_OFFLOAD | ETH_RESET_MAC) - }; - - /* Check for minimal reset flags */ - if ((*flags & ETH_RESET_EFX_INVISIBLE) != ETH_RESET_EFX_INVISIBLE) - return -EINVAL; - *flags ^= ETH_RESET_EFX_INVISIBLE; - method = RESET_TYPE_INVISIBLE; - - if (*flags & ETH_RESET_PHY) { - *flags ^= ETH_RESET_PHY; - method = RESET_TYPE_ALL; - } + int rc; - if ((*flags & efx->type->reset_world_flags) == - efx->type->reset_world_flags) { - *flags ^= efx->type->reset_world_flags; - method = RESET_TYPE_WORLD; - } + rc = efx->type->map_reset_flags(flags); + if (rc < 0) + return rc; - return efx_reset(efx, method); + return efx_reset(efx, rc); } static int diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index a4c7830ec9b..94bf4aaf984 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1051,6 +1051,49 @@ static int falcon_b0_test_registers(struct efx_nic *efx) ************************************************************************** */ +static enum reset_type falcon_map_reset_reason(enum reset_type reason) +{ + switch (reason) { + case RESET_TYPE_RX_RECOVERY: + case RESET_TYPE_RX_DESC_FETCH: + case RESET_TYPE_TX_DESC_FETCH: + case RESET_TYPE_TX_SKIP: + /* These can occasionally occur due to hardware bugs. + * We try to reset without disrupting the link. + */ + return RESET_TYPE_INVISIBLE; + default: + return RESET_TYPE_ALL; + } +} + +static int falcon_map_reset_flags(u32 *flags) +{ + enum { + FALCON_RESET_INVISIBLE = (ETH_RESET_DMA | ETH_RESET_FILTER | + ETH_RESET_OFFLOAD | ETH_RESET_MAC), + FALCON_RESET_ALL = FALCON_RESET_INVISIBLE | ETH_RESET_PHY, + FALCON_RESET_WORLD = FALCON_RESET_ALL | ETH_RESET_IRQ, + }; + + if ((*flags & FALCON_RESET_WORLD) == FALCON_RESET_WORLD) { + *flags &= ~FALCON_RESET_WORLD; + return RESET_TYPE_WORLD; + } + + if ((*flags & FALCON_RESET_ALL) == FALCON_RESET_ALL) { + *flags &= ~FALCON_RESET_ALL; + return RESET_TYPE_ALL; + } + + if ((*flags & FALCON_RESET_INVISIBLE) == FALCON_RESET_INVISIBLE) { + *flags &= ~FALCON_RESET_INVISIBLE; + return RESET_TYPE_INVISIBLE; + } + + return -EINVAL; +} + /* Resets NIC to known state. This routine must be called in process * context and is allowed to sleep. */ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) @@ -1709,6 +1752,8 @@ const struct efx_nic_type falcon_a1_nic_type = { .init = falcon_init_nic, .fini = efx_port_dummy_op_void, .monitor = falcon_monitor, + .map_reset_reason = falcon_map_reset_reason, + .map_reset_flags = falcon_map_reset_flags, .reset = falcon_reset_hw, .probe_port = falcon_probe_port, .remove_port = falcon_remove_port, @@ -1741,7 +1786,6 @@ const struct efx_nic_type falcon_a1_nic_type = { .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, .offload_features = NETIF_F_IP_CSUM, - .reset_world_flags = ETH_RESET_IRQ, }; const struct efx_nic_type falcon_b0_nic_type = { @@ -1750,6 +1794,8 @@ const struct efx_nic_type falcon_b0_nic_type = { .init = falcon_init_nic, .fini = efx_port_dummy_op_void, .monitor = falcon_monitor, + .map_reset_reason = falcon_map_reset_reason, + .map_reset_flags = falcon_map_reset_flags, .reset = falcon_reset_hw, .probe_port = falcon_probe_port, .remove_port = falcon_remove_port, @@ -1791,6 +1837,5 @@ const struct efx_nic_type falcon_b0_nic_type = { .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, - .reset_world_flags = ETH_RESET_IRQ, }; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index c422eb2ce60..4597066741f 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -828,6 +828,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @init: Initialise the controller * @fini: Shut down the controller * @monitor: Periodic function for polling link state and hardware monitor + * @map_reset_reason: Map ethtool reset reason to a reset method + * @map_reset_flags: Map ethtool reset flags to a reset method, if possible * @reset: Reset the controller hardware and possibly the PHY. This will * be called while the controller is uninitialised. * @probe_port: Probe the MAC and PHY @@ -865,8 +867,6 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @rx_dc_base: Base address in SRAM of RX queue descriptor caches * @offload_features: net_device feature flags for protocol offload * features implemented in hardware - * @reset_world_flags: Flags for additional components covered by - * reset method RESET_TYPE_WORLD */ struct efx_nic_type { int (*probe)(struct efx_nic *efx); @@ -874,6 +874,8 @@ struct efx_nic_type { int (*init)(struct efx_nic *efx); void (*fini)(struct efx_nic *efx); void (*monitor)(struct efx_nic *efx); + enum reset_type (*map_reset_reason)(enum reset_type reason); + int (*map_reset_flags)(u32 *flags); int (*reset)(struct efx_nic *efx, enum reset_type method); int (*probe_port)(struct efx_nic *efx); void (*remove_port)(struct efx_nic *efx); @@ -908,7 +910,6 @@ struct efx_nic_type { unsigned int tx_dc_base; unsigned int rx_dc_base; u32 offload_features; - u32 reset_world_flags; }; /************************************************************************** diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index a66818ed401..442897b1427 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -177,6 +177,36 @@ static int siena_test_registers(struct efx_nic *efx) ************************************************************************** */ +static enum reset_type siena_map_reset_reason(enum reset_type reason) +{ + return RESET_TYPE_ALL; +} + +static int siena_map_reset_flags(u32 *flags) +{ + enum { + SIENA_RESET_PORT = (ETH_RESET_DMA | ETH_RESET_FILTER | + ETH_RESET_OFFLOAD | ETH_RESET_MAC | + ETH_RESET_PHY), + SIENA_RESET_MC = (SIENA_RESET_PORT | + ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT), + }; + + if ((*flags & SIENA_RESET_MC) == SIENA_RESET_MC) { + *flags &= ~SIENA_RESET_MC; + return RESET_TYPE_WORLD; + } + + if ((*flags & SIENA_RESET_PORT) == SIENA_RESET_PORT) { + *flags &= ~SIENA_RESET_PORT; + return RESET_TYPE_ALL; + } + + /* no invisible reset implemented */ + + return -EINVAL; +} + static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) { int rc; @@ -605,6 +635,8 @@ const struct efx_nic_type siena_a0_nic_type = { .init = siena_init_nic, .fini = efx_port_dummy_op_void, .monitor = NULL, + .map_reset_reason = siena_map_reset_reason, + .map_reset_flags = siena_map_reset_flags, .reset = siena_reset_hw, .probe_port = siena_probe_port, .remove_port = siena_remove_port, @@ -641,5 +673,4 @@ const struct efx_nic_type siena_a0_nic_type = { .rx_dc_base = 0x68000, .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE), - .reset_world_flags = ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT, }; -- cgit v1.2.3-70-g09d2 From a659b2a94d87add999229ecd9f2f56817d5d737b Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Wed, 22 Jun 2011 12:11:33 +0100 Subject: sfc: Fix Siena mac statistics on big endian platforms [bwh: Use __force in the one place it's needed] Signed-off-by: Ben Hutchings --- drivers/net/sfc/siena.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 442897b1427..5735e84c69d 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -420,14 +420,13 @@ static void siena_remove_nic(struct efx_nic *efx) efx->nic_data = NULL; } -#define STATS_GENERATION_INVALID ((u64)(-1)) +#define STATS_GENERATION_INVALID ((__force __le64)(-1)) static int siena_try_update_nic_stats(struct efx_nic *efx) { - u64 *dma_stats; + __le64 *dma_stats; struct efx_mac_stats *mac_stats; - u64 generation_start; - u64 generation_end; + __le64 generation_start, generation_end; mac_stats = &efx->mac_stats; dma_stats = efx->stats_buffer.addr; @@ -438,7 +437,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) rmb(); #define MAC_STAT(M, D) \ - mac_stats->M = dma_stats[MC_CMD_MAC_ ## D] + mac_stats->M = le64_to_cpu(dma_stats[MC_CMD_MAC_ ## D]) MAC_STAT(tx_bytes, TX_BYTES); MAC_STAT(tx_bad_bytes, TX_BAD_BYTES); @@ -508,7 +507,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) MAC_STAT(rx_internal_error, RX_INTERNAL_ERROR_PKTS); mac_stats->rx_good_lt64 = 0; - efx->n_rx_nodesc_drop_cnt = dma_stats[MC_CMD_MAC_RX_NODESC_DROPS]; + efx->n_rx_nodesc_drop_cnt = + le64_to_cpu(dma_stats[MC_CMD_MAC_RX_NODESC_DROPS]); #undef MAC_STAT @@ -537,7 +537,7 @@ static void siena_update_nic_stats(struct efx_nic *efx) static void siena_start_nic_stats(struct efx_nic *efx) { - u64 *dma_stats = (u64 *)efx->stats_buffer.addr; + __le64 *dma_stats = efx->stats_buffer.addr; dma_stats[MC_CMD_MAC_GENERATION_END] = STATS_GENERATION_INVALID; -- cgit v1.2.3-70-g09d2 From 589327905cf0ce4402f7fb1ed29682f7ae68a82e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 25 Jun 2011 00:22:08 +0100 Subject: sfc: Fix assertions in efx_filter_rfs() This function is intended to assert (when DEBUG is defined) that the skb header area includes the header fields it's looking at, which RFS should already have pulled. But it uses pskb_may_pull(), which will attempt to pull more data if necesary. It must instead compare skb_headlen() with the required length. Signed-off-by: Ben Hutchings --- drivers/net/sfc/filter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index 054f0a3d45a..2b9636f96e0 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -657,11 +657,11 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, return -EPROTONOSUPPORT; /* RFS must validate the IP header length before calling us */ - EFX_BUG_ON_PARANOID(!pskb_may_pull(skb, nhoff + sizeof(*ip))); + EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + sizeof(*ip)); ip = (const struct iphdr *)(skb->data + nhoff); if (ip_is_fragment(ip)) return -EPROTONOSUPPORT; - EFX_BUG_ON_PARANOID(!pskb_may_pull(skb, nhoff + 4 * ip->ihl + 4)); + EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + 4 * ip->ihl + 4); ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl); efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT, 0, rxq_index); -- cgit v1.2.3-70-g09d2 From 7b5b0abdb6757011ab51eaf1227e3fcf3ab61d97 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:38:53 +0000 Subject: ariadne: Update style, neaten, restructure to eliminate prototypes Convert to current logging styles. Move code blocks to eliminate need for prototypes. Use tabs for code indent and sandardize spacing. Comment neatening. Signed-off-by: Joe Perches Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ariadne.c | 1267 +++++++++++++++++++++++-------------------------- 1 file changed, 601 insertions(+), 666 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index b7f45cd756a..7ed78f40204 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -34,6 +34,9 @@ * - an MC68230 Parallel Interface/Timer configured as 2 parallel ports */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +/*#define DEBUG*/ + #include #include #include @@ -54,802 +57,734 @@ #include "ariadne.h" - #ifdef ARIADNE_DEBUG int ariadne_debug = ARIADNE_DEBUG; #else int ariadne_debug = 1; #endif +/* Macros to Fix Endianness problems */ - /* - * Macros to Fix Endianness problems - */ - - /* Swap the Bytes in a WORD */ -#define swapw(x) (((x>>8)&0x00ff)|((x<<8)&0xff00)) - /* Get the Low BYTE in a WORD */ -#define lowb(x) (x&0xff) - /* Get the Swapped High WORD in a LONG */ -#define swhighw(x) ((((x)>>8)&0xff00)|(((x)>>24)&0x00ff)) - /* Get the Swapped Low WORD in a LONG */ -#define swloww(x) ((((x)<<8)&0xff00)|(((x)>>8)&0x00ff)) +/* Swap the Bytes in a WORD */ +#define swapw(x) (((x >> 8) & 0x00ff) | ((x << 8) & 0xff00)) +/* Get the Low BYTE in a WORD */ +#define lowb(x) (x & 0xff) +/* Get the Swapped High WORD in a LONG */ +#define swhighw(x) ((((x) >> 8) & 0xff00) | (((x) >> 24) & 0x00ff)) +/* Get the Swapped Low WORD in a LONG */ +#define swloww(x) ((((x) << 8) & 0xff00) | (((x) >> 8) & 0x00ff)) - - /* - * Transmit/Receive Ring Definitions - */ +/* Transmit/Receive Ring Definitions */ #define TX_RING_SIZE 5 #define RX_RING_SIZE 16 #define PKT_BUF_SIZE 1520 - - /* - * Private Device Data - */ +/* Private Device Data */ struct ariadne_private { - volatile struct TDRE *tx_ring[TX_RING_SIZE]; - volatile struct RDRE *rx_ring[RX_RING_SIZE]; - volatile u_short *tx_buff[TX_RING_SIZE]; - volatile u_short *rx_buff[RX_RING_SIZE]; - int cur_tx, cur_rx; /* The next free ring entry */ - int dirty_tx; /* The ring entries to be free()ed. */ - char tx_full; + volatile struct TDRE *tx_ring[TX_RING_SIZE]; + volatile struct RDRE *rx_ring[RX_RING_SIZE]; + volatile u_short *tx_buff[TX_RING_SIZE]; + volatile u_short *rx_buff[RX_RING_SIZE]; + int cur_tx, cur_rx; /* The next free ring entry */ + int dirty_tx; /* The ring entries to be free()ed */ + char tx_full; }; - - /* - * Structure Created in the Ariadne's RAM Buffer - */ +/* Structure Created in the Ariadne's RAM Buffer */ struct lancedata { - struct TDRE tx_ring[TX_RING_SIZE]; - struct RDRE rx_ring[RX_RING_SIZE]; - u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)]; - u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)]; + struct TDRE tx_ring[TX_RING_SIZE]; + struct RDRE rx_ring[RX_RING_SIZE]; + u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE / sizeof(u_short)]; + u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE / sizeof(u_short)]; }; -static int ariadne_open(struct net_device *dev); -static void ariadne_init_ring(struct net_device *dev); -static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb, - struct net_device *dev); -static void ariadne_tx_timeout(struct net_device *dev); -static int ariadne_rx(struct net_device *dev); -static void ariadne_reset(struct net_device *dev); -static irqreturn_t ariadne_interrupt(int irq, void *data); -static int ariadne_close(struct net_device *dev); -static struct net_device_stats *ariadne_get_stats(struct net_device *dev); -static void set_multicast_list(struct net_device *dev); - - static void memcpyw(volatile u_short *dest, u_short *src, int len) { - while (len >= 2) { - *(dest++) = *(src++); - len -= 2; - } - if (len == 1) - *dest = (*(u_char *)src)<<8; + while (len >= 2) { + *(dest++) = *(src++); + len -= 2; + } + if (len == 1) + *dest = (*(u_char *)src) << 8; } +static void ariadne_init_ring(struct net_device *dev) +{ + struct ariadne_private *priv = netdev_priv(dev); + volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start; + int i; -static int __devinit ariadne_init_one(struct zorro_dev *z, - const struct zorro_device_id *ent); -static void __devexit ariadne_remove_one(struct zorro_dev *z); - - -static struct zorro_device_id ariadne_zorro_tbl[] __devinitdata = { - { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE }, - { 0 } -}; -MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl); + netif_stop_queue(dev); -static struct zorro_driver ariadne_driver = { - .name = "ariadne", - .id_table = ariadne_zorro_tbl, - .probe = ariadne_init_one, - .remove = __devexit_p(ariadne_remove_one), -}; + priv->tx_full = 0; + priv->cur_rx = priv->cur_tx = 0; + priv->dirty_tx = 0; + + /* Set up TX Ring */ + for (i = 0; i < TX_RING_SIZE; i++) { + volatile struct TDRE *t = &lancedata->tx_ring[i]; + t->TMD0 = swloww(ARIADNE_RAM + + offsetof(struct lancedata, tx_buff[i])); + t->TMD1 = swhighw(ARIADNE_RAM + + offsetof(struct lancedata, tx_buff[i])) | + TF_STP | TF_ENP; + t->TMD2 = swapw((u_short)-PKT_BUF_SIZE); + t->TMD3 = 0; + priv->tx_ring[i] = &lancedata->tx_ring[i]; + priv->tx_buff[i] = lancedata->tx_buff[i]; + netdev_dbg(dev, "TX Entry %2d at %p, Buf at %p\n", + i, &lancedata->tx_ring[i], lancedata->tx_buff[i]); + } -static const struct net_device_ops ariadne_netdev_ops = { - .ndo_open = ariadne_open, - .ndo_stop = ariadne_close, - .ndo_start_xmit = ariadne_start_xmit, - .ndo_tx_timeout = ariadne_tx_timeout, - .ndo_get_stats = ariadne_get_stats, - .ndo_set_multicast_list = set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, -}; + /* Set up RX Ring */ + for (i = 0; i < RX_RING_SIZE; i++) { + volatile struct RDRE *r = &lancedata->rx_ring[i]; + r->RMD0 = swloww(ARIADNE_RAM + + offsetof(struct lancedata, rx_buff[i])); + r->RMD1 = swhighw(ARIADNE_RAM + + offsetof(struct lancedata, rx_buff[i])) | + RF_OWN; + r->RMD2 = swapw((u_short)-PKT_BUF_SIZE); + r->RMD3 = 0x0000; + priv->rx_ring[i] = &lancedata->rx_ring[i]; + priv->rx_buff[i] = lancedata->rx_buff[i]; + netdev_dbg(dev, "RX Entry %2d at %p, Buf at %p\n", + i, &lancedata->rx_ring[i], lancedata->rx_buff[i]); + } +} -static int __devinit ariadne_init_one(struct zorro_dev *z, - const struct zorro_device_id *ent) +static int ariadne_rx(struct net_device *dev) { - unsigned long board = z->resource.start; - unsigned long base_addr = board+ARIADNE_LANCE; - unsigned long mem_start = board+ARIADNE_RAM; - struct resource *r1, *r2; - struct net_device *dev; - struct ariadne_private *priv; - int err; - - r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960"); - if (!r1) - return -EBUSY; - r2 = request_mem_region(mem_start, ARIADNE_RAM_SIZE, "RAM"); - if (!r2) { - release_mem_region(base_addr, sizeof(struct Am79C960)); - return -EBUSY; - } - - dev = alloc_etherdev(sizeof(struct ariadne_private)); - if (dev == NULL) { - release_mem_region(base_addr, sizeof(struct Am79C960)); - release_mem_region(mem_start, ARIADNE_RAM_SIZE); - return -ENOMEM; - } - - priv = netdev_priv(dev); - - r1->name = dev->name; - r2->name = dev->name; - - dev->dev_addr[0] = 0x00; - dev->dev_addr[1] = 0x60; - dev->dev_addr[2] = 0x30; - dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff; - dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff; - dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff; - dev->base_addr = ZTWO_VADDR(base_addr); - dev->mem_start = ZTWO_VADDR(mem_start); - dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE; - - dev->netdev_ops = &ariadne_netdev_ops; - dev->watchdog_timeo = 5*HZ; - - err = register_netdev(dev); - if (err) { - release_mem_region(base_addr, sizeof(struct Am79C960)); - release_mem_region(mem_start, ARIADNE_RAM_SIZE); - free_netdev(dev); - return err; - } - zorro_set_drvdata(z, dev); + struct ariadne_private *priv = netdev_priv(dev); + int entry = priv->cur_rx % RX_RING_SIZE; + int i; - printk(KERN_INFO "%s: Ariadne at 0x%08lx, Ethernet Address %pM\n", - dev->name, board, dev->dev_addr); + /* If we own the next entry, it's a new packet. Send it up */ + while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) { + int status = lowb(priv->rx_ring[entry]->RMD1); + + if (status != (RF_STP | RF_ENP)) { /* There was an error */ + /* There is a tricky error noted by + * John Murphy to Russ Nelson: + * Even with full-sized buffers it's possible for a + * jabber packet to use two buffers, with only the + * last correctly noting the error + */ + /* Only count a general error at the end of a packet */ + if (status & RF_ENP) + dev->stats.rx_errors++; + if (status & RF_FRAM) + dev->stats.rx_frame_errors++; + if (status & RF_OFLO) + dev->stats.rx_over_errors++; + if (status & RF_CRC) + dev->stats.rx_crc_errors++; + if (status & RF_BUFF) + dev->stats.rx_fifo_errors++; + priv->rx_ring[entry]->RMD1 &= 0xff00 | RF_STP | RF_ENP; + } else { + /* Malloc up new buffer, compatible with net-3 */ + short pkt_len = swapw(priv->rx_ring[entry]->RMD3); + struct sk_buff *skb; + + skb = dev_alloc_skb(pkt_len + 2); + if (skb == NULL) { + netdev_warn(dev, "Memory squeeze, deferring packet\n"); + for (i = 0; i < RX_RING_SIZE; i++) + if (lowb(priv->rx_ring[(entry + i) % RX_RING_SIZE]->RMD1) & RF_OWN) + break; + + if (i > RX_RING_SIZE - 2) { + dev->stats.rx_dropped++; + priv->rx_ring[entry]->RMD1 |= RF_OWN; + priv->cur_rx++; + } + break; + } + + + skb_reserve(skb, 2); /* 16 byte align */ + skb_put(skb, pkt_len); /* Make room */ + skb_copy_to_linear_data(skb, + (const void *)priv->rx_buff[entry], + pkt_len); + skb->protocol = eth_type_trans(skb, dev); + netdev_dbg(dev, "RX pkt type 0x%04x from %pM to %pM data 0x%08x len %d\n", + ((u_short *)skb->data)[6], + skb->data + 6, skb->data, + (int)skb->data, (int)skb->len); + + netif_rx(skb); + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; + } - return 0; -} + priv->rx_ring[entry]->RMD1 |= RF_OWN; + entry = (++priv->cur_rx) % RX_RING_SIZE; + } + priv->cur_rx = priv->cur_rx % RX_RING_SIZE; -static int ariadne_open(struct net_device *dev) -{ - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; - u_short in; - u_long version; - int i; - - /* Reset the LANCE */ - in = lance->Reset; - - /* Stop the LANCE */ - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - lance->RDP = STOP; - - /* Check the LANCE version */ - lance->RAP = CSR88; /* Chip ID */ - version = swapw(lance->RDP); - lance->RAP = CSR89; /* Chip ID */ - version |= swapw(lance->RDP)<<16; - if ((version & 0x00000fff) != 0x00000003) { - printk(KERN_WARNING "ariadne_open: Couldn't find AMD Ethernet Chip\n"); - return -EAGAIN; - } - if ((version & 0x0ffff000) != 0x00003000) { - printk(KERN_WARNING "ariadne_open: Couldn't find Am79C960 (Wrong part " - "number = %ld)\n", (version & 0x0ffff000)>>12); - return -EAGAIN; - } -#if 0 - printk(KERN_DEBUG "ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n", - (version & 0xf0000000)>>28); -#endif + /* We should check that at least two ring entries are free. + * If not, we should free one and mark stats->rx_dropped++ + */ - ariadne_init_ring(dev); - - /* Miscellaneous Stuff */ - lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */ - lance->RDP = 0x0000; - lance->RAP = CSR4; /* Test and Features Control */ - lance->RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM; - - /* Set the Multicast Table */ - lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */ - lance->RDP = 0x0000; - lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */ - lance->RDP = 0x0000; - lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */ - lance->RDP = 0x0000; - lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */ - lance->RDP = 0x0000; - - /* Set the Ethernet Hardware Address */ - lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */ - lance->RDP = ((u_short *)&dev->dev_addr[0])[0]; - lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */ - lance->RDP = ((u_short *)&dev->dev_addr[0])[1]; - lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */ - lance->RDP = ((u_short *)&dev->dev_addr[0])[2]; - - /* Set the Init Block Mode */ - lance->RAP = CSR15; /* Mode Register */ - lance->RDP = 0x0000; - - /* Set the Transmit Descriptor Ring Pointer */ - lance->RAP = CSR30; /* Base Address of Transmit Ring */ - lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); - lance->RAP = CSR31; /* Base Address of transmit Ring */ - lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); - - /* Set the Receive Descriptor Ring Pointer */ - lance->RAP = CSR24; /* Base Address of Receive Ring */ - lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); - lance->RAP = CSR25; /* Base Address of Receive Ring */ - lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); - - /* Set the Number of RX and TX Ring Entries */ - lance->RAP = CSR76; /* Receive Ring Length */ - lance->RDP = swapw(((u_short)-RX_RING_SIZE)); - lance->RAP = CSR78; /* Transmit Ring Length */ - lance->RDP = swapw(((u_short)-TX_RING_SIZE)); - - /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */ - lance->RAP = ISACSR2; /* Miscellaneous Configuration */ - lance->IDP = ASEL; - - /* LED Control */ - lance->RAP = ISACSR5; /* LED1 Status */ - lance->IDP = PSE|XMTE; - lance->RAP = ISACSR6; /* LED2 Status */ - lance->IDP = PSE|COLE; - lance->RAP = ISACSR7; /* LED3 Status */ - lance->IDP = PSE|RCVE; - - netif_start_queue(dev); - - i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED, - dev->name, dev); - if (i) return i; - - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - lance->RDP = INEA|STRT; - - return 0; + return 0; } - -static void ariadne_init_ring(struct net_device *dev) +static irqreturn_t ariadne_interrupt(int irq, void *data) { - struct ariadne_private *priv = netdev_priv(dev); - volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start; - int i; - - netif_stop_queue(dev); - - priv->tx_full = 0; - priv->cur_rx = priv->cur_tx = 0; - priv->dirty_tx = 0; - - /* Set up TX Ring */ - for (i = 0; i < TX_RING_SIZE; i++) { - volatile struct TDRE *t = &lancedata->tx_ring[i]; - t->TMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])); - t->TMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])) | - TF_STP | TF_ENP; - t->TMD2 = swapw((u_short)-PKT_BUF_SIZE); - t->TMD3 = 0; - priv->tx_ring[i] = &lancedata->tx_ring[i]; - priv->tx_buff[i] = lancedata->tx_buff[i]; -#if 0 - printk(KERN_DEBUG "TX Entry %2d at %p, Buf at %p\n", i, - &lancedata->tx_ring[i], lancedata->tx_buff[i]); -#endif - } - - /* Set up RX Ring */ - for (i = 0; i < RX_RING_SIZE; i++) { - volatile struct RDRE *r = &lancedata->rx_ring[i]; - r->RMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])); - r->RMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])) | - RF_OWN; - r->RMD2 = swapw((u_short)-PKT_BUF_SIZE); - r->RMD3 = 0x0000; - priv->rx_ring[i] = &lancedata->rx_ring[i]; - priv->rx_buff[i] = lancedata->rx_buff[i]; -#if 0 - printk(KERN_DEBUG "RX Entry %2d at %p, Buf at %p\n", i, - &lancedata->rx_ring[i], lancedata->rx_buff[i]); + struct net_device *dev = (struct net_device *)data; + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; + struct ariadne_private *priv; + int csr0, boguscnt; + int handled = 0; + + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + + if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ + return IRQ_NONE; /* generated by the board */ + + priv = netdev_priv(dev); + + boguscnt = 10; + while ((csr0 = lance->RDP) & (ERR | RINT | TINT) && --boguscnt >= 0) { + /* Acknowledge all of the current interrupt sources ASAP */ + lance->RDP = csr0 & ~(INEA | TDMD | STOP | STRT | INIT); + +#ifdef DEBUG + if (ariadne_debug > 5) { + netdev_dbg(dev, "interrupt csr0=%#02x new csr=%#02x [", + csr0, lance->RDP); + if (csr0 & INTR) + pr_cont(" INTR"); + if (csr0 & INEA) + pr_cont(" INEA"); + if (csr0 & RXON) + pr_cont(" RXON"); + if (csr0 & TXON) + pr_cont(" TXON"); + if (csr0 & TDMD) + pr_cont(" TDMD"); + if (csr0 & STOP) + pr_cont(" STOP"); + if (csr0 & STRT) + pr_cont(" STRT"); + if (csr0 & INIT) + pr_cont(" INIT"); + if (csr0 & ERR) + pr_cont(" ERR"); + if (csr0 & BABL) + pr_cont(" BABL"); + if (csr0 & CERR) + pr_cont(" CERR"); + if (csr0 & MISS) + pr_cont(" MISS"); + if (csr0 & MERR) + pr_cont(" MERR"); + if (csr0 & RINT) + pr_cont(" RINT"); + if (csr0 & TINT) + pr_cont(" TINT"); + if (csr0 & IDON) + pr_cont(" IDON"); + pr_cont(" ]\n"); + } #endif - } -} + if (csr0 & RINT) { /* Rx interrupt */ + handled = 1; + ariadne_rx(dev); + } -static int ariadne_close(struct net_device *dev) -{ - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; + if (csr0 & TINT) { /* Tx-done interrupt */ + int dirty_tx = priv->dirty_tx; + + handled = 1; + while (dirty_tx < priv->cur_tx) { + int entry = dirty_tx % TX_RING_SIZE; + int status = lowb(priv->tx_ring[entry]->TMD1); + + if (status & TF_OWN) + break; /* It still hasn't been Txed */ + + priv->tx_ring[entry]->TMD1 &= 0xff00; + + if (status & TF_ERR) { + /* There was an major error, log it */ + int err_status = priv->tx_ring[entry]->TMD3; + dev->stats.tx_errors++; + if (err_status & EF_RTRY) + dev->stats.tx_aborted_errors++; + if (err_status & EF_LCAR) + dev->stats.tx_carrier_errors++; + if (err_status & EF_LCOL) + dev->stats.tx_window_errors++; + if (err_status & EF_UFLO) { + /* Ackk! On FIFO errors the Tx unit is turned off! */ + dev->stats.tx_fifo_errors++; + /* Remove this verbosity later! */ + netdev_err(dev, "Tx FIFO error! Status %04x\n", + csr0); + /* Restart the chip */ + lance->RDP = STRT; + } + } else { + if (status & (TF_MORE | TF_ONE)) + dev->stats.collisions++; + dev->stats.tx_packets++; + } + dirty_tx++; + } - netif_stop_queue(dev); +#ifndef final_version + if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) { + netdev_err(dev, "out-of-sync dirty pointer, %d vs. %d, full=%d\n", + dirty_tx, priv->cur_tx, + priv->tx_full); + dirty_tx += TX_RING_SIZE; + } +#endif - lance->RAP = CSR112; /* Missed Frame Count */ - dev->stats.rx_missed_errors = swapw(lance->RDP); - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + if (priv->tx_full && netif_queue_stopped(dev) && + dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) { + /* The ring is no longer full */ + priv->tx_full = 0; + netif_wake_queue(dev); + } - if (ariadne_debug > 1) { - printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", - dev->name, lance->RDP); - printk(KERN_DEBUG "%s: %lu packets missed\n", dev->name, - dev->stats.rx_missed_errors); - } + priv->dirty_tx = dirty_tx; + } - /* We stop the LANCE here -- it occasionally polls memory if we don't. */ - lance->RDP = STOP; + /* Log misc errors */ + if (csr0 & BABL) { + handled = 1; + dev->stats.tx_errors++; /* Tx babble */ + } + if (csr0 & MISS) { + handled = 1; + dev->stats.rx_errors++; /* Missed a Rx frame */ + } + if (csr0 & MERR) { + handled = 1; + netdev_err(dev, "Bus master arbitration failure, status %04x\n", + csr0); + /* Restart the chip */ + lance->RDP = STRT; + } + } - free_irq(IRQ_AMIGA_PORTS, dev); + /* Clear any other interrupt, and set interrupt enable */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA | BABL | CERR | MISS | MERR | IDON; - return 0; -} + if (ariadne_debug > 4) + netdev_dbg(dev, "exiting interrupt, csr%d=%#04x\n", + lance->RAP, lance->RDP); + return IRQ_RETVAL(handled); +} -static inline void ariadne_reset(struct net_device *dev) +static int ariadne_open(struct net_device *dev) { - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; - - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - lance->RDP = STOP; - ariadne_init_ring(dev); - lance->RDP = INEA|STRT; - netif_start_queue(dev); -} + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; + u_short in; + u_long version; + int i; + /* Reset the LANCE */ + in = lance->Reset; + + /* Stop the LANCE */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = STOP; + + /* Check the LANCE version */ + lance->RAP = CSR88; /* Chip ID */ + version = swapw(lance->RDP); + lance->RAP = CSR89; /* Chip ID */ + version |= swapw(lance->RDP) << 16; + if ((version & 0x00000fff) != 0x00000003) { + pr_warn("Couldn't find AMD Ethernet Chip\n"); + return -EAGAIN; + } + if ((version & 0x0ffff000) != 0x00003000) { + pr_warn("Couldn't find Am79C960 (Wrong part number = %ld)\n", + (version & 0x0ffff000) >> 12); + return -EAGAIN; + } -static irqreturn_t ariadne_interrupt(int irq, void *data) -{ - struct net_device *dev = (struct net_device *)data; - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; - struct ariadne_private *priv; - int csr0, boguscnt; - int handled = 0; + netdev_dbg(dev, "Am79C960 (PCnet-ISA) Revision %ld\n", + (version & 0xf0000000) >> 28); - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + ariadne_init_ring(dev); - if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ - return IRQ_NONE; /* generated by the board. */ + /* Miscellaneous Stuff */ + lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */ + lance->RDP = 0x0000; + lance->RAP = CSR4; /* Test and Features Control */ + lance->RDP = DPOLL | APAD_XMT | MFCOM | RCVCCOM | TXSTRTM | JABM; - priv = netdev_priv(dev); + /* Set the Multicast Table */ + lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */ + lance->RDP = 0x0000; + lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */ + lance->RDP = 0x0000; + lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */ + lance->RDP = 0x0000; + lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */ + lance->RDP = 0x0000; - boguscnt = 10; - while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) { - /* Acknowledge all of the current interrupt sources ASAP. */ - lance->RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT); + /* Set the Ethernet Hardware Address */ + lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */ + lance->RDP = ((u_short *)&dev->dev_addr[0])[0]; + lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */ + lance->RDP = ((u_short *)&dev->dev_addr[0])[1]; + lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */ + lance->RDP = ((u_short *)&dev->dev_addr[0])[2]; -#if 0 - if (ariadne_debug > 5) { - printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.", - dev->name, csr0, lance->RDP); - printk("["); - if (csr0 & INTR) - printk(" INTR"); - if (csr0 & INEA) - printk(" INEA"); - if (csr0 & RXON) - printk(" RXON"); - if (csr0 & TXON) - printk(" TXON"); - if (csr0 & TDMD) - printk(" TDMD"); - if (csr0 & STOP) - printk(" STOP"); - if (csr0 & STRT) - printk(" STRT"); - if (csr0 & INIT) - printk(" INIT"); - if (csr0 & ERR) - printk(" ERR"); - if (csr0 & BABL) - printk(" BABL"); - if (csr0 & CERR) - printk(" CERR"); - if (csr0 & MISS) - printk(" MISS"); - if (csr0 & MERR) - printk(" MERR"); - if (csr0 & RINT) - printk(" RINT"); - if (csr0 & TINT) - printk(" TINT"); - if (csr0 & IDON) - printk(" IDON"); - printk(" ]\n"); - } -#endif + /* Set the Init Block Mode */ + lance->RAP = CSR15; /* Mode Register */ + lance->RDP = 0x0000; - if (csr0 & RINT) { /* Rx interrupt */ - handled = 1; - ariadne_rx(dev); - } + /* Set the Transmit Descriptor Ring Pointer */ + lance->RAP = CSR30; /* Base Address of Transmit Ring */ + lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, tx_ring)); + lance->RAP = CSR31; /* Base Address of transmit Ring */ + lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, tx_ring)); + + /* Set the Receive Descriptor Ring Pointer */ + lance->RAP = CSR24; /* Base Address of Receive Ring */ + lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, rx_ring)); + lance->RAP = CSR25; /* Base Address of Receive Ring */ + lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, rx_ring)); + + /* Set the Number of RX and TX Ring Entries */ + lance->RAP = CSR76; /* Receive Ring Length */ + lance->RDP = swapw(((u_short)-RX_RING_SIZE)); + lance->RAP = CSR78; /* Transmit Ring Length */ + lance->RDP = swapw(((u_short)-TX_RING_SIZE)); + + /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */ + lance->RAP = ISACSR2; /* Miscellaneous Configuration */ + lance->IDP = ASEL; + + /* LED Control */ + lance->RAP = ISACSR5; /* LED1 Status */ + lance->IDP = PSE|XMTE; + lance->RAP = ISACSR6; /* LED2 Status */ + lance->IDP = PSE|COLE; + lance->RAP = ISACSR7; /* LED3 Status */ + lance->IDP = PSE|RCVE; + + netif_start_queue(dev); + + i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED, + dev->name, dev); + if (i) + return i; + + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA | STRT; + + return 0; +} - if (csr0 & TINT) { /* Tx-done interrupt */ - int dirty_tx = priv->dirty_tx; - - handled = 1; - while (dirty_tx < priv->cur_tx) { - int entry = dirty_tx % TX_RING_SIZE; - int status = lowb(priv->tx_ring[entry]->TMD1); - - if (status & TF_OWN) - break; /* It still hasn't been Txed */ - - priv->tx_ring[entry]->TMD1 &= 0xff00; - - if (status & TF_ERR) { - /* There was an major error, log it. */ - int err_status = priv->tx_ring[entry]->TMD3; - dev->stats.tx_errors++; - if (err_status & EF_RTRY) - dev->stats.tx_aborted_errors++; - if (err_status & EF_LCAR) - dev->stats.tx_carrier_errors++; - if (err_status & EF_LCOL) - dev->stats.tx_window_errors++; - if (err_status & EF_UFLO) { - /* Ackk! On FIFO errors the Tx unit is turned off! */ - dev->stats.tx_fifo_errors++; - /* Remove this verbosity later! */ - printk(KERN_ERR "%s: Tx FIFO error! Status %4.4x.\n", - dev->name, csr0); - /* Restart the chip. */ - lance->RDP = STRT; - } - } else { - if (status & (TF_MORE|TF_ONE)) - dev->stats.collisions++; - dev->stats.tx_packets++; - } - dirty_tx++; - } +static int ariadne_close(struct net_device *dev) +{ + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; -#ifndef final_version - if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) { - printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d, " - "full=%d.\n", dirty_tx, priv->cur_tx, priv->tx_full); - dirty_tx += TX_RING_SIZE; - } -#endif + netif_stop_queue(dev); - if (priv->tx_full && netif_queue_stopped(dev) && - dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) { - /* The ring is no longer full. */ - priv->tx_full = 0; - netif_wake_queue(dev); - } + lance->RAP = CSR112; /* Missed Frame Count */ + dev->stats.rx_missed_errors = swapw(lance->RDP); + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - priv->dirty_tx = dirty_tx; + if (ariadne_debug > 1) { + netdev_dbg(dev, "Shutting down ethercard, status was %02x\n", + lance->RDP); + netdev_dbg(dev, "%lu packets missed\n", + dev->stats.rx_missed_errors); } - /* Log misc errors. */ - if (csr0 & BABL) { - handled = 1; - dev->stats.tx_errors++; /* Tx babble. */ - } - if (csr0 & MISS) { - handled = 1; - dev->stats.rx_errors++; /* Missed a Rx frame. */ - } - if (csr0 & MERR) { - handled = 1; - printk(KERN_ERR "%s: Bus master arbitration failure, status " - "%4.4x.\n", dev->name, csr0); - /* Restart the chip. */ - lance->RDP = STRT; - } - } + /* We stop the LANCE here -- it occasionally polls memory if we don't */ + lance->RDP = STOP; - /* Clear any other interrupt, and set interrupt enable. */ - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - lance->RDP = INEA|BABL|CERR|MISS|MERR|IDON; + free_irq(IRQ_AMIGA_PORTS, dev); -#if 0 - if (ariadne_debug > 4) - printk(KERN_DEBUG "%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, - lance->RAP, lance->RDP); -#endif - return IRQ_RETVAL(handled); + return 0; } +static inline void ariadne_reset(struct net_device *dev) +{ + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; + + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = STOP; + ariadne_init_ring(dev); + lance->RDP = INEA | STRT; + netif_start_queue(dev); +} static void ariadne_tx_timeout(struct net_device *dev) { - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; - printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n", - dev->name, lance->RDP); - ariadne_reset(dev); - netif_wake_queue(dev); + netdev_err(dev, "transmit timed out, status %04x, resetting\n", + lance->RDP); + ariadne_reset(dev); + netif_wake_queue(dev); } - static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct ariadne_private *priv = netdev_priv(dev); - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; - int entry; - unsigned long flags; - int len = skb->len; - -#if 0 - if (ariadne_debug > 3) { - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - printk(KERN_DEBUG "%s: ariadne_start_xmit() called, csr0 %4.4x.\n", - dev->name, lance->RDP); - lance->RDP = 0x0000; - } -#endif - - /* FIXME: is the 79C960 new enough to do its own padding right ? */ - if (skb->len < ETH_ZLEN) - { - if (skb_padto(skb, ETH_ZLEN)) - return NETDEV_TX_OK; - len = ETH_ZLEN; - } - - /* Fill in a Tx ring entry */ + struct ariadne_private *priv = netdev_priv(dev); + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; + int entry; + unsigned long flags; + int len = skb->len; #if 0 -{ - printk(KERN_DEBUG "TX pkt type 0x%04x from %pM to %pM " - " data 0x%08x len %d\n", - ((u_short *)skb->data)[6], - skb->data + 6, skb->data, - (int)skb->data, (int)skb->len); -} + if (ariadne_debug > 3) { + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + netdev_dbg(dev, "%s: csr0 %04x\n", __func__, lance->RDP); + lance->RDP = 0x0000; + } #endif - local_irq_save(flags); - - entry = priv->cur_tx % TX_RING_SIZE; - - /* Caution: the write order is important here, set the base address with - the "ownership" bits last. */ - - priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len); - priv->tx_ring[entry]->TMD3 = 0x0000; - memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len); - -#if 0 - { - int i, len; - - len = skb->len > 64 ? 64 : skb->len; - len >>= 1; - for (i = 0; i < len; i += 8) { - int j; - printk(KERN_DEBUG "%04x:", i); - for (j = 0; (j < 8) && ((i+j) < len); j++) { - if (!(j & 1)) - printk(" "); - printk("%04x", priv->tx_buff[entry][i+j]); - } - printk("\n"); + /* FIXME: is the 79C960 new enough to do its own padding right ? */ + if (skb->len < ETH_ZLEN) { + if (skb_padto(skb, ETH_ZLEN)) + return NETDEV_TX_OK; + len = ETH_ZLEN; } - } -#endif - priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1&0xff00)|TF_OWN|TF_STP|TF_ENP; + /* Fill in a Tx ring entry */ - dev_kfree_skb(skb); + netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data 0x%08x len %d\n", + ((u_short *)skb->data)[6], + skb->data + 6, skb->data, + (int)skb->data, (int)skb->len); - priv->cur_tx++; - if ((priv->cur_tx >= TX_RING_SIZE) && (priv->dirty_tx >= TX_RING_SIZE)) { + local_irq_save(flags); -#if 0 - printk(KERN_DEBUG "*** Subtracting TX_RING_SIZE from cur_tx (%d) and " - "dirty_tx (%d)\n", priv->cur_tx, priv->dirty_tx); -#endif + entry = priv->cur_tx % TX_RING_SIZE; - priv->cur_tx -= TX_RING_SIZE; - priv->dirty_tx -= TX_RING_SIZE; - } - dev->stats.tx_bytes += len; + /* Caution: the write order is important here, set the base address with + the "ownership" bits last */ - /* Trigger an immediate send poll. */ - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - lance->RDP = INEA|TDMD; + priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len); + priv->tx_ring[entry]->TMD3 = 0x0000; + memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len); - if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) != 0) { - netif_stop_queue(dev); - priv->tx_full = 1; - } - local_irq_restore(flags); +#ifdef DEBUG + print_hex_dump(KERN_DEBUG, "tx_buff: ", DUMP_PREFIX_OFFSET, 16, 1, + (void *)priv->tx_buff[entry], + skb->len > 64 ? 64 : skb->len, true); +#endif - return NETDEV_TX_OK; -} + priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1 & 0xff00) + | TF_OWN | TF_STP | TF_ENP; + dev_kfree_skb(skb); -static int ariadne_rx(struct net_device *dev) -{ - struct ariadne_private *priv = netdev_priv(dev); - int entry = priv->cur_rx % RX_RING_SIZE; - int i; - - /* If we own the next entry, it's a new packet. Send it up. */ - while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) { - int status = lowb(priv->rx_ring[entry]->RMD1); - - if (status != (RF_STP|RF_ENP)) { /* There was an error. */ - /* There is a tricky error noted by John Murphy, - to Russ Nelson: Even with full-sized - buffers it's possible for a jabber packet to use two - buffers, with only the last correctly noting the error. */ - if (status & RF_ENP) - /* Only count a general error at the end of a packet.*/ - dev->stats.rx_errors++; - if (status & RF_FRAM) - dev->stats.rx_frame_errors++; - if (status & RF_OFLO) - dev->stats.rx_over_errors++; - if (status & RF_CRC) - dev->stats.rx_crc_errors++; - if (status & RF_BUFF) - dev->stats.rx_fifo_errors++; - priv->rx_ring[entry]->RMD1 &= 0xff00|RF_STP|RF_ENP; - } else { - /* Malloc up new buffer, compatible with net-3. */ - short pkt_len = swapw(priv->rx_ring[entry]->RMD3); - struct sk_buff *skb; - - skb = dev_alloc_skb(pkt_len+2); - if (skb == NULL) { - printk(KERN_WARNING "%s: Memory squeeze, deferring packet.\n", - dev->name); - for (i = 0; i < RX_RING_SIZE; i++) - if (lowb(priv->rx_ring[(entry+i) % RX_RING_SIZE]->RMD1) & RF_OWN) - break; - - if (i > RX_RING_SIZE-2) { - dev->stats.rx_dropped++; - priv->rx_ring[entry]->RMD1 |= RF_OWN; - priv->cur_rx++; - } - break; - } + priv->cur_tx++; + if ((priv->cur_tx >= TX_RING_SIZE) && + (priv->dirty_tx >= TX_RING_SIZE)) { + netdev_dbg(dev, "*** Subtracting TX_RING_SIZE from cur_tx (%d) and dirty_tx (%d)\n", + priv->cur_tx, priv->dirty_tx); - skb_reserve(skb,2); /* 16 byte align */ - skb_put(skb,pkt_len); /* Make room */ - skb_copy_to_linear_data(skb, (char *)priv->rx_buff[entry], pkt_len); - skb->protocol=eth_type_trans(skb,dev); -#if 0 -{ - printk(KERN_DEBUG "RX pkt type 0x%04x from ", - ((u_short *)skb->data)[6]); - { - u_char *ptr = &((u_char *)skb->data)[6]; - printk("%pM", ptr); - } - printk(" to "); - { - u_char *ptr = (u_char *)skb->data; - printk("%pM", ptr); - } - printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len); -} -#endif - - netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; + priv->cur_tx -= TX_RING_SIZE; + priv->dirty_tx -= TX_RING_SIZE; } + dev->stats.tx_bytes += len; - priv->rx_ring[entry]->RMD1 |= RF_OWN; - entry = (++priv->cur_rx) % RX_RING_SIZE; - } + /* Trigger an immediate send poll */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA | TDMD; - priv->cur_rx = priv->cur_rx % RX_RING_SIZE; - - /* We should check that at least two ring entries are free. If not, - we should free one and mark stats->rx_dropped++. */ + if (lowb(priv->tx_ring[(entry + 1) % TX_RING_SIZE]->TMD1) != 0) { + netif_stop_queue(dev); + priv->tx_full = 1; + } + local_irq_restore(flags); - return 0; + return NETDEV_TX_OK; } - static struct net_device_stats *ariadne_get_stats(struct net_device *dev) { - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; - short saved_addr; - unsigned long flags; - - local_irq_save(flags); - saved_addr = lance->RAP; - lance->RAP = CSR112; /* Missed Frame Count */ - dev->stats.rx_missed_errors = swapw(lance->RDP); - lance->RAP = saved_addr; - local_irq_restore(flags); - - return &dev->stats; + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; + short saved_addr; + unsigned long flags; + + local_irq_save(flags); + saved_addr = lance->RAP; + lance->RAP = CSR112; /* Missed Frame Count */ + dev->stats.rx_missed_errors = swapw(lance->RDP); + lance->RAP = saved_addr; + local_irq_restore(flags); + + return &dev->stats; } - /* Set or clear the multicast filter for this adaptor. - num_addrs == -1 Promiscuous mode, receive all packets - num_addrs == 0 Normal mode, clear multicast list - num_addrs > 0 Multicast mode, receive normal and MC packets, and do - best-effort filtering. + * num_addrs == -1 Promiscuous mode, receive all packets + * num_addrs == 0 Normal mode, clear multicast list + * num_addrs > 0 Multicast mode, receive normal and MC packets, + * and do best-effort filtering. */ static void set_multicast_list(struct net_device *dev) { - volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; + volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr; - if (!netif_running(dev)) - return; + if (!netif_running(dev)) + return; - netif_stop_queue(dev); + netif_stop_queue(dev); - /* We take the simple way out and always enable promiscuous mode. */ - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - lance->RDP = STOP; /* Temporarily stop the lance. */ - ariadne_init_ring(dev); + /* We take the simple way out and always enable promiscuous mode */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = STOP; /* Temporarily stop the lance */ + ariadne_init_ring(dev); - if (dev->flags & IFF_PROMISC) { - lance->RAP = CSR15; /* Mode Register */ - lance->RDP = PROM; /* Set promiscuous mode */ - } else { - short multicast_table[4]; - int num_addrs = netdev_mc_count(dev); - int i; - /* We don't use the multicast table, but rely on upper-layer filtering. */ - memset(multicast_table, (num_addrs == 0) ? 0 : -1, - sizeof(multicast_table)); - for (i = 0; i < 4; i++) { - lance->RAP = CSR8+(i<<8); /* Logical Address Filter */ - lance->RDP = swapw(multicast_table[i]); + if (dev->flags & IFF_PROMISC) { + lance->RAP = CSR15; /* Mode Register */ + lance->RDP = PROM; /* Set promiscuous mode */ + } else { + short multicast_table[4]; + int num_addrs = netdev_mc_count(dev); + int i; + /* We don't use the multicast table, + * but rely on upper-layer filtering + */ + memset(multicast_table, (num_addrs == 0) ? 0 : -1, + sizeof(multicast_table)); + for (i = 0; i < 4; i++) { + lance->RAP = CSR8 + (i << 8); + /* Logical Address Filter */ + lance->RDP = swapw(multicast_table[i]); + } + lance->RAP = CSR15; /* Mode Register */ + lance->RDP = 0x0000; /* Unset promiscuous mode */ } - lance->RAP = CSR15; /* Mode Register */ - lance->RDP = 0x0000; /* Unset promiscuous mode */ - } - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - lance->RDP = INEA|STRT|IDON; /* Resume normal operation. */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA | STRT | IDON;/* Resume normal operation */ - netif_wake_queue(dev); + netif_wake_queue(dev); } static void __devexit ariadne_remove_one(struct zorro_dev *z) { - struct net_device *dev = zorro_get_drvdata(z); + struct net_device *dev = zorro_get_drvdata(z); - unregister_netdev(dev); - release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960)); - release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE); - free_netdev(dev); + unregister_netdev(dev); + release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960)); + release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE); + free_netdev(dev); } +static struct zorro_device_id ariadne_zorro_tbl[] __devinitdata = { + { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE }, + { 0 } +}; +MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl); + +static const struct net_device_ops ariadne_netdev_ops = { + .ndo_open = ariadne_open, + .ndo_stop = ariadne_close, + .ndo_start_xmit = ariadne_start_xmit, + .ndo_tx_timeout = ariadne_tx_timeout, + .ndo_get_stats = ariadne_get_stats, + .ndo_set_multicast_list = set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, +}; + +static int __devinit ariadne_init_one(struct zorro_dev *z, + const struct zorro_device_id *ent) +{ + unsigned long board = z->resource.start; + unsigned long base_addr = board + ARIADNE_LANCE; + unsigned long mem_start = board + ARIADNE_RAM; + struct resource *r1, *r2; + struct net_device *dev; + struct ariadne_private *priv; + int err; + + r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960"); + if (!r1) + return -EBUSY; + r2 = request_mem_region(mem_start, ARIADNE_RAM_SIZE, "RAM"); + if (!r2) { + release_mem_region(base_addr, sizeof(struct Am79C960)); + return -EBUSY; + } + + dev = alloc_etherdev(sizeof(struct ariadne_private)); + if (dev == NULL) { + release_mem_region(base_addr, sizeof(struct Am79C960)); + release_mem_region(mem_start, ARIADNE_RAM_SIZE); + return -ENOMEM; + } + + priv = netdev_priv(dev); + + r1->name = dev->name; + r2->name = dev->name; + + dev->dev_addr[0] = 0x00; + dev->dev_addr[1] = 0x60; + dev->dev_addr[2] = 0x30; + dev->dev_addr[3] = (z->rom.er_SerialNumber >> 16) & 0xff; + dev->dev_addr[4] = (z->rom.er_SerialNumber >> 8) & 0xff; + dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff; + dev->base_addr = ZTWO_VADDR(base_addr); + dev->mem_start = ZTWO_VADDR(mem_start); + dev->mem_end = dev->mem_start + ARIADNE_RAM_SIZE; + + dev->netdev_ops = &ariadne_netdev_ops; + dev->watchdog_timeo = 5 * HZ; + + err = register_netdev(dev); + if (err) { + release_mem_region(base_addr, sizeof(struct Am79C960)); + release_mem_region(mem_start, ARIADNE_RAM_SIZE); + free_netdev(dev); + return err; + } + zorro_set_drvdata(z, dev); + + netdev_info(dev, "Ariadne at 0x%08lx, Ethernet Address %pM\n", + board, dev->dev_addr); + + return 0; +} + +static struct zorro_driver ariadne_driver = { + .name = "ariadne", + .id_table = ariadne_zorro_tbl, + .probe = ariadne_init_one, + .remove = __devexit_p(ariadne_remove_one), +}; + static int __init ariadne_init_module(void) { - return zorro_register_driver(&ariadne_driver); + return zorro_register_driver(&ariadne_driver); } static void __exit ariadne_cleanup_module(void) { - zorro_unregister_driver(&ariadne_driver); + zorro_unregister_driver(&ariadne_driver); } module_init(ariadne_init_module); -- cgit v1.2.3-70-g09d2 From 747e252fa1a061cf63d12ed68ac937cf53a4fe4e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:38:54 +0000 Subject: a2065: Use pr_fmt, pr_ and netdev_ Use current logging styles. Other miscellaneous cleanups: Space removal and additions for checkpatch warnings. Signed-off-by: Joe Perches Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/a2065.c | 336 +++++++++++++++++++++++++--------------------------- 1 file changed, 162 insertions(+), 174 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 25ea98aacf3..7d9a1a6ea8b 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -37,6 +37,11 @@ * both 10BASE-2 (thin coax) and AUI (DB-15) connectors */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +/*#define DEBUG*/ +/*#define TEST_HITS*/ + #include #include #include @@ -58,29 +63,22 @@ #include "a2065.h" - - /* - * Transmit/Receive Ring Definitions - */ +/* Transmit/Receive Ring Definitions */ #define LANCE_LOG_TX_BUFFERS (2) #define LANCE_LOG_RX_BUFFERS (4) -#define TX_RING_SIZE (1<tx_old<=lp->tx_new)?\ - lp->tx_old+lp->tx_ring_mod_mask-lp->tx_new:\ - lp->tx_old - lp->tx_new-1) - - #define LANCE_ADDR(x) ((int)(x) & ~0xff000000) /* Load the CSR registers */ -static void load_csrs (struct lance_private *lp) +static void load_csrs(struct lance_private *lp) { volatile struct lance_regs *ll = lp->ll; volatile struct lance_init_block *aib = lp->lance_init_block; - int leptr; - - leptr = LANCE_ADDR (aib); + int leptr = LANCE_ADDR(aib); ll->rap = LE_CSR1; ll->rdp = (leptr & 0xFFFF); @@ -156,19 +144,16 @@ static void load_csrs (struct lance_private *lp) ll->rap = LE_CSR0; } -#define ZERO 0 - /* Setup the Lance Rx and Tx rings */ -static void lance_init_ring (struct net_device *dev) +static void lance_init_ring(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; - volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */ + volatile struct lance_init_block *aib = lp->lance_init_block; + /* for LANCE_ADDR computations */ int leptr; int i; - aib = lp->lance_init_block; - /* Lock out other processes while setting up hardware */ netif_stop_queue(dev); lp->rx_new = lp->tx_new = 0; @@ -179,41 +164,38 @@ static void lance_init_ring (struct net_device *dev) /* Copy the ethernet address to the lance init block * Note that on the sparc you need to swap the ethernet address. */ - ib->phys_addr [0] = dev->dev_addr [1]; - ib->phys_addr [1] = dev->dev_addr [0]; - ib->phys_addr [2] = dev->dev_addr [3]; - ib->phys_addr [3] = dev->dev_addr [2]; - ib->phys_addr [4] = dev->dev_addr [5]; - ib->phys_addr [5] = dev->dev_addr [4]; - - if (ZERO) - printk(KERN_DEBUG "TX rings:\n"); + ib->phys_addr[0] = dev->dev_addr[1]; + ib->phys_addr[1] = dev->dev_addr[0]; + ib->phys_addr[2] = dev->dev_addr[3]; + ib->phys_addr[3] = dev->dev_addr[2]; + ib->phys_addr[4] = dev->dev_addr[5]; + ib->phys_addr[5] = dev->dev_addr[4]; /* Setup the Tx ring entries */ - for (i = 0; i <= (1<lance_log_tx_bufs); i++) { + netdev_dbg(dev, "TX rings:\n"); + for (i = 0; i <= 1 << lp->lance_log_tx_bufs; i++) { leptr = LANCE_ADDR(&aib->tx_buf[i][0]); - ib->btx_ring [i].tmd0 = leptr; - ib->btx_ring [i].tmd1_hadr = leptr >> 16; - ib->btx_ring [i].tmd1_bits = 0; - ib->btx_ring [i].length = 0xf000; /* The ones required by tmd2 */ - ib->btx_ring [i].misc = 0; - if (i < 3 && ZERO) - printk(KERN_DEBUG "%d: 0x%8.8x\n", i, leptr); + ib->btx_ring[i].tmd0 = leptr; + ib->btx_ring[i].tmd1_hadr = leptr >> 16; + ib->btx_ring[i].tmd1_bits = 0; + ib->btx_ring[i].length = 0xf000; /* The ones required by tmd2 */ + ib->btx_ring[i].misc = 0; + if (i < 3) + netdev_dbg(dev, "%d: 0x%08x\n", i, leptr); } /* Setup the Rx ring entries */ - if (ZERO) - printk(KERN_DEBUG "RX rings:\n"); - for (i = 0; i < (1<lance_log_rx_bufs); i++) { + netdev_dbg(dev, "RX rings:\n"); + for (i = 0; i < 1 << lp->lance_log_rx_bufs; i++) { leptr = LANCE_ADDR(&aib->rx_buf[i][0]); - ib->brx_ring [i].rmd0 = leptr; - ib->brx_ring [i].rmd1_hadr = leptr >> 16; - ib->brx_ring [i].rmd1_bits = LE_R1_OWN; - ib->brx_ring [i].length = -RX_BUFF_SIZE | 0xf000; - ib->brx_ring [i].mblength = 0; - if (i < 3 && ZERO) - printk(KERN_DEBUG "%d: 0x%8.8x\n", i, leptr); + ib->brx_ring[i].rmd0 = leptr; + ib->brx_ring[i].rmd1_hadr = leptr >> 16; + ib->brx_ring[i].rmd1_bits = LE_R1_OWN; + ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000; + ib->brx_ring[i].mblength = 0; + if (i < 3) + netdev_dbg(dev, "%d: 0x%08x\n", i, leptr); } /* Setup the initialization block */ @@ -222,22 +204,20 @@ static void lance_init_ring (struct net_device *dev) leptr = LANCE_ADDR(&aib->brx_ring); ib->rx_len = (lp->lance_log_rx_bufs << 13) | (leptr >> 16); ib->rx_ptr = leptr; - if (ZERO) - printk(KERN_DEBUG "RX ptr: %8.8x\n", leptr); + netdev_dbg(dev, "RX ptr: %08x\n", leptr); /* Setup tx descriptor pointer */ leptr = LANCE_ADDR(&aib->btx_ring); ib->tx_len = (lp->lance_log_tx_bufs << 13) | (leptr >> 16); ib->tx_ptr = leptr; - if (ZERO) - printk(KERN_DEBUG "TX ptr: %8.8x\n", leptr); + netdev_dbg(dev, "TX ptr: %08x\n", leptr); /* Clear the multicast filter */ - ib->filter [0] = 0; - ib->filter [1] = 0; + ib->filter[0] = 0; + ib->filter[1] = 0; } -static int init_restart_lance (struct lance_private *lp) +static int init_restart_lance(struct lance_private *lp) { volatile struct lance_regs *ll = lp->ll; int i; @@ -249,8 +229,7 @@ static int init_restart_lance (struct lance_private *lp) for (i = 0; (i < 100) && !(ll->rdp & (LE_C0_ERR | LE_C0_IDON)); i++) barrier(); if ((i == 100) || (ll->rdp & LE_C0_ERR)) { - printk(KERN_ERR "LANCE unopened after %d ticks, csr0=%4.4x.\n", - i, ll->rdp); + pr_err("unopened after %d ticks, csr0=%04x\n", i, ll->rdp); return -EIO; } @@ -261,7 +240,7 @@ static int init_restart_lance (struct lance_private *lp) return 0; } -static int lance_rx (struct net_device *dev) +static int lance_rx(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; @@ -271,22 +250,24 @@ static int lance_rx (struct net_device *dev) #ifdef TEST_HITS int i; - printk(KERN_DEBUG "["); + char buf[RX_RING_SIZE + 1]; + for (i = 0; i < RX_RING_SIZE; i++) { + char r1_own = ib->brx_ring[i].rmd1_bits & LE_R1_OWN; if (i == lp->rx_new) - printk ("%s", - ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "_" : "X"); + buf[i] = r1_own ? '_' : 'X'; else - printk ("%s", - ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "." : "1"); + buf[i] = r1_own ? '.' : '1'; } - printk ("]\n"); + buf[RX_RING_SIZE] = 0; + + pr_debug("RxRing TestHits: [%s]\n", buf); #endif - ll->rdp = LE_C0_RINT|LE_C0_INEA; - for (rd = &ib->brx_ring [lp->rx_new]; + ll->rdp = LE_C0_RINT | LE_C0_INEA; + for (rd = &ib->brx_ring[lp->rx_new]; !((bits = rd->rmd1_bits) & LE_R1_OWN); - rd = &ib->brx_ring [lp->rx_new]) { + rd = &ib->brx_ring[lp->rx_new]) { /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { @@ -297,18 +278,22 @@ static int lance_rx (struct net_device *dev) /* Count only the end frame as a rx error, * not the beginning */ - if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++; - if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++; - if (bits & LE_R1_OFL) dev->stats.rx_over_errors++; - if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++; - if (bits & LE_R1_EOP) dev->stats.rx_errors++; + if (bits & LE_R1_BUF) + dev->stats.rx_fifo_errors++; + if (bits & LE_R1_CRC) + dev->stats.rx_crc_errors++; + if (bits & LE_R1_OFL) + dev->stats.rx_over_errors++; + if (bits & LE_R1_FRA) + dev->stats.rx_frame_errors++; + if (bits & LE_R1_EOP) + dev->stats.rx_errors++; } else { int len = (rd->mblength & 0xfff) - 4; - struct sk_buff *skb = dev_alloc_skb (len+2); + struct sk_buff *skb = dev_alloc_skb(len + 2); if (!skb) { - printk(KERN_WARNING "%s: Memory squeeze, " - "deferring packet.\n", dev->name); + netdev_warn(dev, "Memory squeeze, deferring packet\n"); dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; @@ -316,13 +301,13 @@ static int lance_rx (struct net_device *dev) return 0; } - skb_reserve (skb, 2); /* 16 byte align */ - skb_put (skb, len); /* make room */ + skb_reserve(skb, 2); /* 16 byte align */ + skb_put(skb, len); /* make room */ skb_copy_to_linear_data(skb, - (unsigned char *)&(ib->rx_buf [lp->rx_new][0]), - len); - skb->protocol = eth_type_trans (skb, dev); - netif_rx (skb); + (unsigned char *)&ib->rx_buf[lp->rx_new][0], + len); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; } @@ -335,7 +320,7 @@ static int lance_rx (struct net_device *dev) return 0; } -static int lance_tx (struct net_device *dev) +static int lance_tx(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; @@ -350,7 +335,7 @@ static int lance_tx (struct net_device *dev) j = lp->tx_old; for (i = j; i != lp->tx_new; i = j) { - td = &ib->btx_ring [i]; + td = &ib->btx_ring[i]; /* If we hit a packet not owned by us, stop */ if (td->tmd1_bits & LE_T1_OWN) @@ -360,45 +345,44 @@ static int lance_tx (struct net_device *dev) status = td->misc; dev->stats.tx_errors++; - if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++; - if (status & LE_T3_LCOL) dev->stats.tx_window_errors++; + if (status & LE_T3_RTY) + dev->stats.tx_aborted_errors++; + if (status & LE_T3_LCOL) + dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { dev->stats.tx_carrier_errors++; if (lp->auto_select) { lp->tpe = 1 - lp->tpe; - printk(KERN_ERR "%s: Carrier Lost, " - "trying %s\n", dev->name, - lp->tpe?"TPE":"AUI"); + netdev_err(dev, "Carrier Lost, trying %s\n", + lp->tpe ? "TPE" : "AUI"); /* Stop the lance */ ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; - lance_init_ring (dev); - load_csrs (lp); - init_restart_lance (lp); + lance_init_ring(dev); + load_csrs(lp); + init_restart_lance(lp); return 0; } } - /* buffer errors and underflows turn off the transmitter */ - /* Restart the adapter */ - if (status & (LE_T3_BUF|LE_T3_UFL)) { + /* buffer errors and underflows turn off + * the transmitter, so restart the adapter + */ + if (status & (LE_T3_BUF | LE_T3_UFL)) { dev->stats.tx_fifo_errors++; - printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, " - "restarting\n", dev->name); + netdev_err(dev, "Tx: ERR_BUF|ERR_UFL, restarting\n"); /* Stop the lance */ ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; - lance_init_ring (dev); - load_csrs (lp); - init_restart_lance (lp); + lance_init_ring(dev); + load_csrs(lp); + init_restart_lance(lp); return 0; } } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) { - /* - * So we don't count the packet more than once. - */ + /* So we don't count the packet more than once. */ td->tmd1_bits &= ~(LE_T1_POK); /* One collision before packet was sent. */ @@ -419,7 +403,14 @@ static int lance_tx (struct net_device *dev) return 0; } -static irqreturn_t lance_interrupt (int irq, void *dev_id) +static int lance_tx_buffs_avail(struct lance_private *lp) +{ + if (lp->tx_old <= lp->tx_new) + return lp->tx_old + lp->tx_ring_mod_mask - lp->tx_new; + return lp->tx_old - lp->tx_new - 1; +} + +static irqreturn_t lance_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct lance_private *lp = netdev_priv(dev); @@ -433,19 +424,19 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id) return IRQ_NONE; /* been generated by the Lance. */ /* Acknowledge all the interrupt sources ASAP */ - ll->rdp = csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT| + ll->rdp = csr0 & ~(LE_C0_INEA | LE_C0_TDMD | LE_C0_STOP | LE_C0_STRT | LE_C0_INIT); - if ((csr0 & LE_C0_ERR)) { + if (csr0 & LE_C0_ERR) { /* Clear the error condition */ - ll->rdp = LE_C0_BABL|LE_C0_ERR|LE_C0_MISS|LE_C0_INEA; + ll->rdp = LE_C0_BABL | LE_C0_ERR | LE_C0_MISS | LE_C0_INEA; } if (csr0 & LE_C0_RINT) - lance_rx (dev); + lance_rx(dev); if (csr0 & LE_C0_TINT) - lance_tx (dev); + lance_tx(dev); /* Log misc errors. */ if (csr0 & LE_C0_BABL) @@ -453,22 +444,22 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id) if (csr0 & LE_C0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */ if (csr0 & LE_C0_MERR) { - printk(KERN_ERR "%s: Bus master arbitration failure, status " - "%4.4x.\n", dev->name, csr0); + netdev_err(dev, "Bus master arbitration failure, status %04x\n", + csr0); /* Restart the chip. */ ll->rdp = LE_C0_STRT; } - if (netif_queue_stopped(dev) && TX_BUFFS_AVAIL > 0) + if (netif_queue_stopped(dev) && lance_tx_buffs_avail(lp) > 0) netif_wake_queue(dev); ll->rap = LE_CSR0; - ll->rdp = LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR| - LE_C0_IDON|LE_C0_INEA; + ll->rdp = (LE_C0_BABL | LE_C0_CERR | LE_C0_MISS | LE_C0_MERR | + LE_C0_IDON | LE_C0_INEA); return IRQ_HANDLED; } -static int lance_open (struct net_device *dev) +static int lance_open(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; @@ -481,17 +472,18 @@ static int lance_open (struct net_device *dev) /* Install the Interrupt handler */ ret = request_irq(IRQ_AMIGA_PORTS, lance_interrupt, IRQF_SHARED, dev->name, dev); - if (ret) return ret; + if (ret) + return ret; - load_csrs (lp); - lance_init_ring (dev); + load_csrs(lp); + lance_init_ring(dev); netif_start_queue(dev); - return init_restart_lance (lp); + return init_restart_lance(lp); } -static int lance_close (struct net_device *dev) +static int lance_close(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; @@ -507,7 +499,7 @@ static int lance_close (struct net_device *dev) return 0; } -static inline int lance_reset (struct net_device *dev) +static inline int lance_reset(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; @@ -517,16 +509,15 @@ static inline int lance_reset (struct net_device *dev) ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; - load_csrs (lp); + load_csrs(lp); - lance_init_ring (dev); + lance_init_ring(dev); dev->trans_start = jiffies; /* prevent tx timeout */ netif_start_queue(dev); - status = init_restart_lance (lp); -#ifdef DEBUG_DRIVER - printk(KERN_DEBUG "Lance restart=%d\n", status); -#endif + status = init_restart_lance(lp); + netdev_dbg(dev, "Lance restart=%d\n", status); + return status; } @@ -535,14 +526,13 @@ static void lance_tx_timeout(struct net_device *dev) struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; - printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n", - dev->name, ll->rdp); + netdev_err(dev, "transmit timed out, status %04x, reset\n", ll->rdp); lance_reset(dev); netif_wake_queue(dev); } -static netdev_tx_t lance_start_xmit (struct sk_buff *skb, - struct net_device *dev) +static netdev_tx_t lance_start_xmit(struct sk_buff *skb, + struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; @@ -557,33 +547,33 @@ static netdev_tx_t lance_start_xmit (struct sk_buff *skb, local_irq_save(flags); - if (!TX_BUFFS_AVAIL){ + if (!lance_tx_buffs_avail(lp)) { local_irq_restore(flags); return NETDEV_TX_LOCKED; } -#ifdef DEBUG_DRIVER +#ifdef DEBUG /* dump the packet */ print_hex_dump(KERN_DEBUG, "skb->data: ", DUMP_PREFIX_NONE, 16, 1, skb->data, 64, true); #endif entry = lp->tx_new & lp->tx_ring_mod_mask; - ib->btx_ring [entry].length = (-skblen) | 0xf000; - ib->btx_ring [entry].misc = 0; + ib->btx_ring[entry].length = (-skblen) | 0xf000; + ib->btx_ring[entry].misc = 0; - skb_copy_from_linear_data(skb, (void *)&ib->tx_buf [entry][0], skblen); + skb_copy_from_linear_data(skb, (void *)&ib->tx_buf[entry][0], skblen); /* Now, give the packet to the lance */ - ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN); + ib->btx_ring[entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN); lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask; dev->stats.tx_bytes += skblen; - if (TX_BUFFS_AVAIL <= 0) + if (lance_tx_buffs_avail(lp) <= 0) netif_stop_queue(dev); /* Kick the lance: transmit now */ ll->rdp = LE_C0_INEA | LE_C0_TDMD; - dev_kfree_skb (skb); + dev_kfree_skb(skb); local_irq_restore(flags); @@ -591,7 +581,7 @@ static netdev_tx_t lance_start_xmit (struct sk_buff *skb, } /* taken from the depca driver */ -static void lance_load_multicast (struct net_device *dev) +static void lance_load_multicast(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; @@ -601,14 +591,14 @@ static void lance_load_multicast (struct net_device *dev) u32 crc; /* set all multicast bits */ - if (dev->flags & IFF_ALLMULTI){ - ib->filter [0] = 0xffffffff; - ib->filter [1] = 0xffffffff; + if (dev->flags & IFF_ALLMULTI) { + ib->filter[0] = 0xffffffff; + ib->filter[1] = 0xffffffff; return; } /* clear the multicast filter */ - ib->filter [0] = 0; - ib->filter [1] = 0; + ib->filter[0] = 0; + ib->filter[1] = 0; /* Add addresses */ netdev_for_each_mc_addr(ha, dev) { @@ -620,11 +610,11 @@ static void lance_load_multicast (struct net_device *dev) crc = ether_crc_le(6, addrs); crc = crc >> 26; - mcast_table [crc >> 4] |= 1 << (crc & 0xf); + mcast_table[crc >> 4] |= 1 << (crc & 0xf); } } -static void lance_set_multicast (struct net_device *dev) +static void lance_set_multicast(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; @@ -643,16 +633,16 @@ static void lance_set_multicast (struct net_device *dev) ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; - lance_init_ring (dev); + lance_init_ring(dev); if (dev->flags & IFF_PROMISC) { ib->mode |= LE_MO_PROM; } else { ib->mode &= ~LE_MO_PROM; - lance_load_multicast (dev); + lance_load_multicast(dev); } - load_csrs (lp); - init_restart_lance (lp); + load_csrs(lp); + init_restart_lance(lp); netif_wake_queue(dev); } @@ -692,14 +682,12 @@ static int __devinit a2065_init_one(struct zorro_dev *z, { struct net_device *dev; struct lance_private *priv; - unsigned long board, base_addr, mem_start; + unsigned long board = z->resource.start; + unsigned long base_addr = board + A2065_LANCE; + unsigned long mem_start = board + A2065_RAM; struct resource *r1, *r2; int err; - board = z->resource.start; - base_addr = board+A2065_LANCE; - mem_start = board+A2065_RAM; - r1 = request_mem_region(base_addr, sizeof(struct lance_regs), "Am7990"); if (!r1) @@ -730,12 +718,12 @@ static int __devinit a2065_init_one(struct zorro_dev *z, dev->dev_addr[1] = 0x00; dev->dev_addr[2] = 0x9f; } - dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff; - dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff; + dev->dev_addr[3] = (z->rom.er_SerialNumber >> 16) & 0xff; + dev->dev_addr[4] = (z->rom.er_SerialNumber >> 8) & 0xff; dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff; dev->base_addr = ZTWO_VADDR(base_addr); dev->mem_start = ZTWO_VADDR(mem_start); - dev->mem_end = dev->mem_start+A2065_RAM_SIZE; + dev->mem_end = dev->mem_start + A2065_RAM_SIZE; priv->ll = (volatile struct lance_regs *)dev->base_addr; priv->init_block = (struct lance_init_block *)dev->mem_start; @@ -755,7 +743,7 @@ static int __devinit a2065_init_one(struct zorro_dev *z, init_timer(&priv->multicast_timer); priv->multicast_timer.data = (unsigned long) dev; priv->multicast_timer.function = - (void (*)(unsigned long)) &lance_set_multicast; + (void (*)(unsigned long))lance_set_multicast; err = register_netdev(dev); if (err) { @@ -766,8 +754,8 @@ static int __devinit a2065_init_one(struct zorro_dev *z, } zorro_set_drvdata(z, dev); - printk(KERN_INFO "%s: A2065 at 0x%08lx, Ethernet Address " - "%pM\n", dev->name, board, dev->dev_addr); + netdev_info(dev, "A2065 at 0x%08lx, Ethernet Address %pM\n", + board, dev->dev_addr); return 0; } -- cgit v1.2.3-70-g09d2 From 840f63933983a1d873c5b2f85d2e169bb94e3c19 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:38:55 +0000 Subject: lib8390: Use pr_ and netdev_ Use the current logging styles. Signed-off-by: Joe Perches Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/lib8390.c | 86 +++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index 70eb2077bd2..59d5414eb45 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -267,9 +267,10 @@ static void __ei_tx_timeout(struct net_device *dev) isr = ei_inb(e8390_base+EN0_ISR); spin_unlock_irqrestore(&ei_local->page_lock, flags); - printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", - dev->name, (txsr & ENTSR_ABT) ? "excess collisions." : - (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); + netdev_dbg(dev, "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d\n", + (txsr & ENTSR_ABT) ? "excess collisions." : + (isr) ? "lost interrupt?" : "cable problem?", + txsr, isr, tickssofar); if (!isr && !dev->stats.tx_packets) { @@ -349,22 +350,22 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, output_page = ei_local->tx_start_page; ei_local->tx1 = send_length; if (ei_debug && ei_local->tx2 > 0) - printk(KERN_DEBUG "%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n", - dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing); + netdev_dbg(dev, "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", + ei_local->tx2, ei_local->lasttx, ei_local->txing); } else if (ei_local->tx2 == 0) { output_page = ei_local->tx_start_page + TX_PAGES/2; ei_local->tx2 = send_length; if (ei_debug && ei_local->tx1 > 0) - printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n", - dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing); + netdev_dbg(dev, "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", + ei_local->tx1, ei_local->lasttx, ei_local->txing); } else { /* We should never get here. */ if (ei_debug) - printk(KERN_DEBUG "%s: No Tx buffers free! tx1=%d tx2=%d last=%d\n", - dev->name, ei_local->tx1, ei_local->tx2, ei_local->lasttx); + netdev_dbg(dev, "No Tx buffers free! tx1=%d tx2=%d last=%d\n", + ei_local->tx1, ei_local->tx2, ei_local->lasttx); ei_local->irqlock = 0; netif_stop_queue(dev); ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); @@ -448,9 +449,8 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) * This might just be an interrupt for a PCI device sharing * this line */ - printk("%s: Interrupted while interrupts are masked!" - " isr=%#2x imr=%#2x.\n", - dev->name, ei_inb_p(e8390_base + EN0_ISR), + netdev_err(dev, "Interrupted while interrupts are masked! isr=%#2x imr=%#2x\n", + ei_inb_p(e8390_base + EN0_ISR), ei_inb_p(e8390_base + EN0_IMR)); spin_unlock(&ei_local->page_lock); return IRQ_NONE; @@ -459,7 +459,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) /* Change to page 0 and read the intr status reg. */ ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); if (ei_debug > 3) - printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name, + netdev_dbg(dev, "interrupt(isr=%#2.2x)\n", ei_inb_p(e8390_base + EN0_ISR)); /* !!Assumption!! -- we stay in page 0. Don't break this. */ @@ -467,7 +467,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) ++nr_serviced < MAX_SERVICE) { if (!netif_running(dev)) { - printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name); + netdev_warn(dev, "interrupt from stopped card\n"); /* rmk - acknowledge the interrupts */ ei_outb_p(interrupts, e8390_base + EN0_ISR); interrupts = 0; @@ -510,11 +510,11 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) { /* 0xFF is valid for a card removal */ if(interrupts!=0xFF) - printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n", - dev->name, interrupts); + netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", + interrupts); ei_outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ } else { - printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts); + netdev_warn(dev, "unknown interrupt %#2x\n", interrupts); ei_outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ } } @@ -554,18 +554,18 @@ static void ei_tx_err(struct net_device *dev) unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); #ifdef VERBOSE_ERROR_DUMP - printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr); + netdev_dbg(dev, "transmitter error (%#2x):", txsr); if (txsr & ENTSR_ABT) - printk("excess-collisions "); + pr_cont(" excess-collisions "); if (txsr & ENTSR_ND) - printk("non-deferral "); + pr_cont(" non-deferral "); if (txsr & ENTSR_CRS) - printk("lost-carrier "); + pr_cont(" lost-carrier "); if (txsr & ENTSR_FU) - printk("FIFO-underrun "); + pr_cont(" FIFO-underrun "); if (txsr & ENTSR_CDH) - printk("lost-heartbeat "); - printk("\n"); + pr_cont(" lost-heartbeat "); + pr_cont("\n"); #endif ei_outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */ @@ -606,8 +606,8 @@ static void ei_tx_intr(struct net_device *dev) if (ei_local->tx1 < 0) { if (ei_local->lasttx != 1 && ei_local->lasttx != -1) - printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n", - ei_local->name, ei_local->lasttx, ei_local->tx1); + pr_err("%s: bogus last_tx_buffer %d, tx1=%d\n", + ei_local->name, ei_local->lasttx, ei_local->tx1); ei_local->tx1 = 0; if (ei_local->tx2 > 0) { @@ -622,8 +622,8 @@ static void ei_tx_intr(struct net_device *dev) else if (ei_local->tx2 < 0) { if (ei_local->lasttx != 2 && ei_local->lasttx != -2) - printk("%s: bogus last_tx_buffer %d, tx2=%d.\n", - ei_local->name, ei_local->lasttx, ei_local->tx2); + pr_err("%s: bogus last_tx_buffer %d, tx2=%d\n", + ei_local->name, ei_local->lasttx, ei_local->tx2); ei_local->tx2 = 0; if (ei_local->tx1 > 0) { @@ -703,8 +703,8 @@ static void ei_receive(struct net_device *dev) is that some clones crash in roughly the same way. */ if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF)) - printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n", - dev->name, this_frame, ei_local->current_page); + netdev_err(dev, "mismatched read page pointers %2x vs %2x\n", + this_frame, ei_local->current_page); if (this_frame == rxing_page) /* Read all the frames? */ break; /* Done for now */ @@ -733,8 +733,8 @@ static void ei_receive(struct net_device *dev) if (pkt_len < 60 || pkt_len > 1518) { if (ei_debug) - printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n", - dev->name, rx_frame.count, rx_frame.status, + netdev_dbg(dev, "bogus packet size: %d, status=%#2x nxpg=%#2x\n", + rx_frame.count, rx_frame.status, rx_frame.next); dev->stats.rx_errors++; dev->stats.rx_length_errors++; @@ -747,8 +747,8 @@ static void ei_receive(struct net_device *dev) if (skb == NULL) { if (ei_debug > 1) - printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n", - dev->name, pkt_len); + netdev_dbg(dev, "Couldn't allocate a sk_buff of size %d\n", + pkt_len); dev->stats.rx_dropped++; break; } @@ -769,8 +769,8 @@ static void ei_receive(struct net_device *dev) else { if (ei_debug) - printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n", - dev->name, rx_frame.status, rx_frame.next, + netdev_dbg(dev, "bogus packet: status=%#2x nxpg=%#2x size=%d\n", + rx_frame.status, rx_frame.next, rx_frame.count); dev->stats.rx_errors++; /* NB: The NIC counts CRC, frame and missed errors. */ @@ -781,8 +781,8 @@ static void ei_receive(struct net_device *dev) /* This _should_ never happen: it's here for avoiding bad clones. */ if (next_frame >= ei_local->stop_page) { - printk("%s: next frame inconsistency, %#2x\n", dev->name, - next_frame); + netdev_notice(dev, "next frame inconsistency, %#2x\n", + next_frame); next_frame = ei_local->rx_start_page; } ei_local->current_page = next_frame; @@ -822,7 +822,7 @@ static void ei_rx_overrun(struct net_device *dev) ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); if (ei_debug > 1) - printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name); + netdev_dbg(dev, "Receiver overrun\n"); dev->stats.rx_over_errors++; /* @@ -960,7 +960,8 @@ static void do_set_multicast_list(struct net_device *dev) ei_outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); #ifndef BUG_83C690 if(ei_inb_p(e8390_base + EN1_MULT_SHIFT(i))!=ei_local->mcfilter[i]) - printk(KERN_ERR "Multicast filter read/write mismap %d\n",i); + netdev_err(dev, "Multicast filter read/write mismap %d\n", + i); #endif } ei_outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); @@ -1072,7 +1073,7 @@ static void __NS8390_init(struct net_device *dev, int startp) { ei_outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); if (ei_debug > 1 && ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) - printk(KERN_ERR "Hw. address read/write mismap %d\n",i); + netdev_err(dev, "Hw. address read/write mismap %d\n", i); } ei_outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); @@ -1106,8 +1107,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, if (ei_inb_p(e8390_base + E8390_CMD) & E8390_TRANS) { - printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n", - dev->name); + netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); return; } ei_outb_p(length & 0xff, e8390_base + EN0_TCNTLO); -- cgit v1.2.3-70-g09d2 From 7340c4db810f3b129fc4dd648991ed5ca5346592 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:38:56 +0000 Subject: lib8390: Indent braces appropriately Move the braces around to conform to kernel standard style. Signed-off-by: Joe Perches Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/lib8390.c | 119 ++++++++++++++++---------------------------------- 1 file changed, 38 insertions(+), 81 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index 59d5414eb45..9ace5a746f7 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -272,8 +272,7 @@ static void __ei_tx_timeout(struct net_device *dev) (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); - if (!isr && !dev->stats.tx_packets) - { + if (!isr && !dev->stats.tx_packets) { /* The 8390 probably hasn't gotten on the cable yet. */ ei_local->interface_num ^= 1; /* Try a different xcvr. */ } @@ -345,24 +344,19 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, * card, leaving a substantial gap between each transmitted packet. */ - if (ei_local->tx1 == 0) - { + if (ei_local->tx1 == 0) { output_page = ei_local->tx_start_page; ei_local->tx1 = send_length; if (ei_debug && ei_local->tx2 > 0) netdev_dbg(dev, "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", ei_local->tx2, ei_local->lasttx, ei_local->txing); - } - else if (ei_local->tx2 == 0) - { + } else if (ei_local->tx2 == 0) { output_page = ei_local->tx_start_page + TX_PAGES/2; ei_local->tx2 = send_length; if (ei_debug && ei_local->tx1 > 0) netdev_dbg(dev, "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", ei_local->tx1, ei_local->lasttx, ei_local->txing); - } - else - { /* We should never get here. */ + } else { /* We should never get here. */ if (ei_debug) netdev_dbg(dev, "No Tx buffers free! tx1=%d tx2=%d last=%d\n", ei_local->tx1, ei_local->tx2, ei_local->lasttx); @@ -383,22 +377,18 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, ei_block_output(dev, send_length, data, output_page); - if (! ei_local->txing) - { + if (! ei_local->txing) { ei_local->txing = 1; NS8390_trigger_send(dev, send_length, output_page); - if (output_page == ei_local->tx_start_page) - { + if (output_page == ei_local->tx_start_page) { ei_local->tx1 = -1; ei_local->lasttx = -1; - } - else - { + } else { ei_local->tx2 = -1; ei_local->lasttx = -2; } - } - else ei_local->txqueue++; + } else + ei_local->txqueue++; if (ei_local->tx1 && ei_local->tx2) netif_stop_queue(dev); @@ -443,8 +433,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) spin_lock(&ei_local->page_lock); - if (ei_local->irqlock) - { + if (ei_local->irqlock) { /* * This might just be an interrupt for a PCI device sharing * this line @@ -464,8 +453,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) /* !!Assumption!! -- we stay in page 0. Don't break this. */ while ((interrupts = ei_inb_p(e8390_base + EN0_ISR)) != 0 && - ++nr_serviced < MAX_SERVICE) - { + ++nr_serviced < MAX_SERVICE) { if (!netif_running(dev)) { netdev_warn(dev, "interrupt from stopped card\n"); /* rmk - acknowledge the interrupts */ @@ -475,8 +463,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) } if (interrupts & ENISR_OVER) ei_rx_overrun(dev); - else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) - { + else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) { /* Got a good (?) packet. */ ei_receive(dev); } @@ -486,8 +473,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) else if (interrupts & ENISR_TX_ERR) ei_tx_err(dev); - if (interrupts & ENISR_COUNTERS) - { + if (interrupts & ENISR_COUNTERS) { dev->stats.rx_frame_errors += ei_inb_p(e8390_base + EN0_COUNTER0); dev->stats.rx_crc_errors += ei_inb_p(e8390_base + EN0_COUNTER1); dev->stats.rx_missed_errors+= ei_inb_p(e8390_base + EN0_COUNTER2); @@ -496,18 +482,14 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) /* Ignore any RDC interrupts that make it back to here. */ if (interrupts & ENISR_RDC) - { ei_outb_p(ENISR_RDC, e8390_base + EN0_ISR); - } ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); } - if (interrupts && ei_debug) - { + if (interrupts && ei_debug) { ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); - if (nr_serviced >= MAX_SERVICE) - { + if (nr_serviced >= MAX_SERVICE) { /* 0xFF is valid for a card removal */ if(interrupts!=0xFF) netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", @@ -572,8 +554,7 @@ static void ei_tx_err(struct net_device *dev) if (tx_was_aborted) ei_tx_intr(dev); - else - { + else { dev->stats.tx_errors++; if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++; if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++; @@ -603,37 +584,31 @@ static void ei_tx_intr(struct net_device *dev) */ ei_local->txqueue--; - if (ei_local->tx1 < 0) - { + if (ei_local->tx1 < 0) { if (ei_local->lasttx != 1 && ei_local->lasttx != -1) pr_err("%s: bogus last_tx_buffer %d, tx1=%d\n", ei_local->name, ei_local->lasttx, ei_local->tx1); ei_local->tx1 = 0; - if (ei_local->tx2 > 0) - { + if (ei_local->tx2 > 0) { ei_local->txing = 1; NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6); dev->trans_start = jiffies; ei_local->tx2 = -1, ei_local->lasttx = 2; - } - else ei_local->lasttx = 20, ei_local->txing = 0; - } - else if (ei_local->tx2 < 0) - { + } else + ei_local->lasttx = 20, ei_local->txing = 0; + } else if (ei_local->tx2 < 0) { if (ei_local->lasttx != 2 && ei_local->lasttx != -2) pr_err("%s: bogus last_tx_buffer %d, tx2=%d\n", ei_local->name, ei_local->lasttx, ei_local->tx2); ei_local->tx2 = 0; - if (ei_local->tx1 > 0) - { + if (ei_local->tx1 > 0) { ei_local->txing = 1; NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page); dev->trans_start = jiffies; ei_local->tx1 = -1; ei_local->lasttx = 1; - } - else + } else ei_local->lasttx = 10, ei_local->txing = 0; } // else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n", @@ -644,11 +619,9 @@ static void ei_tx_intr(struct net_device *dev) dev->stats.collisions++; if (status & ENTSR_PTX) dev->stats.tx_packets++; - else - { + else { dev->stats.tx_errors++; - if (status & ENTSR_ABT) - { + if (status & ENTSR_ABT) { dev->stats.tx_aborted_errors++; dev->stats.collisions += 16; } @@ -682,8 +655,7 @@ static void ei_receive(struct net_device *dev) struct e8390_pkt_hdr rx_frame; int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page; - while (++rx_pkt_count < 10) - { + while (++rx_pkt_count < 10) { int pkt_len, pkt_stat; /* Get the rx page (incoming packet pointer). */ @@ -730,30 +702,24 @@ static void ei_receive(struct net_device *dev) continue; } - if (pkt_len < 60 || pkt_len > 1518) - { + if (pkt_len < 60 || pkt_len > 1518) { if (ei_debug) netdev_dbg(dev, "bogus packet size: %d, status=%#2x nxpg=%#2x\n", rx_frame.count, rx_frame.status, rx_frame.next); dev->stats.rx_errors++; dev->stats.rx_length_errors++; - } - else if ((pkt_stat & 0x0F) == ENRSR_RXOK) - { + } else if ((pkt_stat & 0x0F) == ENRSR_RXOK) { struct sk_buff *skb; skb = dev_alloc_skb(pkt_len+2); - if (skb == NULL) - { + if (skb == NULL) { if (ei_debug > 1) netdev_dbg(dev, "Couldn't allocate a sk_buff of size %d\n", pkt_len); dev->stats.rx_dropped++; break; - } - else - { + } else { skb_reserve(skb,2); /* IP headers on 16 byte boundaries */ skb_put(skb, pkt_len); /* Make room */ ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); @@ -765,9 +731,7 @@ static void ei_receive(struct net_device *dev) if (pkt_stat & ENRSR_PHY) dev->stats.multicast++; } - } - else - { + } else { if (ei_debug) netdev_dbg(dev, "bogus packet: status=%#2x nxpg=%#2x size=%d\n", rx_frame.status, rx_frame.next, @@ -845,8 +809,7 @@ static void ei_rx_overrun(struct net_device *dev) * step is vital, and skipping it will cause no end of havoc. */ - if (was_txing) - { + if (was_txing) { unsigned char tx_completed = ei_inb_p(e8390_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR); if (!tx_completed) must_resend = 1; @@ -930,13 +893,11 @@ static void do_set_multicast_list(struct net_device *dev) int i; struct ei_device *ei_local = netdev_priv(dev); - if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) - { + if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { memset(ei_local->mcfilter, 0, 8); if (!netdev_mc_empty(dev)) make_mc_bits(ei_local->mcfilter, dev); - } - else + } else memset(ei_local->mcfilter, 0xFF, 8); /* mcast set to accept-all */ /* @@ -955,8 +916,7 @@ static void do_set_multicast_list(struct net_device *dev) if (netif_running(dev)) ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); ei_outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); - for(i = 0; i < 8; i++) - { + for(i = 0; i < 8; i++) { ei_outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); #ifndef BUG_83C690 if(ei_inb_p(e8390_base + EN1_MULT_SHIFT(i))!=ei_local->mcfilter[i]) @@ -1069,8 +1029,7 @@ static void __NS8390_init(struct net_device *dev, int startp) /* Copy the station address into the DS8390 registers. */ ei_outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */ - for(i = 0; i < 6; i++) - { + for(i = 0; i < 6; i++) { ei_outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); if (ei_debug > 1 && ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) netdev_err(dev, "Hw. address read/write mismap %d\n", i); @@ -1082,8 +1041,7 @@ static void __NS8390_init(struct net_device *dev, int startp) ei_local->tx1 = ei_local->tx2 = 0; ei_local->txing = 0; - if (startp) - { + if (startp) { ei_outb_p(0xff, e8390_base + EN0_ISR); ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); @@ -1105,8 +1063,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); - if (ei_inb_p(e8390_base + E8390_CMD) & E8390_TRANS) - { + if (ei_inb_p(e8390_base + E8390_CMD) & E8390_TRANS) { netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); return; } -- cgit v1.2.3-70-g09d2 From be763c940fc3ccdaeda238e3ef5840961b649740 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:38:57 +0000 Subject: lib8390: Normalize source code spacing Make more conformant to normal kernel style. Long line lengths > 80 columns ignored. Signed-off-by: Joe Perches Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/lib8390.c | 81 ++++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 37 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index 9ace5a746f7..b0ee6f67061 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -36,7 +36,7 @@ Paul Gortmaker : tweak ANK's above multicast changes a bit. Paul Gortmaker : update packet statistics for v2.1.x Alan Cox : support arbitrary stupid port mappings on the - 68K Macintosh. Support >16bit I/O spaces + 68K Macintosh. Support >16bit I/O spaces Paul Gortmaker : add kmod support for auto-loading of the 8390 module by all drivers that require it. Alan Cox : Spinlocking work, added 'BUG_83C690' @@ -206,19 +206,19 @@ static int __ei_open(struct net_device *dev) struct ei_device *ei_local = netdev_priv(dev); if (dev->watchdog_timeo <= 0) - dev->watchdog_timeo = TX_TIMEOUT; + dev->watchdog_timeo = TX_TIMEOUT; /* * Grab the page lock so we own the register set, then call * the init function. */ - spin_lock_irqsave(&ei_local->page_lock, flags); + spin_lock_irqsave(&ei_local->page_lock, flags); __NS8390_init(dev, 1); /* Set the flag before we drop the lock, That way the IRQ arrives after its set and we get no silly warnings */ netif_start_queue(dev); - spin_unlock_irqrestore(&ei_local->page_lock, flags); + spin_unlock_irqrestore(&ei_local->page_lock, flags); ei_local->irqlock = 0; return 0; } @@ -238,9 +238,9 @@ static int __ei_close(struct net_device *dev) * Hold the page lock during close */ - spin_lock_irqsave(&ei_local->page_lock, flags); + spin_lock_irqsave(&ei_local->page_lock, flags); __NS8390_init(dev, 0); - spin_unlock_irqrestore(&ei_local->page_lock, flags); + spin_unlock_irqrestore(&ei_local->page_lock, flags); netif_stop_queue(dev); return 0; } @@ -377,7 +377,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, ei_block_output(dev, send_length, data, output_page); - if (! ei_local->txing) { + if (!ei_local->txing) { ei_local->txing = 1; NS8390_trigger_send(dev, send_length, output_page); if (output_page == ei_local->tx_start_page) { @@ -402,7 +402,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, spin_unlock(&ei_local->page_lock); enable_irq_lockdep_irqrestore(dev->irq, &flags); skb_tx_timestamp(skb); - dev_kfree_skb (skb); + dev_kfree_skb(skb); dev->stats.tx_bytes += send_length; return NETDEV_TX_OK; @@ -476,7 +476,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) if (interrupts & ENISR_COUNTERS) { dev->stats.rx_frame_errors += ei_inb_p(e8390_base + EN0_COUNTER0); dev->stats.rx_crc_errors += ei_inb_p(e8390_base + EN0_COUNTER1); - dev->stats.rx_missed_errors+= ei_inb_p(e8390_base + EN0_COUNTER2); + dev->stats.rx_missed_errors += ei_inb_p(e8390_base + EN0_COUNTER2); ei_outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */ } @@ -491,7 +491,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id) ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); if (nr_serviced >= MAX_SERVICE) { /* 0xFF is valid for a card removal */ - if(interrupts!=0xFF) + if (interrupts != 0xFF) netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", interrupts); ei_outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ @@ -556,9 +556,12 @@ static void ei_tx_err(struct net_device *dev) ei_tx_intr(dev); else { dev->stats.tx_errors++; - if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++; - if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++; - if (txsr & ENTSR_OWC) dev->stats.tx_window_errors++; + if (txsr & ENTSR_CRS) + dev->stats.tx_carrier_errors++; + if (txsr & ENTSR_CDH) + dev->stats.tx_heartbeat_errors++; + if (txsr & ENTSR_OWC) + dev->stats.tx_window_errors++; } } @@ -610,9 +613,10 @@ static void ei_tx_intr(struct net_device *dev) ei_local->lasttx = 1; } else ei_local->lasttx = 10, ei_local->txing = 0; - } -// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n", -// dev->name, ei_local->lasttx); + } /* else + netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n", + ei_local->lasttx); +*/ /* Minimize Tx latency: update the statistics after we restart TXing. */ if (status & ENTSR_COL) @@ -674,7 +678,9 @@ static void ei_receive(struct net_device *dev) Keep quiet if it looks like a card removal. One problem here is that some clones crash in roughly the same way. */ - if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF)) + if (ei_debug > 0 && + this_frame != ei_local->current_page && + (this_frame != 0x0 || rxing_page != 0xFF)) netdev_err(dev, "mismatched read page pointers %2x vs %2x\n", this_frame, ei_local->current_page); @@ -720,10 +726,10 @@ static void ei_receive(struct net_device *dev) dev->stats.rx_dropped++; break; } else { - skb_reserve(skb,2); /* IP headers on 16 byte boundaries */ + skb_reserve(skb, 2); /* IP headers on 16 byte boundaries */ skb_put(skb, pkt_len); /* Make room */ ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); - skb->protocol=eth_type_trans(skb,dev); + skb->protocol = eth_type_trans(skb, dev); if (!skb_defer_rx_timestamp(skb)) netif_rx(skb); dev->stats.rx_packets++; @@ -833,7 +839,7 @@ static void ei_rx_overrun(struct net_device *dev) */ ei_outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); if (must_resend) - ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); + ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); } /* @@ -850,11 +856,11 @@ static struct net_device_stats *__ei_get_stats(struct net_device *dev) if (!netif_running(dev)) return &dev->stats; - spin_lock_irqsave(&ei_local->page_lock,flags); + spin_lock_irqsave(&ei_local->page_lock, flags); /* Read the counter registers, assuming we are in page 0. */ - dev->stats.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0); - dev->stats.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1); - dev->stats.rx_missed_errors+= ei_inb_p(ioaddr + EN0_COUNTER2); + dev->stats.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0); + dev->stats.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1); + dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2); spin_unlock_irqrestore(&ei_local->page_lock, flags); return &dev->stats; @@ -916,23 +922,23 @@ static void do_set_multicast_list(struct net_device *dev) if (netif_running(dev)) ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); ei_outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); - for(i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { ei_outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); #ifndef BUG_83C690 - if(ei_inb_p(e8390_base + EN1_MULT_SHIFT(i))!=ei_local->mcfilter[i]) + if (ei_inb_p(e8390_base + EN1_MULT_SHIFT(i)) != ei_local->mcfilter[i]) netdev_err(dev, "Multicast filter read/write mismap %d\n", i); #endif } ei_outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); - if(dev->flags&IFF_PROMISC) - ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR); + if (dev->flags&IFF_PROMISC) + ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR); else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) - ei_outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR); - else - ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); - } + ei_outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR); + else + ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); +} /* * Called without lock held. This is invoked from user context and may @@ -1004,8 +1010,8 @@ static void __NS8390_init(struct net_device *dev, int startp) ? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0)) : 0x48; - if(sizeof(struct e8390_pkt_hdr)!=4) - panic("8390.c: header struct mispacked\n"); + if (sizeof(struct e8390_pkt_hdr) != 4) + panic("8390.c: header struct mispacked\n"); /* Follow National Semi's recommendations for initing the DP83902. */ ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); /* 0x21 */ ei_outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */ @@ -1029,9 +1035,10 @@ static void __NS8390_init(struct net_device *dev, int startp) /* Copy the station address into the DS8390 registers. */ ei_outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */ - for(i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) { ei_outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); - if (ei_debug > 1 && ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) + if (ei_debug > 1 && + ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i)) != dev->dev_addr[i]) netdev_err(dev, "Hw. address read/write mismap %d\n", i); } @@ -1059,7 +1066,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); + struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); -- cgit v1.2.3-70-g09d2 From 5aedcf50e547e37b89d105efc4a2f0f1b0217af4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:38:58 +0000 Subject: lib8390: Convert include Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/lib8390.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index b0ee6f67061..946b255a78f 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -58,8 +58,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From 3c01164e80a11fe2743cc36a0f2915673f1cac74 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:38:59 +0000 Subject: lib8390: Remove unnecessary extern Already declared in 8390.h Signed-off-by: Joe Perches Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/lib8390.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index 946b255a78f..05ae21435bf 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -108,7 +108,6 @@ int ei_debug = 1; /* Index to functions. */ static void ei_tx_intr(struct net_device *dev); static void ei_tx_err(struct net_device *dev); -void ei_tx_timeout(struct net_device *dev); static void ei_receive(struct net_device *dev); static void ei_rx_overrun(struct net_device *dev); -- cgit v1.2.3-70-g09d2 From 572404ea6bcbfaeb84b9522b46c35f5a5db15392 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 22 Jun 2011 20:39:00 +0000 Subject: zorro8390: Update style, neaten, restructure to eliminate prototypes Convert to current logging styles. Move code blocks to eliminate need for prototypes. Use tabs for code indent and standardize spacing. Comment neatening. Signed-off-by: Joe Perches Acked-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/zorro8390.c | 673 ++++++++++++++++++++++++------------------------ 1 file changed, 333 insertions(+), 340 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c index 8c7c522a056..15e7751a273 100644 --- a/drivers/net/zorro8390.c +++ b/drivers/net/zorro8390.c @@ -19,6 +19,8 @@ * Ethernet Controllers. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -34,115 +36,242 @@ #include #include -#define EI_SHIFT(x) (ei_local->reg_offset[x]) -#define ei_inb(port) in_8(port) -#define ei_outb(val,port) out_8(port,val) -#define ei_inb_p(port) in_8(port) -#define ei_outb_p(val,port) out_8(port,val) +#define EI_SHIFT(x) (ei_local->reg_offset[x]) +#define ei_inb(port) in_8(port) +#define ei_outb(val, port) out_8(port, val) +#define ei_inb_p(port) in_8(port) +#define ei_outb_p(val, port) out_8(port, val) static const char version[] = - "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; + "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; #include "lib8390.c" #define DRV_NAME "zorro8390" #define NE_BASE (dev->base_addr) -#define NE_CMD (0x00*2) -#define NE_DATAPORT (0x10*2) /* NatSemi-defined port window offset. */ -#define NE_RESET (0x1f*2) /* Issue a read to reset, a write to clear. */ -#define NE_IO_EXTENT (0x20*2) - -#define NE_EN0_ISR (0x07*2) -#define NE_EN0_DCFG (0x0e*2) - -#define NE_EN0_RSARLO (0x08*2) -#define NE_EN0_RSARHI (0x09*2) -#define NE_EN0_RCNTLO (0x0a*2) -#define NE_EN0_RXCR (0x0c*2) -#define NE_EN0_TXCR (0x0d*2) -#define NE_EN0_RCNTHI (0x0b*2) -#define NE_EN0_IMR (0x0f*2) +#define NE_CMD (0x00 * 2) +#define NE_DATAPORT (0x10 * 2) /* NatSemi-defined port window offset */ +#define NE_RESET (0x1f * 2) /* Issue a read to reset, + * a write to clear. */ +#define NE_IO_EXTENT (0x20 * 2) + +#define NE_EN0_ISR (0x07 * 2) +#define NE_EN0_DCFG (0x0e * 2) + +#define NE_EN0_RSARLO (0x08 * 2) +#define NE_EN0_RSARHI (0x09 * 2) +#define NE_EN0_RCNTLO (0x0a * 2) +#define NE_EN0_RXCR (0x0c * 2) +#define NE_EN0_TXCR (0x0d * 2) +#define NE_EN0_RCNTHI (0x0b * 2) +#define NE_EN0_IMR (0x0f * 2) #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ - -#define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) - +#define WORDSWAP(a) ((((a) >> 8) & 0xff) | ((a) << 8)) static struct card_info { - zorro_id id; - const char *name; - unsigned int offset; + zorro_id id; + const char *name; + unsigned int offset; } cards[] __devinitdata = { - { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 }, - { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 }, + { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 }, + { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 }, }; -static int __devinit zorro8390_init_one(struct zorro_dev *z, - const struct zorro_device_id *ent); -static int __devinit zorro8390_init(struct net_device *dev, - unsigned long board, const char *name, - unsigned long ioaddr); -static int zorro8390_open(struct net_device *dev); -static int zorro8390_close(struct net_device *dev); -static void zorro8390_reset_8390(struct net_device *dev); +/* Hard reset the card. This used to pause for the same period that a + * 8390 reset command required, but that shouldn't be necessary. + */ +static void zorro8390_reset_8390(struct net_device *dev) +{ + unsigned long reset_start_time = jiffies; + + if (ei_debug > 1) + netdev_dbg(dev, "resetting - t=%ld...\n", jiffies); + + z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); + + ei_status.txing = 0; + ei_status.dmaing = 0; + + /* This check _should_not_ be necessary, omit eventually. */ + while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RESET) == 0) + if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { + netdev_warn(dev, "%s: did not complete\n", __func__); + break; + } + z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr */ +} + +/* Grab the 8390 specific header. Similar to the block_input routine, but + * we don't need to be concerned with ring wrap as the header will be at + * the start of a page, so we optimize accordingly. + */ static void zorro8390_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page); + struct e8390_pkt_hdr *hdr, int ring_page) +{ + int nic_base = dev->base_addr; + int cnt; + short *ptrs; + + /* This *shouldn't* happen. + * If it does, it's the last thing you'll see + */ + if (ei_status.dmaing) { + netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", + __func__, ei_status.dmaing, ei_status.irqlock); + return; + } + + ei_status.dmaing |= 0x01; + z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); + z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); + z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); + z_writeb(0, nic_base + NE_EN0_RCNTHI); + z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ + z_writeb(ring_page, nic_base + NE_EN0_RSARHI); + z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); + + ptrs = (short *)hdr; + for (cnt = 0; cnt < sizeof(struct e8390_pkt_hdr) >> 1; cnt++) + *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); + + z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ + + hdr->count = WORDSWAP(hdr->count); + + ei_status.dmaing &= ~0x01; +} + +/* Block input and output, similar to the Crynwr packet driver. + * If you are porting to a new ethercard, look at the packet driver source + * for hints. The NEx000 doesn't share the on-board packet memory -- + * you have to put the packet out through the "remote DMA" dataport + * using z_writeb. + */ static void zorro8390_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset); -static void zorro8390_block_output(struct net_device *dev, const int count, + struct sk_buff *skb, int ring_offset) +{ + int nic_base = dev->base_addr; + char *buf = skb->data; + short *ptrs; + int cnt; + + /* This *shouldn't* happen. + * If it does, it's the last thing you'll see + */ + if (ei_status.dmaing) { + netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", + __func__, ei_status.dmaing, ei_status.irqlock); + return; + } + ei_status.dmaing |= 0x01; + z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); + z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); + z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); + z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); + z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); + z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); + z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); + ptrs = (short *)buf; + for (cnt = 0; cnt < count >> 1; cnt++) + *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); + if (count & 0x01) + buf[count - 1] = z_readb(NE_BASE + NE_DATAPORT); + + z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ + ei_status.dmaing &= ~0x01; +} + +static void zorro8390_block_output(struct net_device *dev, int count, const unsigned char *buf, - const int start_page); -static void __devexit zorro8390_remove_one(struct zorro_dev *z); + const int start_page) +{ + int nic_base = NE_BASE; + unsigned long dma_start; + short *ptrs; + int cnt; + + /* Round the count up for word writes. Do we need to do this? + * What effect will an odd byte count have on the 8390? + * I should check someday. + */ + if (count & 0x01) + count++; + + /* This *shouldn't* happen. + * If it does, it's the last thing you'll see + */ + if (ei_status.dmaing) { + netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", + __func__, ei_status.dmaing, ei_status.irqlock); + return; + } + ei_status.dmaing |= 0x01; + /* We should already be in page 0, but to be safe... */ + z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); + + z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); + + /* Now the normal output. */ + z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); + z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); + z_writeb(0x00, nic_base + NE_EN0_RSARLO); + z_writeb(start_page, nic_base + NE_EN0_RSARHI); + + z_writeb(E8390_RWRITE + E8390_START, nic_base + NE_CMD); + ptrs = (short *)buf; + for (cnt = 0; cnt < count >> 1; cnt++) + z_writew(*ptrs++, NE_BASE + NE_DATAPORT); + + dma_start = jiffies; + + while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) + if (time_after(jiffies, dma_start + 2 * HZ / 100)) { + /* 20ms */ + netdev_err(dev, "timeout waiting for Tx RDC\n"); + zorro8390_reset_8390(dev); + __NS8390_init(dev, 1); + break; + } + + z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ + ei_status.dmaing &= ~0x01; +} -static struct zorro_device_id zorro8390_zorro_tbl[] __devinitdata = { - { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, }, - { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, }, - { 0 } -}; -MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl); +static int zorro8390_open(struct net_device *dev) +{ + __ei_open(dev); + return 0; +} -static struct zorro_driver zorro8390_driver = { - .name = "zorro8390", - .id_table = zorro8390_zorro_tbl, - .probe = zorro8390_init_one, - .remove = __devexit_p(zorro8390_remove_one), -}; +static int zorro8390_close(struct net_device *dev) +{ + if (ei_debug > 1) + netdev_dbg(dev, "Shutting down ethercard\n"); + __ei_close(dev); + return 0; +} -static int __devinit zorro8390_init_one(struct zorro_dev *z, - const struct zorro_device_id *ent) +static void __devexit zorro8390_remove_one(struct zorro_dev *z) { - struct net_device *dev; - unsigned long board, ioaddr; - int err, i; - - for (i = ARRAY_SIZE(cards)-1; i >= 0; i--) - if (z->id == cards[i].id) - break; - if (i < 0) - return -ENODEV; - - board = z->resource.start; - ioaddr = board+cards[i].offset; - dev = ____alloc_ei_netdev(0); - if (!dev) - return -ENOMEM; - if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, DRV_NAME)) { - free_netdev(dev); - return -EBUSY; - } - if ((err = zorro8390_init(dev, board, cards[i].name, - ZTWO_VADDR(ioaddr)))) { - release_mem_region(ioaddr, NE_IO_EXTENT*2); + struct net_device *dev = zorro_get_drvdata(z); + + unregister_netdev(dev); + free_irq(IRQ_AMIGA_PORTS, dev); + release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT * 2); free_netdev(dev); - return err; - } - zorro_set_drvdata(z, dev); - return 0; } +static struct zorro_device_id zorro8390_zorro_tbl[] __devinitdata = { + { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, }, + { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, }, + { 0 } +}; +MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl); + static const struct net_device_ops zorro8390_netdev_ops = { .ndo_open = zorro8390_open, .ndo_stop = zorro8390_close, @@ -151,7 +280,7 @@ static const struct net_device_ops zorro8390_netdev_ops = { .ndo_get_stats = __ei_get_stats, .ndo_set_multicast_list = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = __ei_poll, @@ -162,295 +291,159 @@ static int __devinit zorro8390_init(struct net_device *dev, unsigned long board, const char *name, unsigned long ioaddr) { - int i; - int err; - unsigned char SA_prom[32]; - int start_page, stop_page; - static u32 zorro8390_offsets[16] = { - 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, - 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, - }; - - /* Reset card. Who knows what dain-bramaged state it was left in. */ - { - unsigned long reset_start_time = jiffies; - - z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); - - while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { - printk(KERN_WARNING " not found (no reset ack).\n"); - return -ENODEV; - } - - z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ - } - - /* Read the 16 bytes of station address PROM. - We must first initialize registers, similar to NS8390_init(eifdev, 0). - We can't reliably read the SAPROM address without this. - (I learned the hard way!). */ - { - struct { - u32 value; - u32 offset; - } program_seq[] = { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/ - {0x48, NE_EN0_DCFG}, /* Set byte-wide (0x48) access. */ - {0x00, NE_EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_IMR}, /* Mask completion irq. */ - {0xFF, NE_EN0_ISR}, - {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, NE_EN0_RCNTLO}, - {0x00, NE_EN0_RCNTHI}, - {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, NE_EN0_RSARHI}, - {E8390_RREAD+E8390_START, NE_CMD}, + int i; + int err; + unsigned char SA_prom[32]; + int start_page, stop_page; + static u32 zorro8390_offsets[16] = { + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, + 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, }; - for (i = 0; i < ARRAY_SIZE(program_seq); i++) { - z_writeb(program_seq[i].value, ioaddr + program_seq[i].offset); - } - } - for (i = 0; i < 16; i++) { - SA_prom[i] = z_readb(ioaddr + NE_DATAPORT); - (void)z_readb(ioaddr + NE_DATAPORT); - } - /* We must set the 8390 for word mode. */ - z_writeb(0x49, ioaddr + NE_EN0_DCFG); - start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; + /* Reset card. Who knows what dain-bramaged state it was left in. */ + { + unsigned long reset_start_time = jiffies; - dev->base_addr = ioaddr; - dev->irq = IRQ_AMIGA_PORTS; + z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); - /* Install the Interrupt handler */ - i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, IRQF_SHARED, DRV_NAME, dev); - if (i) return i; + while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) + if (time_after(jiffies, + reset_start_time + 2 * HZ / 100)) { + netdev_warn(dev, "not found (no reset ack)\n"); + return -ENODEV; + } - for(i = 0; i < ETHER_ADDR_LEN; i++) - dev->dev_addr[i] = SA_prom[i]; - -#ifdef DEBUG - printk("%pM", dev->dev_addr); -#endif + z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ + } - ei_status.name = name; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = 1; + /* Read the 16 bytes of station address PROM. + * We must first initialize registers, + * similar to NS8390_init(eifdev, 0). + * We can't reliably read the SAPROM address without this. + * (I learned the hard way!). + */ + { + static const struct { + u32 value; + u32 offset; + } program_seq[] = { + {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD}, + /* Select page 0 */ + {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */ + {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */ + {0x00, NE_EN0_RCNTHI}, + {0x00, NE_EN0_IMR}, /* Mask completion irq */ + {0xFF, NE_EN0_ISR}, + {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ + {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */ + {32, NE_EN0_RCNTLO}, + {0x00, NE_EN0_RCNTHI}, + {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */ + {0x00, NE_EN0_RSARHI}, + {E8390_RREAD + E8390_START, NE_CMD}, + }; + for (i = 0; i < ARRAY_SIZE(program_seq); i++) + z_writeb(program_seq[i].value, + ioaddr + program_seq[i].offset); + } + for (i = 0; i < 16; i++) { + SA_prom[i] = z_readb(ioaddr + NE_DATAPORT); + (void)z_readb(ioaddr + NE_DATAPORT); + } - ei_status.rx_start_page = start_page + TX_PAGES; + /* We must set the 8390 for word mode. */ + z_writeb(0x49, ioaddr + NE_EN0_DCFG); + start_page = NESM_START_PG; + stop_page = NESM_STOP_PG; - ei_status.reset_8390 = &zorro8390_reset_8390; - ei_status.block_input = &zorro8390_block_input; - ei_status.block_output = &zorro8390_block_output; - ei_status.get_8390_hdr = &zorro8390_get_8390_hdr; - ei_status.reg_offset = zorro8390_offsets; + dev->base_addr = ioaddr; + dev->irq = IRQ_AMIGA_PORTS; - dev->netdev_ops = &zorro8390_netdev_ops; - __NS8390_init(dev, 0); - err = register_netdev(dev); - if (err) { - free_irq(IRQ_AMIGA_PORTS, dev); - return err; - } + /* Install the Interrupt handler */ + i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, + IRQF_SHARED, DRV_NAME, dev); + if (i) + return i; - printk(KERN_INFO "%s: %s at 0x%08lx, Ethernet Address %pM\n", - dev->name, name, board, dev->dev_addr); + for (i = 0; i < ETHER_ADDR_LEN; i++) + dev->dev_addr[i] = SA_prom[i]; - return 0; -} + pr_debug("Found ethernet address: %pM\n", dev->dev_addr); -static int zorro8390_open(struct net_device *dev) -{ - __ei_open(dev); - return 0; -} + ei_status.name = name; + ei_status.tx_start_page = start_page; + ei_status.stop_page = stop_page; + ei_status.word16 = 1; -static int zorro8390_close(struct net_device *dev) -{ - if (ei_debug > 1) - printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); - __ei_close(dev); - return 0; -} + ei_status.rx_start_page = start_page + TX_PAGES; -/* Hard reset the card. This used to pause for the same period that a - 8390 reset command required, but that shouldn't be necessary. */ -static void zorro8390_reset_8390(struct net_device *dev) -{ - unsigned long reset_start_time = jiffies; + ei_status.reset_8390 = zorro8390_reset_8390; + ei_status.block_input = zorro8390_block_input; + ei_status.block_output = zorro8390_block_output; + ei_status.get_8390_hdr = zorro8390_get_8390_hdr; + ei_status.reg_offset = zorro8390_offsets; - if (ei_debug > 1) - printk(KERN_DEBUG "resetting the 8390 t=%ld...\n", jiffies); - - z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); - - ei_status.txing = 0; - ei_status.dmaing = 0; - - /* This check _should_not_ be necessary, omit eventually. */ - while ((z_readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { - printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", - dev->name); - break; + dev->netdev_ops = &zorro8390_netdev_ops; + __NS8390_init(dev, 0); + err = register_netdev(dev); + if (err) { + free_irq(IRQ_AMIGA_PORTS, dev); + return err; } - z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */ -} -/* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ + netdev_info(dev, "%s at 0x%08lx, Ethernet Address %pM\n", + name, board, dev->dev_addr); -static void zorro8390_get_8390_hdr(struct net_device *dev, - struct e8390_pkt_hdr *hdr, int ring_page) -{ - int nic_base = dev->base_addr; - int cnt; - short *ptrs; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - printk(KERN_ERR "%s: DMAing conflict in ne_get_8390_hdr " - "[DMAstat:%d][irqlock:%d].\n", dev->name, ei_status.dmaing, - ei_status.irqlock); - return; - } - - ei_status.dmaing |= 0x01; - z_writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); - z_writeb(0, nic_base + NE_EN0_RCNTHI); - z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ - z_writeb(ring_page, nic_base + NE_EN0_RSARHI); - z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - - ptrs = (short*)hdr; - for (cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++) - *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - - hdr->count = WORDSWAP(hdr->count); - - ei_status.dmaing &= ~0x01; + return 0; } -/* Block input and output, similar to the Crynwr packet driver. If you - are porting to a new ethercard, look at the packet driver source for hints. - The NEx000 doesn't share the on-board packet memory -- you have to put - the packet out through the "remote DMA" dataport using z_writeb. */ - -static void zorro8390_block_input(struct net_device *dev, int count, - struct sk_buff *skb, int ring_offset) +static int __devinit zorro8390_init_one(struct zorro_dev *z, + const struct zorro_device_id *ent) { - int nic_base = dev->base_addr; - char *buf = skb->data; - short *ptrs; - int cnt; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - printk(KERN_ERR "%s: DMAing conflict in ne_block_input " - "[DMAstat:%d][irqlock:%d].\n", - dev->name, ei_status.dmaing, ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - z_writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); - z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); - z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); - z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); - z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - ptrs = (short*)buf; - for (cnt = 0; cnt < (count>>1); cnt++) - *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); - if (count & 0x01) - buf[count-1] = z_readb(NE_BASE + NE_DATAPORT); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; -} + struct net_device *dev; + unsigned long board, ioaddr; + int err, i; + + for (i = ARRAY_SIZE(cards) - 1; i >= 0; i--) + if (z->id == cards[i].id) + break; + if (i < 0) + return -ENODEV; -static void zorro8390_block_output(struct net_device *dev, int count, - const unsigned char *buf, - const int start_page) -{ - int nic_base = NE_BASE; - unsigned long dma_start; - short *ptrs; - int cnt; - - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - if (count & 0x01) - count++; - - /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { - printk(KERN_ERR "%s: DMAing conflict in ne_block_output." - "[DMAstat:%d][irqlock:%d]\n", dev->name, ei_status.dmaing, - ei_status.irqlock); - return; - } - ei_status.dmaing |= 0x01; - /* We should already be in page 0, but to be safe... */ - z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); - - /* Now the normal output. */ - z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); - z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); - z_writeb(0x00, nic_base + NE_EN0_RSARLO); - z_writeb(start_page, nic_base + NE_EN0_RSARHI); - - z_writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - ptrs = (short*)buf; - for (cnt = 0; cnt < count>>1; cnt++) - z_writew(*ptrs++, NE_BASE+NE_DATAPORT); - - dma_start = jiffies; - - while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ - printk(KERN_ERR "%s: timeout waiting for Tx RDC.\n", - dev->name); - zorro8390_reset_8390(dev); - __NS8390_init(dev,1); - break; + board = z->resource.start; + ioaddr = board + cards[i].offset; + dev = ____alloc_ei_netdev(0); + if (!dev) + return -ENOMEM; + if (!request_mem_region(ioaddr, NE_IO_EXTENT * 2, DRV_NAME)) { + free_netdev(dev); + return -EBUSY; } - - z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; + err = zorro8390_init(dev, board, cards[i].name, ZTWO_VADDR(ioaddr)); + if (err) { + release_mem_region(ioaddr, NE_IO_EXTENT * 2); + free_netdev(dev); + return err; + } + zorro_set_drvdata(z, dev); + return 0; } -static void __devexit zorro8390_remove_one(struct zorro_dev *z) -{ - struct net_device *dev = zorro_get_drvdata(z); - - unregister_netdev(dev); - free_irq(IRQ_AMIGA_PORTS, dev); - release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT*2); - free_netdev(dev); -} +static struct zorro_driver zorro8390_driver = { + .name = "zorro8390", + .id_table = zorro8390_zorro_tbl, + .probe = zorro8390_init_one, + .remove = __devexit_p(zorro8390_remove_one), +}; static int __init zorro8390_init_module(void) { - return zorro_register_driver(&zorro8390_driver); + return zorro_register_driver(&zorro8390_driver); } static void __exit zorro8390_cleanup_module(void) { - zorro_unregister_driver(&zorro8390_driver); + zorro_unregister_driver(&zorro8390_driver); } module_init(zorro8390_init_module); -- cgit v1.2.3-70-g09d2 From a65151ba201fe56ac146767e018674a84bfef1a6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 27 May 2011 05:31:32 +0000 Subject: ixgbe: pass adapter struct instead of netdev for interrupt data This change makes it so that we pass the adapter struct instead of the netdev for most of the basic interrupts that are not associated with q_vectors. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 2496a27b599..b308571428a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1880,8 +1880,7 @@ static void ixgbe_check_lsc(struct ixgbe_adapter *adapter) static irqreturn_t ixgbe_msix_lsc(int irq, void *data) { - struct net_device *netdev = data; - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = data; struct ixgbe_hw *hw = &adapter->hw; u32 eicr; @@ -2376,7 +2375,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) sprintf(adapter->lsc_int_name, "%s:lsc", netdev->name); err = request_irq(adapter->msix_entries[vector].vector, - ixgbe_msix_lsc, 0, adapter->lsc_int_name, netdev); + ixgbe_msix_lsc, 0, adapter->lsc_int_name, adapter); if (err) { e_err(probe, "request_irq for msix_lsc failed: %d\n", err); goto free_queue_irqs; @@ -2488,8 +2487,7 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, **/ static irqreturn_t ixgbe_intr(int irq, void *data) { - struct net_device *netdev = data; - struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_adapter *adapter = data; struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; u32 eicr; @@ -2586,10 +2584,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter) err = ixgbe_request_msix_irqs(adapter); } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { err = request_irq(adapter->pdev->irq, ixgbe_intr, 0, - netdev->name, netdev); + netdev->name, adapter); } else { err = request_irq(adapter->pdev->irq, ixgbe_intr, IRQF_SHARED, - netdev->name, netdev); + netdev->name, adapter); } if (err) @@ -2600,15 +2598,13 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter) static void ixgbe_free_irq(struct ixgbe_adapter *adapter) { - struct net_device *netdev = adapter->netdev; - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { int i, q_vectors; q_vectors = adapter->num_msix_vectors; i = q_vectors - 1; - free_irq(adapter->msix_entries[i].vector, netdev); + free_irq(adapter->msix_entries[i].vector, adapter); i--; for (; i >= 0; i--) { @@ -2623,7 +2619,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) ixgbe_reset_q_vectors(adapter); } else { - free_irq(adapter->pdev->irq, netdev); + free_irq(adapter->pdev->irq, adapter); } } -- cgit v1.2.3-70-g09d2 From 7d4987de752a94772ad1ae85ad5c702bbcf73305 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 27 May 2011 05:31:37 +0000 Subject: ixgbe: Convert IXGBE_DESC_UNUSED from macro to static inline function This change is a minor cleanup that converts the IXGBE_DESC_UNUSED macro into a static inline function just for the case of the code being a bit cleaner. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 10 +++++++--- drivers/net/ixgbe/ixgbe_main.c | 10 +++++----- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index d6bfb2f6ba8..b1d4b02606a 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -306,9 +306,13 @@ struct ixgbe_q_vector { ((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8) #define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG -#define IXGBE_DESC_UNUSED(R) \ - ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ - (R)->next_to_clean - (R)->next_to_use - 1) +static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring) +{ + u16 ntc = ring->next_to_clean; + u16 ntu = ring->next_to_use; + + return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1; +} #define IXGBE_RX_DESC_ADV(R, i) \ (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b308571428a..f8a22eb89da 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -882,7 +882,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) if (unlikely(count && netif_carrier_ok(tx_ring->netdev) && - (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) { + (ixgbe_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD))) { /* Make sure that anybody stopping the queue after this * sees the new next_to_clean. */ @@ -1474,7 +1474,7 @@ next_desc: } rx_ring->next_to_clean = i; - cleaned_count = IXGBE_DESC_UNUSED(rx_ring); + cleaned_count = ixgbe_desc_unused(rx_ring); if (cleaned_count) ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); @@ -3126,7 +3126,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); ixgbe_rx_desc_queue_enable(adapter, ring); - ixgbe_alloc_rx_buffers(ring, IXGBE_DESC_UNUSED(ring)); + ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring)); } static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) @@ -6817,7 +6817,7 @@ static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) /* We need to check again in a case another CPU has just * made room available. */ - if (likely(IXGBE_DESC_UNUSED(tx_ring) < size)) + if (likely(ixgbe_desc_unused(tx_ring) < size)) return -EBUSY; /* A reprieve! - use start_queue because it doesn't call schedule */ @@ -6828,7 +6828,7 @@ static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) { - if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size)) + if (likely(ixgbe_desc_unused(tx_ring) >= size)) return 0; return __ixgbe_maybe_stop_tx(tx_ring, size); } -- cgit v1.2.3-70-g09d2 From 63544e9c0055316d0397cb671f2ff99d85c77293 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 27 May 2011 05:31:42 +0000 Subject: ixgbe: Move all values that deal with count, next_to_use, next_to_clean to u16 This change updates all values dealing with count, next_to_use, and next_to_clean so that they stay u16 values. The advantage of this is that there is no re-casting of type during the propagation through the stack. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f8a22eb89da..4fbe0770218 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6537,11 +6537,12 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, struct ixgbe_tx_buffer *tx_buffer_info; unsigned int len; unsigned int total = skb->len; - unsigned int offset = 0, size, count = 0, i; + unsigned int offset = 0, size, count = 0; unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int f; unsigned int bytecount = skb->len; u16 gso_segs = 1; + u16 i; i = tx_ring->next_to_use; @@ -6807,7 +6808,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring, struct sk_buff *skb, input, common, ring->queue_index); } -static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) +static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) { netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); /* Herbert's original patch had: @@ -6826,7 +6827,7 @@ static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) return 0; } -static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) +static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) { if (likely(ixgbe_desc_unused(tx_ring) >= size)) return 0; @@ -6864,13 +6865,13 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring) { - unsigned int first; unsigned int tx_flags = 0; - u8 hdr_len = 0; int tso; - int count = 0; + u16 count = 0; + u16 first; unsigned int f; __be16 protocol; + u8 hdr_len = 0; protocol = vlan_get_protocol(skb); -- cgit v1.2.3-70-g09d2 From 897ab15606ce896b6a574a263beb51cbfb43f041 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 27 May 2011 05:31:47 +0000 Subject: ixgbe: Add one function that handles most of context descriptor setup There is a significant amount of shared functionality between the checksum and TSO offload configuration that is shared in regards to how they setup the context descriptors. Since so much of the functionality is shared it makes sense to move the shared functionality into a single function and just call that function from the two context descriptor specific routines. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 4 +- drivers/net/ixgbe/ixgbe_fcoe.c | 85 +++++------- drivers/net/ixgbe/ixgbe_main.c | 295 ++++++++++++++++++----------------------- 3 files changed, 162 insertions(+), 222 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index b1d4b02606a..393ceae7f3d 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -580,10 +580,10 @@ extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring); extern void ixgbe_set_rx_mode(struct net_device *netdev); extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); +extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); -extern int ixgbe_fso(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, struct sk_buff *skb, +extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, u32 tx_flags, u8 *hdr_len); extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index f5f39edb86a..9c20077dd44 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -474,24 +474,18 @@ ddp_out: * * Returns : 0 indicates no FSO, > 0 for FSO, < 0 for error */ -int ixgbe_fso(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, struct sk_buff *skb, +int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, u32 tx_flags, u8 *hdr_len) { - u8 sof, eof; + struct fc_frame_header *fh; u32 vlan_macip_lens; - u32 fcoe_sof_eof; - u32 type_tucmd; + u32 fcoe_sof_eof = 0; u32 mss_l4len_idx; - int mss = 0; - unsigned int i; - struct ixgbe_tx_buffer *tx_buffer_info; - struct ixgbe_adv_tx_context_desc *context_desc; - struct fc_frame_header *fh; + u8 sof, eof; if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) { - e_err(drv, "Wrong gso type %d:expecting SKB_GSO_FCOE\n", - skb_shinfo(skb)->gso_type); + dev_err(tx_ring->dev, "Wrong gso type %d:expecting SKB_GSO_FCOE\n", + skb_shinfo(skb)->gso_type); return -EINVAL; } @@ -501,23 +495,22 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, sizeof(struct fcoe_hdr)); /* sets up SOF and ORIS */ - fcoe_sof_eof = 0; sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof; switch (sof) { case FC_SOF_I2: - fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS; + fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_ORIS; break; case FC_SOF_I3: - fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF; - fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS; + fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF | + IXGBE_ADVTXD_FCOEF_ORIS; break; case FC_SOF_N2: break; case FC_SOF_N3: - fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF; + fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF; break; default: - e_warn(drv, "unknown sof = 0x%x\n", sof); + dev_warn(tx_ring->dev, "unknown sof = 0x%x\n", sof); return -EINVAL; } @@ -530,12 +523,11 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, break; case FC_EOF_T: /* lso needs ORIE */ - if (skb_is_gso(skb)) { - fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N; - fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIE; - } else { + if (skb_is_gso(skb)) + fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N | + IXGBE_ADVTXD_FCOEF_ORIE; + else fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T; - } break; case FC_EOF_NI: fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI; @@ -544,7 +536,7 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A; break; default: - e_warn(drv, "unknown eof = 0x%x\n", eof); + dev_warn(tx_ring->dev, "unknown eof = 0x%x\n", eof); return -EINVAL; } @@ -553,43 +545,28 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, if (fh->fh_f_ctl[2] & FC_FC_REL_OFF) fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC; - /* hdr_len includes fc_hdr if FCoE lso is enabled */ + /* include trailer in headlen as it is replicated per frame */ *hdr_len = sizeof(struct fcoe_crc_eof); + + /* hdr_len includes fc_hdr if FCoE LSO is enabled */ if (skb_is_gso(skb)) *hdr_len += (skb_transport_offset(skb) + sizeof(struct fc_frame_header)); - /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */ - vlan_macip_lens = (skb_transport_offset(skb) + - sizeof(struct fc_frame_header)); - vlan_macip_lens |= ((skb_transport_offset(skb) - 4) - << IXGBE_ADVTXD_MACLEN_SHIFT); - vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); - - /* type_tycmd and mss: set TUCMD.FCoE to enable offload */ - type_tucmd = IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT | - IXGBE_ADVTXT_TUCMD_FCOE; - if (skb_is_gso(skb)) - mss = skb_shinfo(skb)->gso_size; + /* mss_l4len_id: use 1 for FSO as TSO, no need for L4LEN */ - mss_l4len_idx = (mss << IXGBE_ADVTXD_MSS_SHIFT) | - (1 << IXGBE_ADVTXD_IDX_SHIFT); + mss_l4len_idx = skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT; + mss_l4len_idx |= 1 << IXGBE_ADVTXD_IDX_SHIFT; + + /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */ + vlan_macip_lens = skb_transport_offset(skb) + + sizeof(struct fc_frame_header); + vlan_macip_lens |= (skb_transport_offset(skb) - 4) + << IXGBE_ADVTXD_MACLEN_SHIFT; + vlan_macip_lens |= tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; /* write context desc */ - i = tx_ring->next_to_use; - context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); - context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); - context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof); - context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd); - context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); - - tx_buffer_info = &tx_ring->tx_buffer_info[i]; - tx_buffer_info->time_stamp = jiffies; - tx_buffer_info->next_to_watch = i; - - i++; - if (i == tx_ring->count) - i = 0; - tx_ring->next_to_use = i; + ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fcoe_sof_eof, + IXGBE_ADVTXT_TUCMD_FCOE, mss_l4len_idx); return skb_is_gso(skb); } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 4fbe0770218..00e60c5ab27 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -6353,179 +6354,145 @@ static void ixgbe_service_task(struct work_struct *work) ixgbe_service_event_complete(adapter); } -static int ixgbe_tso(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, struct sk_buff *skb, - u32 tx_flags, u8 *hdr_len, __be16 protocol) +void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens, + u32 fcoe_sof_eof, u32 type_tucmd, u32 mss_l4len_idx) { struct ixgbe_adv_tx_context_desc *context_desc; - unsigned int i; - int err; - struct ixgbe_tx_buffer *tx_buffer_info; - u32 vlan_macip_lens = 0, type_tucmd_mlhl; - u32 mss_l4len_idx, l4len; + u16 i = tx_ring->next_to_use; - if (skb_is_gso(skb)) { - if (skb_header_cloned(skb)) { - err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); - if (err) - return err; - } - l4len = tcp_hdrlen(skb); - *hdr_len += l4len; - - if (protocol == htons(ETH_P_IP)) { - struct iphdr *iph = ip_hdr(skb); - iph->tot_len = 0; - iph->check = 0; - tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, - iph->daddr, 0, - IPPROTO_TCP, - 0); - } else if (skb_is_gso_v6(skb)) { - ipv6_hdr(skb)->payload_len = 0; - tcp_hdr(skb)->check = - ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0); - } + context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); - i = tx_ring->next_to_use; + i++; + tx_ring->next_to_use = (i < tx_ring->count) ? i : 0; - tx_buffer_info = &tx_ring->tx_buffer_info[i]; - context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); - - /* VLAN MACLEN IPLEN */ - if (tx_flags & IXGBE_TX_FLAGS_VLAN) - vlan_macip_lens |= - (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); - vlan_macip_lens |= ((skb_network_offset(skb)) << - IXGBE_ADVTXD_MACLEN_SHIFT); - *hdr_len += skb_network_offset(skb); - vlan_macip_lens |= - (skb_transport_header(skb) - skb_network_header(skb)); - *hdr_len += - (skb_transport_header(skb) - skb_network_header(skb)); - context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); - context_desc->seqnum_seed = 0; - - /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ - type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); + /* set bits to identify this as an advanced context descriptor */ + type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT; - if (protocol == htons(ETH_P_IP)) - type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; - type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; - context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); - - /* MSS L4LEN IDX */ - mss_l4len_idx = - (skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT); - mss_l4len_idx |= (l4len << IXGBE_ADVTXD_L4LEN_SHIFT); - /* use index 1 for TSO */ - mss_l4len_idx |= (1 << IXGBE_ADVTXD_IDX_SHIFT); - context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); + context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); + context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof); + context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd); + context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); +} - tx_buffer_info->time_stamp = jiffies; - tx_buffer_info->next_to_watch = i; +static int ixgbe_tso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, + u32 tx_flags, __be16 protocol, u8 *hdr_len) +{ + int err; + u32 vlan_macip_lens, type_tucmd; + u32 mss_l4len_idx, l4len; - i++; - if (i == tx_ring->count) - i = 0; - tx_ring->next_to_use = i; + if (!skb_is_gso(skb)) + return 0; - return true; + if (skb_header_cloned(skb)) { + err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); + if (err) + return err; } - return false; -} -static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb, - __be16 protocol) + /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ + type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP; + + if (protocol == __constant_htons(ETH_P_IP)) { + struct iphdr *iph = ip_hdr(skb); + iph->tot_len = 0; + iph->check = 0; + tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, + iph->daddr, 0, + IPPROTO_TCP, + 0); + type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4; + } else if (skb_is_gso_v6(skb)) { + ipv6_hdr(skb)->payload_len = 0; + tcp_hdr(skb)->check = + ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0); + } + + l4len = tcp_hdrlen(skb); + *hdr_len = skb_transport_offset(skb) + l4len; + + /* mss_l4len_id: use 1 as index for TSO */ + mss_l4len_idx = l4len << IXGBE_ADVTXD_L4LEN_SHIFT; + mss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT; + mss_l4len_idx |= 1 << IXGBE_ADVTXD_IDX_SHIFT; + + /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */ + vlan_macip_lens = skb_network_header_len(skb); + vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT; + vlan_macip_lens |= tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; + + ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, + mss_l4len_idx); + + return 1; +} + +static bool ixgbe_tx_csum(struct ixgbe_ring *tx_ring, + struct sk_buff *skb, u32 tx_flags, + __be16 protocol) { - u32 rtn = 0; + u32 vlan_macip_lens = 0; + u32 mss_l4len_idx = 0; + u32 type_tucmd = 0; - switch (protocol) { - case cpu_to_be16(ETH_P_IP): - rtn |= IXGBE_ADVTXD_TUCMD_IPV4; - switch (ip_hdr(skb)->protocol) { - case IPPROTO_TCP: - rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + if (skb->ip_summed != CHECKSUM_PARTIAL) { + if (!(tx_flags & IXGBE_TX_FLAGS_VLAN)) + return false; + } else { + u8 l4_hdr = 0; + switch (protocol) { + case __constant_htons(ETH_P_IP): + vlan_macip_lens |= skb_network_header_len(skb); + type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4; + l4_hdr = ip_hdr(skb)->protocol; break; - case IPPROTO_SCTP: - rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + case __constant_htons(ETH_P_IPV6): + vlan_macip_lens |= skb_network_header_len(skb); + l4_hdr = ipv6_hdr(skb)->nexthdr; + break; + default: + if (unlikely(net_ratelimit())) { + dev_warn(tx_ring->dev, + "partial checksum but proto=%x!\n", + skb->protocol); + } break; } - break; - case cpu_to_be16(ETH_P_IPV6): - /* XXX what about other V6 headers?? */ - switch (ipv6_hdr(skb)->nexthdr) { + + switch (l4_hdr) { case IPPROTO_TCP: - rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + mss_l4len_idx = tcp_hdrlen(skb) << + IXGBE_ADVTXD_L4LEN_SHIFT; break; case IPPROTO_SCTP: - rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + mss_l4len_idx = sizeof(struct sctphdr) << + IXGBE_ADVTXD_L4LEN_SHIFT; + break; + case IPPROTO_UDP: + mss_l4len_idx = sizeof(struct udphdr) << + IXGBE_ADVTXD_L4LEN_SHIFT; + break; + default: + if (unlikely(net_ratelimit())) { + dev_warn(tx_ring->dev, + "partial checksum but l4 proto=%x!\n", + skb->protocol); + } break; } - break; - default: - if (unlikely(net_ratelimit())) - e_warn(probe, "partial checksum but proto=%x!\n", - protocol); - break; } - return rtn; -} - -static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, - __be16 protocol) -{ - struct ixgbe_adv_tx_context_desc *context_desc; - unsigned int i; - struct ixgbe_tx_buffer *tx_buffer_info; - u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; - - if (skb->ip_summed == CHECKSUM_PARTIAL || - (tx_flags & IXGBE_TX_FLAGS_VLAN)) { - i = tx_ring->next_to_use; - tx_buffer_info = &tx_ring->tx_buffer_info[i]; - context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); - - if (tx_flags & IXGBE_TX_FLAGS_VLAN) - vlan_macip_lens |= - (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); - vlan_macip_lens |= (skb_network_offset(skb) << - IXGBE_ADVTXD_MACLEN_SHIFT); - if (skb->ip_summed == CHECKSUM_PARTIAL) - vlan_macip_lens |= (skb_transport_header(skb) - - skb_network_header(skb)); - - context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); - context_desc->seqnum_seed = 0; + vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT; + vlan_macip_lens |= tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; - type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); + ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, + type_tucmd, mss_l4len_idx); - if (skb->ip_summed == CHECKSUM_PARTIAL) - type_tucmd_mlhl |= ixgbe_psum(adapter, skb, protocol); - - context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); - /* use index zero for tx checksum offload */ - context_desc->mss_l4len_idx = 0; - - tx_buffer_info->time_stamp = jiffies; - tx_buffer_info->next_to_watch = i; - - i++; - if (i == tx_ring->count) - i = 0; - tx_ring->next_to_use = i; - - return true; - } - - return false; + return (skb->ip_summed == CHECKSUM_PARTIAL); } static int ixgbe_tx_map(struct ixgbe_adapter *adapter, @@ -6918,29 +6885,21 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, if (tx_flags & IXGBE_TX_FLAGS_FCOE) { #ifdef IXGBE_FCOE /* setup tx offload for FCoE */ - tso = ixgbe_fso(adapter, tx_ring, skb, tx_flags, &hdr_len); - if (tso < 0) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - if (tso) + tso = ixgbe_fso(tx_ring, skb, tx_flags, &hdr_len); + if (tso < 0) + goto out_drop; + else if (tso) tx_flags |= IXGBE_TX_FLAGS_FSO; #endif /* IXGBE_FCOE */ } else { if (protocol == htons(ETH_P_IP)) tx_flags |= IXGBE_TX_FLAGS_IPV4; - tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len, - protocol); - if (tso < 0) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - - if (tso) + tso = ixgbe_tso(tx_ring, skb, tx_flags, protocol, &hdr_len); + if (tso < 0) + goto out_drop; + else if (tso) tx_flags |= IXGBE_TX_FLAGS_TSO; - else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags, - protocol) && - (skb->ip_summed == CHECKSUM_PARTIAL)) + else if (ixgbe_tx_csum(tx_ring, skb, tx_flags, protocol)) tx_flags |= IXGBE_TX_FLAGS_CSUM; } @@ -6953,12 +6912,16 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED); } else { - dev_kfree_skb_any(skb); tx_ring->tx_buffer_info[first].time_stamp = 0; tx_ring->next_to_use = first; + goto out_drop; } return NETDEV_TX_OK; + +out_drop: + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -- cgit v1.2.3-70-g09d2 From a535c30e9e98d201089503a0ffa0093cba16e796 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 27 May 2011 05:31:52 +0000 Subject: ixgbe: Update method used for determining descriptor count for an skb This patch updates the current methods used for determining if we have enough space to transmit a given skb. The current method is quite wasteful as it has us go through and determine how each page is going to be broken up. That only needs to be done if pages are larger than our maximum data per TXD. As such I have wrapped that in a page size check. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 7 ++++++ drivers/net/ixgbe/ixgbe_main.c | 55 ++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 29 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 393ceae7f3d..744b6410813 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -131,6 +131,13 @@ struct vf_macvlans { u8 vf_macvlan[ETH_ALEN]; }; +#define IXGBE_MAX_TXD_PWR 14 +#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR) + +/* Tx Descriptors needed, worst case */ +#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IXGBE_MAX_DATA_PER_TXD) +#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4) + /* wrapper around a pointer to a socket buffer, * so a DMA handle can be stored along with the buffer */ struct ixgbe_tx_buffer { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 00e60c5ab27..305e1e4f80b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -772,15 +772,6 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring) return ret; } -#define IXGBE_MAX_TXD_PWR 14 -#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR) - -/* Tx Descriptors needed, worst case */ -#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \ - (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0)) -#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ - MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ - /** * ixgbe_tx_timeout_reset - initiate reset due to Tx timeout * @adapter: driver private struct @@ -6832,14 +6823,34 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring) { - unsigned int tx_flags = 0; int tso; - u16 count = 0; + u32 tx_flags = 0; +#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD + unsigned short f; +#endif u16 first; - unsigned int f; + u16 count = TXD_USE_COUNT(skb_headlen(skb)); __be16 protocol; u8 hdr_len = 0; + /* + * need: 1 descriptor per page * PAGE_SIZE/IXGBE_MAX_DATA_PER_TXD, + * + 1 desc for skb_head_len/IXGBE_MAX_DATA_PER_TXD, + * + 2 desc gap to keep tail from touching head, + * + 1 desc for context descriptor, + * otherwise try next time + */ +#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD + for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) + count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); +#else + count += skb_shinfo(skb)->nr_frags; +#endif + if (ixgbe_maybe_stop_tx(tx_ring, count + 3)) { + tx_ring->tx_stats.tx_busy++; + return NETDEV_TX_BUSY; + } + protocol = vlan_get_protocol(skb); if (vlan_tx_tag_present(skb)) { @@ -6863,25 +6874,11 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED && (protocol == htons(ETH_P_FCOE))) tx_flags |= IXGBE_TX_FLAGS_FCOE; -#endif - - /* four things can cause us to need a context descriptor */ - if (skb_is_gso(skb) || - (skb->ip_summed == CHECKSUM_PARTIAL) || - (tx_flags & IXGBE_TX_FLAGS_VLAN) || - (tx_flags & IXGBE_TX_FLAGS_FCOE)) - count++; - - count += TXD_USE_COUNT(skb_headlen(skb)); - for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); - - if (ixgbe_maybe_stop_tx(tx_ring, count)) { - tx_ring->tx_stats.tx_busy++; - return NETDEV_TX_BUSY; - } +#endif + /* record the location of the first descriptor for this packet */ first = tx_ring->next_to_use; + if (tx_flags & IXGBE_TX_FLAGS_FCOE) { #ifdef IXGBE_FCOE /* setup tx offload for FCoE */ -- cgit v1.2.3-70-g09d2 From 7555e83df399ef35e031b137442eac2b1894b993 Mon Sep 17 00:00:00 2001 From: Lior Levy Date: Sat, 25 Jun 2011 00:09:08 -0700 Subject: ixgbe: A fix to VF TX rate limit There is a need to configure MMW_SIZE in register RTTBCNRM with a correct value (0x4 for non jumbo frames and 0x14 for jumbo frames support). For 82599 the value is 0x4 and for X540 the value is 0x14. Signed-off-by: Lior Levy Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_sriov.c | 16 ++++++++++++++++ drivers/net/ixgbe/ixgbe_type.h | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index ac99b0458fe..d99d01e2132 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -605,6 +605,22 @@ static void ixgbe_set_vf_rate_limit(struct ixgbe_hw *hw, int vf, int tx_rate, } IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, 2*vf); /* vf Y uses queue 2*Y */ + /* + * Set global transmit compensation time to the MMW_SIZE in RTTBCNRM + * register. Typically MMW_SIZE=0x014 if 9728-byte jumbo is supported + * and 0x004 otherwise. + */ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRM, 0x4); + break; + case ixgbe_mac_X540: + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRM, 0x14); + break; + default: + break; + } + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val); } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 1eefc0c6840..e0d970ebab7 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -534,7 +534,7 @@ #define IXGBE_RTTBCNRC_RF_INT_SHIFT 14 #define IXGBE_RTTBCNRC_RF_INT_MASK \ (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT) - +#define IXGBE_RTTBCNRM 0x04980 /* FCoE DMA Context Registers */ #define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */ -- cgit v1.2.3-70-g09d2 From 9372453e87560f1602815bf08b9e2af0f5136a61 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 18 Jun 2011 07:39:52 +0000 Subject: ixgbe: complete FCoE initialization from setapp() routine Commit, commit c8ca76ebc6e50752c5311b92bb9aef7edb324577 Author: John Fastabend Date: Sat Mar 12 03:50:53 2011 +0000 ixgbe: DCB, further cleanups to app configuration Removed the getapp() routines from ixgbe because they are no longer needed. It also allowed the set hardware routines to use both IEEE 802.1Qaz app types and CEE app types. This added code to do bit shifting in the IEEE case. This patch reverts the checks and handles the IEEE case from the setapp entry point. I prefer this because it keeps the two paths from having to be aware of the DCB mode. This resolves a bug where I missed setting the selector bit in the IEEE spec value and left it in the CEE value. Now that they are separate routines these types of errors should not occur. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index bd2d7526538..db659df6b50 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -330,24 +330,20 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + int ret; +#ifdef IXGBE_FCOE struct dcb_app app = { .selector = DCB_APP_IDTYPE_ETHTYPE, .protocol = ETH_P_FCOE, }; u8 up = dcb_getapp(netdev, &app); - int ret; +#endif ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, MAX_TRAFFIC_CLASS); if (ret) return DCB_NO_HW_CHG; - /* In IEEE mode app data must be parsed into DCBX format for - * hardware routines. - */ - if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) - up = (1 << up); - #ifdef IXGBE_FCOE if (up && (up != (1 << adapter->fcoe.up))) adapter->dcb_set_bitmap |= BIT_APP_UPCHG; @@ -678,18 +674,34 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app) { struct ixgbe_adapter *adapter = netdev_priv(dev); + int err = -EINVAL; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) - return -EINVAL; + return err; - dcb_setapp(dev, app); + err = dcb_ieee_setapp(dev, app); #ifdef IXGBE_FCOE - if (app->selector == 1 && app->protocol == ETH_P_FCOE && - adapter->fcoe.tc == app->priority) - ixgbe_dcbnl_set_all(dev); + if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && + app->protocol == ETH_P_FCOE) { + u8 app_mask = dcb_ieee_getapp_mask(dev, app); + + if (app_mask & (1 << adapter->fcoe.up)) + return err; + + adapter->fcoe.up = app->priority; + + if (netif_running(dev)) + dev->netdev_ops->ndo_stop(dev); + + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_init_interrupt_scheme(adapter); + + if (netif_running(dev)) + dev->netdev_ops->ndo_open(dev); + } #endif - return 0; + return err; } static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) -- cgit v1.2.3-70-g09d2 From 3b3bf3b92b313db62a07869a649533f7f4f25c24 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 18 Jun 2011 07:39:58 +0000 Subject: ixgbe: remove unused fcoe.tc field and fcoe_setapp() The fcoe.tc field is no longer used so remove it. After the field is removed there is no need to keep fcoe_setapp() around so remove it as well. And finally we can get rid of some DCB #ifdef's in the fcoe code. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 2 +- drivers/net/ixgbe/ixgbe_fcoe.c | 54 ---------------------------------------- drivers/net/ixgbe/ixgbe_fcoe.h | 1 - drivers/net/ixgbe/ixgbe_main.c | 1 - 4 files changed, 1 insertion(+), 57 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index db659df6b50..1a137650351 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -357,7 +357,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) usleep_range(1000, 2000); - ixgbe_fcoe_setapp(adapter, up); + adapter->fcoe.up = ffs(up) - 1; if (netif_running(netdev)) netdev->netdev_ops->ndo_stop(netdev); diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 9c20077dd44..f0c1018bbf3 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -26,9 +26,6 @@ *******************************************************************************/ #include "ixgbe.h" -#ifdef CONFIG_IXGBE_DCB -#include "ixgbe_dcb_82599.h" -#endif /* CONFIG_IXGBE_DCB */ #include #include #include @@ -625,10 +622,6 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_fcoe *fcoe = &adapter->fcoe; struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; -#ifdef CONFIG_IXGBE_DCB - u8 tc; - u32 up2tc; -#endif if (!fcoe->pool) { spin_lock_init(&fcoe->lock); @@ -694,18 +687,6 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) IXGBE_FCRXCTRL_FCOELLI | IXGBE_FCRXCTRL_FCCRCBO | (FC_FCOE_VER << IXGBE_FCRXCTRL_FCOEVER_SHIFT)); -#ifdef CONFIG_IXGBE_DCB - up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC); - for (i = 0; i < MAX_USER_PRIORITY; i++) { - tc = (u8)(up2tc >> (i * IXGBE_RTTUP2TC_UP_SHIFT)); - tc &= (MAX_TRAFFIC_CLASS - 1); - if (fcoe->tc == tc) { - fcoe->up = i; - break; - } - } -#endif - return; out_extra_ddp_buffer: @@ -833,41 +814,6 @@ out_disable: return rc; } -#ifdef CONFIG_IXGBE_DCB -/** - * ixgbe_fcoe_setapp - sets the user priority bitmap for FCoE - * @adapter : ixgbe adapter - * @up : 802.1p user priority bitmap - * - * Finds out the traffic class from the input user priority - * bitmap for FCoE. - * - * Returns : 0 on success otherwise returns 1 on error - */ -u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up) -{ - int i; - u32 up2tc; - - /* valid user priority bitmap must not be 0 */ - if (up) { - /* from user priority to the corresponding traffic class */ - up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC); - for (i = 0; i < MAX_USER_PRIORITY; i++) { - if (up & (1 << i)) { - up2tc >>= (i * IXGBE_RTTUP2TC_UP_SHIFT); - up2tc &= (MAX_TRAFFIC_CLASS - 1); - adapter->fcoe.tc = (u8)up2tc; - adapter->fcoe.up = i; - return 0; - } - } - } - - return 1; -} -#endif /* CONFIG_IXGBE_DCB */ - /** * ixgbe_fcoe_get_wwn - get world wide name for the node or the port * @netdev : ixgbe adapter diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index d876e7ac225..99de145e290 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -74,7 +74,6 @@ struct ixgbe_fcoe { dma_addr_t extra_ddp_buffer_dma; unsigned long mode; #ifdef CONFIG_IXGBE_DCB - u8 tc; u8 up; #endif }; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 305e1e4f80b..fa671ae0ab6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5169,7 +5169,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->ring_feature[RING_F_FCOE].indices = 0; #ifdef CONFIG_IXGBE_DCB /* Default traffic class to use for FCoE */ - adapter->fcoe.tc = IXGBE_FCOE_DEFTC; adapter->fcoe.up = IXGBE_FCOE_DEFTC; #endif #endif /* IXGBE_FCOE */ -- cgit v1.2.3-70-g09d2 From 42532da64e9c4102decab8f37cf3959af55789a4 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 18 Jun 2011 07:40:04 +0000 Subject: ixgbe: implement DCB ops dcb_ieee_del() Implement DCB ops dcb_ieee_del() and set FCoE to the default priority when no priority exists. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 48 +++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 1a137650351..0ace6ce1d0b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -670,6 +670,22 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, return err; } +#ifdef IXGBE_FCOE +static void ixgbe_dcbnl_devreset(struct net_device *dev) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + if (netif_running(dev)) + dev->netdev_ops->ndo_stop(dev); + + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_init_interrupt_scheme(adapter); + + if (netif_running(dev)) + dev->netdev_ops->ndo_open(dev); +} +#endif + static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app) { @@ -690,15 +706,34 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, return err; adapter->fcoe.up = app->priority; + ixgbe_dcbnl_devreset(dev); + } +#endif + return 0; +} + +static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev, + struct dcb_app *app) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int err; + + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; - if (netif_running(dev)) - dev->netdev_ops->ndo_stop(dev); + err = dcb_ieee_delapp(dev, app); - ixgbe_clear_interrupt_scheme(adapter); - ixgbe_init_interrupt_scheme(adapter); +#ifdef IXGBE_FCOE + if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && + app->protocol == ETH_P_FCOE) { + u8 app_mask = dcb_ieee_getapp_mask(dev, app); + + if (app_mask & (1 << adapter->fcoe.up)) + return err; - if (netif_running(dev)) - dev->netdev_ops->ndo_open(dev); + adapter->fcoe.up = app_mask ? + ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC; + ixgbe_dcbnl_devreset(dev); } #endif return err; @@ -755,6 +790,7 @@ const struct dcbnl_rtnl_ops dcbnl_ops = { .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, .ieee_setapp = ixgbe_dcbnl_ieee_setapp, + .ieee_delapp = ixgbe_dcbnl_ieee_delapp, .getstate = ixgbe_dcbnl_get_state, .setstate = ixgbe_dcbnl_set_state, .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, -- cgit v1.2.3-70-g09d2 From 6e53391cb4f9491182e7fbd280966ebe2aca07dc Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 26 Jun 2011 20:40:48 +0000 Subject: be2net: fix netdev_stats_update Problem initially reproted and fixed by Eric Dumazet netdev_stats_update() resets netdev->stats and then accumulates stats from various rings. This is wrong as stats readers can sometimes catch zero values. Use temporary variables instead for accumulating per-ring values. Signed-off-by: Sathya Perla Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index c4f564cd745..5ca06b0d2d0 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -428,33 +428,38 @@ void netdev_stats_update(struct be_adapter *adapter) struct net_device_stats *dev_stats = &adapter->netdev->stats; struct be_rx_obj *rxo; struct be_tx_obj *txo; + unsigned long pkts = 0, bytes = 0, mcast = 0, drops = 0; int i; - memset(dev_stats, 0, sizeof(*dev_stats)); for_all_rx_queues(adapter, rxo, i) { - dev_stats->rx_packets += rx_stats(rxo)->rx_pkts; - dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes; - dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts; + pkts += rx_stats(rxo)->rx_pkts; + bytes += rx_stats(rxo)->rx_bytes; + mcast += rx_stats(rxo)->rx_mcast_pkts; /* no space in linux buffers: best possible approximation */ if (adapter->generation == BE_GEN3) { if (!(lancer_chip(adapter))) { - struct be_erx_stats_v1 *erx_stats = + struct be_erx_stats_v1 *erx = be_erx_stats_from_cmd(adapter); - dev_stats->rx_dropped += - erx_stats->rx_drops_no_fragments[rxo->q.id]; + drops += erx->rx_drops_no_fragments[rxo->q.id]; } } else { - struct be_erx_stats_v0 *erx_stats = + struct be_erx_stats_v0 *erx = be_erx_stats_from_cmd(adapter); - dev_stats->rx_dropped += - erx_stats->rx_drops_no_fragments[rxo->q.id]; + drops += erx->rx_drops_no_fragments[rxo->q.id]; } } + dev_stats->rx_packets = pkts; + dev_stats->rx_bytes = bytes; + dev_stats->multicast = mcast; + dev_stats->rx_dropped = drops; + pkts = bytes = 0; for_all_tx_queues(adapter, txo, i) { - dev_stats->tx_packets += tx_stats(txo)->be_tx_pkts; - dev_stats->tx_bytes += tx_stats(txo)->be_tx_bytes; + pkts += tx_stats(txo)->be_tx_pkts; + bytes += tx_stats(txo)->be_tx_bytes; } + dev_stats->tx_packets = pkts; + dev_stats->tx_bytes = bytes; /* bad pkts received */ dev_stats->rx_errors = drvs->rx_crc_errors + -- cgit v1.2.3-70-g09d2 From c814fd3669b43f32ddd505178705c02352b0ac7c Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 26 Jun 2011 20:41:25 +0000 Subject: be2net: get rid of multi_rxq module param Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 5ca06b0d2d0..2373d394fa7 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -33,10 +33,6 @@ module_param(num_vfs, uint, S_IRUGO); MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); -static bool multi_rxq = true; -module_param(multi_rxq, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(multi_rxq, "Multi Rx Queue support. Enabled by default"); - static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, @@ -1785,7 +1781,7 @@ static void be_rx_queues_destroy(struct be_adapter *adapter) static u32 be_num_rxqs_want(struct be_adapter *adapter) { - if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && + if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) && !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { return 1 + MAX_RSS_QS; /* one default non-RSS queue */ } else { -- cgit v1.2.3-70-g09d2 From 2903dd654d8788425a9523959b02933ea6555229 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 26 Jun 2011 20:41:53 +0000 Subject: be2net: fix initialization of vlan_prio_bmap Initialization of this field to "all priorities" must be done before MCC queue creation. As soon as the MCC queue is created, an event modifying this value may be received. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 2373d394fa7..ae281de94b9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2554,6 +2554,9 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto tx_qs_destroy; + /* Allow all priorities by default. A GRP5 evt may modify this */ + adapter->vlan_prio_bmap = 0xff; + status = be_mcc_queues_create(adapter); if (status != 0) goto rx_qs_destroy; @@ -3419,10 +3422,6 @@ static int __devinit be_probe(struct pci_dev *pdev, } dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); - /* By default all priorities are enabled. - * Needed in case of no GRP5 evt support - */ - adapter->vlan_prio_bmap = 0xff; schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); return 0; -- cgit v1.2.3-70-g09d2 From 12a3bfefc8c1e43ddb50950cb74f8a11d680567a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:28 +0000 Subject: generic_hdlc: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/c101.c | 30 +++++++------- drivers/net/wan/hd64570.c | 8 ++-- drivers/net/wan/hd64572.c | 8 ++-- drivers/net/wan/hdlc.c | 16 ++++---- drivers/net/wan/hdlc_cisco.c | 21 ++++------ drivers/net/wan/hdlc_fr.c | 96 ++++++++++++++++++++------------------------ drivers/net/wan/hdlc_ppp.c | 9 ++--- drivers/net/wan/hdlc_x25.c | 12 +++--- drivers/net/wan/n2.c | 42 +++++++++---------- drivers/net/wan/pc300too.c | 36 ++++++++--------- drivers/net/wan/pci200syn.c | 29 +++++++------ drivers/net/wan/wanxl.c | 90 +++++++++++++++++++---------------------- 12 files changed, 186 insertions(+), 211 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 4ac85a09c5a..54f995f4a5a 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -14,6 +14,8 @@ * Moxa C101 User's Manual */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -313,44 +315,44 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) int result; if (irq<3 || irq>15 || irq == 6) /* FIXME */ { - printk(KERN_ERR "c101: invalid IRQ value\n"); + pr_err("invalid IRQ value\n"); return -ENODEV; } if (winbase < 0xC0000 || winbase > 0xDFFFF || (winbase & 0x3FFF) !=0) { - printk(KERN_ERR "c101: invalid RAM value\n"); + pr_err("invalid RAM value\n"); return -ENODEV; } card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - printk(KERN_ERR "c101: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); return -ENOBUFS; } card->dev = alloc_hdlcdev(card); if (!card->dev) { - printk(KERN_ERR "c101: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); kfree(card); return -ENOBUFS; } if (request_irq(irq, sca_intr, 0, devname, card)) { - printk(KERN_ERR "c101: could not allocate IRQ\n"); + pr_err("could not allocate IRQ\n"); c101_destroy_card(card); return -EBUSY; } card->irq = irq; if (!request_mem_region(winbase, C101_MAPPED_RAM_SIZE, devname)) { - printk(KERN_ERR "c101: could not request RAM window\n"); + pr_err("could not request RAM window\n"); c101_destroy_card(card); return -EBUSY; } card->phy_winbase = winbase; card->win0base = ioremap(winbase, C101_MAPPED_RAM_SIZE); if (!card->win0base) { - printk(KERN_ERR "c101: could not map I/O address\n"); + pr_err("could not map I/O address\n"); c101_destroy_card(card); return -EFAULT; } @@ -381,7 +383,7 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) result = register_hdlc_device(dev); if (result) { - printk(KERN_WARNING "c101: unable to register hdlc device\n"); + pr_warn("unable to register hdlc device\n"); c101_destroy_card(card); return result; } @@ -389,10 +391,8 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) sca_init_port(card); /* Set up C101 memory */ set_carrier(card); - printk(KERN_INFO "%s: Moxa C101 on IRQ%u," - " using %u TX + %u RX packets rings\n", - dev->name, card->irq, - card->tx_ring_buffers, card->rx_ring_buffers); + netdev_info(dev, "Moxa C101 on IRQ%u, using %u TX + %u RX packets rings\n", + card->irq, card->tx_ring_buffers, card->rx_ring_buffers); *new_card = card; new_card = &card->next_card; @@ -405,12 +405,12 @@ static int __init c101_init(void) { if (hw == NULL) { #ifdef MODULE - printk(KERN_INFO "c101: no card initialized\n"); + pr_info("no card initialized\n"); #endif return -EINVAL; /* no parameters specified, abort */ } - printk(KERN_INFO "%s\n", version); + pr_info("%s\n", version); do { unsigned long irq, ram; @@ -428,7 +428,7 @@ static int __init c101_init(void) return first_card ? 0 : -EINVAL; }while(*hw++ == ':'); - printk(KERN_ERR "c101: invalid hardware parameters\n"); + pr_err("invalid hardware parameters\n"); return first_card ? 0 : -EINVAL; } diff --git a/drivers/net/wan/hd64570.c b/drivers/net/wan/hd64570.c index a3ea27ce04f..33b67d88fce 100644 --- a/drivers/net/wan/hd64570.c +++ b/drivers/net/wan/hd64570.c @@ -582,8 +582,8 @@ static void sca_dump_rings(struct net_device *dev) sca_in(DSR_RX(phy_node(port)), card), port->rxin, sca_in(DSR_RX(phy_node(port)), card) & DSR_DE ? "" : "in"); for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++) - printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); - printk(KERN_CONT "\n"); + pr_cont(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); + pr_cont("\n"); printk(KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " "last=%u %sactive", @@ -593,8 +593,8 @@ static void sca_dump_rings(struct net_device *dev) sca_in(DSR_TX(phy_node(port)), card) & DSR_DE ? "" : "in"); for (cnt = 0; cnt < port_to_card(port)->tx_ring_buffers; cnt++) - printk(" %02X", readb(&(desc_address(port, cnt, 1)->stat))); - printk("\n"); + pr_cont(" %02X", readb(&(desc_address(port, cnt, 1)->stat))); + pr_cont("\n"); printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x, ST: %02x %02x %02x %02x," " FST: %02x CST: %02x %02x\n", diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index e305274f83f..efc0db10118 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c @@ -530,8 +530,8 @@ static void sca_dump_rings(struct net_device *dev) sca_in(DSR_RX(port->chan), card), port->rxin, sca_in(DSR_RX(port->chan), card) & DSR_DE ? "" : "in"); for (cnt = 0; cnt < port->card->rx_ring_buffers; cnt++) - printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); - printk(KERN_CONT "\n"); + pr_cont(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); + pr_cont("\n"); printk(KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " "last=%u %sactive", @@ -541,8 +541,8 @@ static void sca_dump_rings(struct net_device *dev) sca_in(DSR_TX(port->chan), card) & DSR_DE ? "" : "in"); for (cnt = 0; cnt < port->card->tx_ring_buffers; cnt++) - printk(" %02X", readb(&(desc_address(port, cnt, 1)->stat))); - printk("\n"); + pr_cont(" %02X", readb(&(desc_address(port, cnt, 1)->stat))); + pr_cont("\n"); printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x," " ST: %02x %02x %02x %02x %02x, FST: %02x CST: %02x %02x\n", diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c index 5d4bb615ccc..10cc7df9549 100644 --- a/drivers/net/wan/hdlc.c +++ b/drivers/net/wan/hdlc.c @@ -22,6 +22,8 @@ * - proto->start() and stop() are called with spin_lock_irq held. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -130,10 +132,10 @@ static int hdlc_device_event(struct notifier_block *this, unsigned long event, goto carrier_exit; if (hdlc->carrier) { - printk(KERN_INFO "%s: Carrier detected\n", dev->name); + netdev_info(dev, "Carrier detected\n"); hdlc_proto_start(dev); } else { - printk(KERN_INFO "%s: Carrier lost\n", dev->name); + netdev_info(dev, "Carrier lost\n"); hdlc_proto_stop(dev); } @@ -165,10 +167,10 @@ int hdlc_open(struct net_device *dev) spin_lock_irq(&hdlc->state_lock); if (hdlc->carrier) { - printk(KERN_INFO "%s: Carrier detected\n", dev->name); + netdev_info(dev, "Carrier detected\n"); hdlc_proto_start(dev); } else - printk(KERN_INFO "%s: No carrier\n", dev->name); + netdev_info(dev, "No carrier\n"); hdlc->open = 1; @@ -281,8 +283,8 @@ int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, if (size) if ((dev_to_hdlc(dev)->state = kmalloc(size, GFP_KERNEL)) == NULL) { - printk(KERN_WARNING "Memory squeeze on" - " hdlc_proto_attach()\n"); + netdev_warn(dev, + "Memory squeeze on hdlc_proto_attach()\n"); module_put(proto->module); return -ENOBUFS; } @@ -363,7 +365,7 @@ static int __init hdlc_module_init(void) { int result; - printk(KERN_INFO "%s\n", version); + pr_info("%s\n", version); if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0) return result; dev_add_pack(&hdlc_packet_type); diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index b1e5e5b69c2..3f20808b5ff 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -103,9 +103,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, skb = dev_alloc_skb(sizeof(struct hdlc_header) + sizeof(struct cisco_packet)); if (!skb) { - printk(KERN_WARNING - "%s: Memory squeeze on cisco_keepalive_send()\n", - dev->name); + netdev_warn(dev, "Memory squeeze on cisco_keepalive_send()\n"); return; } skb_reserve(skb, 4); @@ -181,8 +179,8 @@ static int cisco_rx(struct sk_buff *skb) CISCO_PACKET_LEN) && (skb->len != sizeof(struct hdlc_header) + CISCO_BIG_PACKET_LEN)) { - printk(KERN_INFO "%s: Invalid length of Cisco control" - " packet (%d bytes)\n", dev->name, skb->len); + netdev_info(dev, "Invalid length of Cisco control packet (%d bytes)\n", + skb->len); goto rx_error; } @@ -217,8 +215,7 @@ static int cisco_rx(struct sk_buff *skb) return NET_RX_SUCCESS; case CISCO_ADDR_REPLY: - printk(KERN_INFO "%s: Unexpected Cisco IP address " - "reply\n", dev->name); + netdev_info(dev, "Unexpected Cisco IP address reply\n"); goto rx_error; case CISCO_KEEPALIVE_REQ: @@ -235,9 +232,8 @@ static int cisco_rx(struct sk_buff *skb) min = sec / 60; sec -= min * 60; hrs = min / 60; min -= hrs * 60; days = hrs / 24; hrs -= days * 24; - printk(KERN_INFO "%s: Link up (peer " - "uptime %ud%uh%um%us)\n", - dev->name, days, hrs, min, sec); + netdev_info(dev, "Link up (peer uptime %ud%uh%um%us)\n", + days, hrs, min, sec); netif_dormant_off(dev); st->up = 1; } @@ -249,8 +245,7 @@ static int cisco_rx(struct sk_buff *skb) } /* switch (keepalive type) */ } /* switch (protocol) */ - printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name, - ntohs(data->protocol)); + netdev_info(dev, "Unsupported protocol %x\n", ntohs(data->protocol)); dev_kfree_skb_any(skb); return NET_RX_DROP; @@ -272,7 +267,7 @@ static void cisco_timer(unsigned long arg) if (st->up && time_after(jiffies, st->last_poll + st->settings.timeout * HZ)) { st->up = 0; - printk(KERN_INFO "%s: Link down\n", dev->name); + netdev_info(dev, "Link down\n"); netif_dormant_on(dev); } diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index fc433f28c04..b25c9229a6a 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -446,15 +446,14 @@ static netdev_tx_t pvc_xmit(struct sk_buff *skb, struct net_device *dev) static inline void fr_log_dlci_active(pvc_device *pvc) { - printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", - pvc->frad->name, - pvc->dlci, - pvc->main ? pvc->main->name : "", - pvc->main && pvc->ether ? " " : "", - pvc->ether ? pvc->ether->name : "", - pvc->state.new ? " new" : "", - !pvc->state.exist ? "deleted" : - pvc->state.active ? "active" : "inactive"); + netdev_info(pvc->frad, "DLCI %d [%s%s%s]%s %s\n", + pvc->dlci, + pvc->main ? pvc->main->name : "", + pvc->main && pvc->ether ? " " : "", + pvc->ether ? pvc->ether->name : "", + pvc->state.new ? " new" : "", + !pvc->state.exist ? "deleted" : + pvc->state.active ? "active" : "inactive"); } @@ -481,16 +480,14 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) if (dce && fullrep) { len += state(hdlc)->dce_pvc_count * (2 + stat_len); if (len > HDLC_MAX_MRU) { - printk(KERN_WARNING "%s: Too many PVCs while sending " - "LMI full report\n", dev->name); + netdev_warn(dev, "Too many PVCs while sending LMI full report\n"); return; } } skb = dev_alloc_skb(len); if (!skb) { - printk(KERN_WARNING "%s: Memory squeeze on fr_lmi_send()\n", - dev->name); + netdev_warn(dev, "Memory squeeze on fr_lmi_send()\n"); return; } memset(skb->data, 0, len); @@ -615,8 +612,7 @@ static void fr_timer(unsigned long arg) state(hdlc)->last_errors <<= 1; /* Shift the list */ if (state(hdlc)->request) { if (state(hdlc)->reliable) - printk(KERN_INFO "%s: No LMI status reply " - "received\n", dev->name); + netdev_info(dev, "No LMI status reply received\n"); state(hdlc)->last_errors |= 1; } @@ -628,8 +624,7 @@ static void fr_timer(unsigned long arg) } if (state(hdlc)->reliable != reliable) { - printk(KERN_INFO "%s: Link %sreliable\n", dev->name, - reliable ? "" : "un"); + netdev_info(dev, "Link %sreliable\n", reliable ? "" : "un"); fr_set_link_state(reliable, dev); } @@ -665,33 +660,32 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH)) { - printk(KERN_INFO "%s: Short LMI frame\n", dev->name); + netdev_info(dev, "Short LMI frame\n"); return 1; } if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : NLPID_CCITT_ANSI_LMI)) { - printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n", - dev->name); + netdev_info(dev, "Received non-LMI frame with LMI DLCI\n"); return 1; } if (skb->data[4] != LMI_CALLREF) { - printk(KERN_INFO "%s: Invalid LMI Call reference (0x%02X)\n", - dev->name, skb->data[4]); + netdev_info(dev, "Invalid LMI Call reference (0x%02X)\n", + skb->data[4]); return 1; } if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) { - printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n", - dev->name, skb->data[5]); + netdev_info(dev, "Invalid LMI Message type (0x%02X)\n", + skb->data[5]); return 1; } if (lmi == LMI_ANSI) { if (skb->data[6] != LMI_ANSI_LOCKSHIFT) { - printk(KERN_INFO "%s: Not ANSI locking shift in LMI" - " message (0x%02X)\n", dev->name, skb->data[6]); + netdev_info(dev, "Not ANSI locking shift in LMI message (0x%02X)\n", + skb->data[6]); return 1; } i = 7; @@ -700,34 +694,34 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE : LMI_ANSI_CISCO_REPTYPE)) { - printk(KERN_INFO "%s: Not an LMI Report type IE (0x%02X)\n", - dev->name, skb->data[i]); + netdev_info(dev, "Not an LMI Report type IE (0x%02X)\n", + skb->data[i]); return 1; } if (skb->data[++i] != LMI_REPT_LEN) { - printk(KERN_INFO "%s: Invalid LMI Report type IE length" - " (%u)\n", dev->name, skb->data[i]); + netdev_info(dev, "Invalid LMI Report type IE length (%u)\n", + skb->data[i]); return 1; } reptype = skb->data[++i]; if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) { - printk(KERN_INFO "%s: Unsupported LMI Report type (0x%02X)\n", - dev->name, reptype); + netdev_info(dev, "Unsupported LMI Report type (0x%02X)\n", + reptype); return 1; } if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE)) { - printk(KERN_INFO "%s: Not an LMI Link integrity verification" - " IE (0x%02X)\n", dev->name, skb->data[i]); + netdev_info(dev, "Not an LMI Link integrity verification IE (0x%02X)\n", + skb->data[i]); return 1; } if (skb->data[++i] != LMI_INTEG_LEN) { - printk(KERN_INFO "%s: Invalid LMI Link integrity verification" - " IE length (%u)\n", dev->name, skb->data[i]); + netdev_info(dev, "Invalid LMI Link integrity verification IE length (%u)\n", + skb->data[i]); return 1; } i++; @@ -801,14 +795,14 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT : LMI_ANSI_CISCO_PVCSTAT)) { - printk(KERN_INFO "%s: Not an LMI PVC status IE" - " (0x%02X)\n", dev->name, skb->data[i]); + netdev_info(dev, "Not an LMI PVC status IE (0x%02X)\n", + skb->data[i]); return 1; } if (skb->data[++i] != stat_len) { - printk(KERN_INFO "%s: Invalid LMI PVC status IE length" - " (%u)\n", dev->name, skb->data[i]); + netdev_info(dev, "Invalid LMI PVC status IE length (%u)\n", + skb->data[i]); return 1; } i++; @@ -829,9 +823,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) pvc = add_pvc(dev, dlci); if (!pvc && !no_ram) { - printk(KERN_WARNING - "%s: Memory squeeze on fr_lmi_recv()\n", - dev->name); + netdev_warn(dev, "Memory squeeze on fr_lmi_recv()\n"); no_ram = 1; } @@ -902,8 +894,8 @@ static int fr_rx(struct sk_buff *skb) pvc = find_pvc(hdlc, dlci); if (!pvc) { #ifdef DEBUG_PKT - printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", - frad->name, dlci); + netdev_info(frad, "No PVC for received frame's DLCI %d\n", + dlci); #endif dev_kfree_skb_any(skb); return NET_RX_DROP; @@ -962,14 +954,14 @@ static int fr_rx(struct sk_buff *skb) break; default: - printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " - "PID=%x\n", frad->name, oui, pid); + netdev_info(frad, "Unsupported protocol, OUI=%x PID=%x\n", + oui, pid); dev_kfree_skb_any(skb); return NET_RX_DROP; } } else { - printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " - "length = %i\n", frad->name, data[3], skb->len); + netdev_info(frad, "Unsupported protocol, NLPID=%x length=%i\n", + data[3], skb->len); dev_kfree_skb_any(skb); return NET_RX_DROP; } @@ -1073,8 +1065,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) int used; if ((pvc = add_pvc(frad, dlci)) == NULL) { - printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", - frad->name); + netdev_warn(frad, "Memory squeeze on fr_add_pvc()\n"); return -ENOBUFS; } @@ -1089,8 +1080,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) dev = alloc_netdev(0, "pvc%d", pvc_setup); if (!dev) { - printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", - frad->name); + netdev_warn(frad, "Memory squeeze on fr_pvc()\n"); delete_unused_pvcs(hdlc); return -ENOBUFS; } diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index 941f053e650..055a918067e 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c @@ -223,8 +223,7 @@ static void ppp_tx_cp(struct net_device *dev, u16 pid, u8 code, skb = dev_alloc_skb(sizeof(struct hdlc_header) + sizeof(struct cp_header) + magic_len + len); if (!skb) { - printk(KERN_WARNING "%s: out of memory in ppp_tx_cp()\n", - dev->name); + netdev_warn(dev, "out of memory in ppp_tx_cp()\n"); return; } skb_reserve(skb, sizeof(struct hdlc_header)); @@ -345,7 +344,7 @@ static void ppp_cp_event(struct net_device *dev, u16 pid, u16 event, u8 code, ppp_tx_cp(dev, pid, CP_CODE_REJ, ++ppp->seq, len, data); if (old_state != OPENED && proto->state == OPENED) { - printk(KERN_INFO "%s: %s up\n", dev->name, proto_name(pid)); + netdev_info(dev, "%s up\n", proto_name(pid)); if (pid == PID_LCP) { netif_dormant_off(dev); ppp_cp_event(dev, PID_IPCP, START, 0, 0, 0, NULL); @@ -356,7 +355,7 @@ static void ppp_cp_event(struct net_device *dev, u16 pid, u16 event, u8 code, } } if (old_state == OPENED && proto->state != OPENED) { - printk(KERN_INFO "%s: %s down\n", dev->name, proto_name(pid)); + netdev_info(dev, "%s down\n", proto_name(pid)); if (pid == PID_LCP) { netif_dormant_on(dev); ppp_cp_event(dev, PID_IPCP, STOP, 0, 0, 0, NULL); @@ -585,7 +584,7 @@ static void ppp_timer(unsigned long arg) break; if (time_after(jiffies, ppp->last_pong + ppp->keepalive_timeout * HZ)) { - printk(KERN_INFO "%s: Link down\n", proto->dev->name); + netdev_info(proto->dev, "Link down\n"); ppp_cp_event(proto->dev, PID_LCP, STOP, 0, 0, 0, NULL); ppp_cp_event(proto->dev, PID_LCP, START, 0, 0, 0, NULL); } else { /* send keep-alive packet */ diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index 70527e5a54a..56aeb011cb3 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c @@ -34,7 +34,7 @@ static void x25_connect_disconnect(struct net_device *dev, int reason, int code) unsigned char *ptr; if ((skb = dev_alloc_skb(1)) == NULL) { - printk(KERN_ERR "%s: out of memory\n", dev->name); + netdev_err(dev, "out of memory\n"); return; } @@ -106,9 +106,8 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) /* Send connect confirm. msg to level 3 */ x25_connected(dev, 0); else - printk(KERN_ERR "%s: LAPB connect request " - "failed, error code = %i\n", - dev->name, result); + netdev_err(dev, "LAPB connect request failed, error code = %i\n", + result); } break; @@ -118,9 +117,8 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev) /* Send disconnect confirm. msg to level 3 */ x25_disconnected(dev, 0); else - printk(KERN_ERR "%s: LAPB disconnect request " - "failed, error code = %i\n", - dev->name, result); + netdev_err(dev, "LAPB disconnect request failed, error code = %i\n", + result); } break; diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index 17d408fe693..5129ad514d2 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -16,6 +16,8 @@ * SDL Inc. PPP/HDLC/CISCO driver */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -341,57 +343,57 @@ static int __init n2_run(unsigned long io, unsigned long irq, int i; if (io < 0x200 || io > 0x3FF || (io % N2_IOPORTS) != 0) { - printk(KERN_ERR "n2: invalid I/O port value\n"); + pr_err("invalid I/O port value\n"); return -ENODEV; } if (irq < 3 || irq > 15 || irq == 6) /* FIXME */ { - printk(KERN_ERR "n2: invalid IRQ value\n"); + pr_err("invalid IRQ value\n"); return -ENODEV; } if (winbase < 0xA0000 || winbase > 0xFFFFF || (winbase & 0xFFF) != 0) { - printk(KERN_ERR "n2: invalid RAM value\n"); + pr_err("invalid RAM value\n"); return -ENODEV; } card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - printk(KERN_ERR "n2: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); return -ENOBUFS; } card->ports[0].dev = alloc_hdlcdev(&card->ports[0]); card->ports[1].dev = alloc_hdlcdev(&card->ports[1]); if (!card->ports[0].dev || !card->ports[1].dev) { - printk(KERN_ERR "n2: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); n2_destroy_card(card); return -ENOMEM; } if (!request_region(io, N2_IOPORTS, devname)) { - printk(KERN_ERR "n2: I/O port region in use\n"); + pr_err("I/O port region in use\n"); n2_destroy_card(card); return -EBUSY; } card->io = io; if (request_irq(irq, sca_intr, 0, devname, card)) { - printk(KERN_ERR "n2: could not allocate IRQ\n"); + pr_err("could not allocate IRQ\n"); n2_destroy_card(card); return -EBUSY; } card->irq = irq; if (!request_mem_region(winbase, USE_WINDOWSIZE, devname)) { - printk(KERN_ERR "n2: could not request RAM window\n"); + pr_err("could not request RAM window\n"); n2_destroy_card(card); return -EBUSY; } card->phy_winbase = winbase; card->winbase = ioremap(winbase, USE_WINDOWSIZE); if (!card->winbase) { - printk(KERN_ERR "n2: ioremap() failed\n"); + pr_err("ioremap() failed\n"); n2_destroy_card(card); return -EFAULT; } @@ -413,7 +415,7 @@ static int __init n2_run(unsigned long io, unsigned long irq, break; default: - printk(KERN_ERR "n2: invalid window size\n"); + pr_err("invalid window size\n"); n2_destroy_card(card); return -ENODEV; } @@ -433,12 +435,12 @@ static int __init n2_run(unsigned long io, unsigned long irq, card->buff_offset = (valid0 + valid1) * sizeof(pkt_desc) * (card->tx_ring_buffers + card->rx_ring_buffers); - printk(KERN_INFO "n2: RISCom/N2 %u KB RAM, IRQ%u, " - "using %u TX + %u RX packets rings\n", card->ram_size / 1024, - card->irq, card->tx_ring_buffers, card->rx_ring_buffers); + pr_info("RISCom/N2 %u KB RAM, IRQ%u, using %u TX + %u RX packets rings\n", + card->ram_size / 1024, card->irq, + card->tx_ring_buffers, card->rx_ring_buffers); if (card->tx_ring_buffers < 1) { - printk(KERN_ERR "n2: RAM test failed\n"); + pr_err("RAM test failed\n"); n2_destroy_card(card); return -EIO; } @@ -474,16 +476,14 @@ static int __init n2_run(unsigned long io, unsigned long irq, port->card = card; if (register_hdlc_device(dev)) { - printk(KERN_WARNING "n2: unable to register hdlc " - "device\n"); + pr_warn("unable to register hdlc device\n"); port->card = NULL; n2_destroy_card(card); return -ENOBUFS; } sca_init_port(port); /* Set up SCA memory */ - printk(KERN_INFO "%s: RISCom/N2 node %d\n", - dev->name, port->phy_node); + netdev_info(dev, "RISCom/N2 node %d\n", port->phy_node); } *new_card = card; @@ -498,12 +498,12 @@ static int __init n2_init(void) { if (hw==NULL) { #ifdef MODULE - printk(KERN_INFO "n2: no card initialized\n"); + pr_info("no card initialized\n"); #endif return -EINVAL; /* no parameters specified, abort */ } - printk(KERN_INFO "%s\n", version); + pr_info("%s\n", version); do { unsigned long io, irq, ram; @@ -541,7 +541,7 @@ static int __init n2_init(void) return first_card ? 0 : -EINVAL; }while(*hw++ == ':'); - printk(KERN_ERR "n2: invalid hardware parameters\n"); + pr_err("invalid hardware parameters\n"); return first_card ? 0 : -EINVAL; } diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index c7ab3becd26..c49c1b3c7aa 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c @@ -17,6 +17,8 @@ * PC300/X21 cards. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -318,7 +320,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - printk(KERN_ERR "pc300: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; @@ -328,7 +330,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, if (pci_resource_len(pdev, 0) != PC300_PLX_SIZE || pci_resource_len(pdev, 2) != PC300_SCA_SIZE || pci_resource_len(pdev, 3) < 16384) { - printk(KERN_ERR "pc300: invalid card EEPROM parameters\n"); + pr_err("invalid card EEPROM parameters\n"); pc300_pci_remove_one(pdev); return -EFAULT; } @@ -345,7 +347,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, if (card->plxbase == NULL || card->scabase == NULL || card->rambase == NULL) { - printk(KERN_ERR "pc300: ioremap() failed\n"); + pr_err("ioremap() failed\n"); pc300_pci_remove_one(pdev); } @@ -370,7 +372,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, for (i = 0; i < card->n_ports; i++) if (!(card->ports[i].netdev = alloc_hdlcdev(&card->ports[i]))) { - printk(KERN_ERR "pc300: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); pc300_pci_remove_one(pdev); return -ENOMEM; } @@ -411,15 +413,14 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, card->buff_offset = card->n_ports * sizeof(pkt_desc) * (card->tx_ring_buffers + card->rx_ring_buffers); - printk(KERN_INFO "pc300: PC300/%s, %u KB RAM at 0x%x, IRQ%u, " - "using %u TX + %u RX packets rings\n", - card->type == PC300_X21 ? "X21" : - card->type == PC300_TE ? "TE" : "RSV", - ramsize / 1024, ramphys, pdev->irq, - card->tx_ring_buffers, card->rx_ring_buffers); + pr_info("PC300/%s, %u KB RAM at 0x%x, IRQ%u, using %u TX + %u RX packets rings\n", + card->type == PC300_X21 ? "X21" : + card->type == PC300_TE ? "TE" : "RSV", + ramsize / 1024, ramphys, pdev->irq, + card->tx_ring_buffers, card->rx_ring_buffers); if (card->tx_ring_buffers < 1) { - printk(KERN_ERR "pc300: RAM test failed\n"); + pr_err("RAM test failed\n"); pc300_pci_remove_one(pdev); return -EFAULT; } @@ -429,8 +430,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, /* Allocate IRQ */ if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, "pc300", card)) { - printk(KERN_WARNING "pc300: could not allocate IRQ%d.\n", - pdev->irq); + pr_warn("could not allocate IRQ%d\n", pdev->irq); pc300_pci_remove_one(pdev); return -EBUSY; } @@ -466,15 +466,13 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, sca_init_port(port); if (register_hdlc_device(dev)) { - printk(KERN_ERR "pc300: unable to register hdlc " - "device\n"); + pr_err("unable to register hdlc device\n"); port->card = NULL; pc300_pci_remove_one(pdev); return -ENOBUFS; } - printk(KERN_INFO "%s: PC300 channel %d\n", - dev->name, port->chan); + netdev_info(dev, "PC300 channel %d\n", port->chan); } return 0; } @@ -505,11 +503,11 @@ static struct pci_driver pc300_pci_driver = { static int __init pc300_init_module(void) { if (pci_clock_freq < 1000000 || pci_clock_freq > 80000000) { - printk(KERN_ERR "pc300: Invalid PCI clock frequency\n"); + pr_err("Invalid PCI clock frequency\n"); return -EINVAL; } if (use_crystal_clock != 0 && use_crystal_clock != 1) { - printk(KERN_ERR "pc300: Invalid 'use_crystal_clock' value\n"); + pr_err("Invalid 'use_crystal_clock' value\n"); return -EINVAL; } diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index fd7375955e4..1ce21163c77 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -14,6 +14,8 @@ * PLX Technology Inc. PCI9052 Data Book */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -297,7 +299,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - printk(KERN_ERR "pci200syn: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; @@ -306,7 +308,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, card->ports[0].netdev = alloc_hdlcdev(&card->ports[0]); card->ports[1].netdev = alloc_hdlcdev(&card->ports[1]); if (!card->ports[0].netdev || !card->ports[1].netdev) { - printk(KERN_ERR "pci200syn: unable to allocate memory\n"); + pr_err("unable to allocate memory\n"); pci200_pci_remove_one(pdev); return -ENOMEM; } @@ -314,7 +316,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, if (pci_resource_len(pdev, 0) != PCI200SYN_PLX_SIZE || pci_resource_len(pdev, 2) != PCI200SYN_SCA_SIZE || pci_resource_len(pdev, 3) < 16384) { - printk(KERN_ERR "pci200syn: invalid card EEPROM parameters\n"); + pr_err("invalid card EEPROM parameters\n"); pci200_pci_remove_one(pdev); return -EFAULT; } @@ -331,7 +333,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, if (card->plxbase == NULL || card->scabase == NULL || card->rambase == NULL) { - printk(KERN_ERR "pci200syn: ioremap() failed\n"); + pr_err("ioremap() failed\n"); pci200_pci_remove_one(pdev); return -EFAULT; } @@ -357,12 +359,12 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, card->buff_offset = 2 * sizeof(pkt_desc) * (card->tx_ring_buffers + card->rx_ring_buffers); - printk(KERN_INFO "pci200syn: %u KB RAM at 0x%x, IRQ%u, using %u TX +" - " %u RX packets rings\n", ramsize / 1024, ramphys, - pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers); + pr_info("%u KB RAM at 0x%x, IRQ%u, using %u TX + %u RX packets rings\n", + ramsize / 1024, ramphys, + pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers); if (card->tx_ring_buffers < 1) { - printk(KERN_ERR "pci200syn: RAM test failed\n"); + pr_err("RAM test failed\n"); pci200_pci_remove_one(pdev); return -EFAULT; } @@ -373,8 +375,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, /* Allocate IRQ */ if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, "pci200syn", card)) { - printk(KERN_WARNING "pci200syn: could not allocate IRQ%d.\n", - pdev->irq); + pr_warn("could not allocate IRQ%d\n", pdev->irq); pci200_pci_remove_one(pdev); return -EBUSY; } @@ -400,15 +401,13 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, port->card = card; sca_init_port(port); if (register_hdlc_device(dev)) { - printk(KERN_ERR "pci200syn: unable to register hdlc " - "device\n"); + pr_err("unable to register hdlc device\n"); port->card = NULL; pci200_pci_remove_one(pdev); return -ENOBUFS; } - printk(KERN_INFO "%s: PCI200SYN channel %d\n", - dev->name, port->chan); + netdev_info(dev, "PCI200SYN channel %d\n", port->chan); } sca_flush(card); @@ -435,7 +434,7 @@ static struct pci_driver pci200_pci_driver = { static int __init pci200_init_module(void) { if (pci_clock_freq < 1000000 || pci_clock_freq > 80000000) { - printk(KERN_ERR "pci200syn: Invalid PCI clock frequency\n"); + pr_err("Invalid PCI clock frequency\n"); return -EINVAL; } return pci_register_driver(&pci200_pci_driver); diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 4ea89fe0006..8d7aa43dfba 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -13,6 +13,8 @@ * - wanXL100 will require minor driver modifications, no access to hw */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -102,9 +104,8 @@ static inline dma_addr_t pci_map_single_debug(struct pci_dev *pdev, void *ptr, { dma_addr_t addr = pci_map_single(pdev, ptr, size, direction); if (addr + size > 0x100000000LL) - printk(KERN_CRIT "wanXL %s: pci_map_single() returned memory" - " at 0x%LX!\n", pci_name(pdev), - (unsigned long long)addr); + pr_crit("%s: pci_map_single() returned memory at 0x%llx!\n", + pci_name(pdev), (unsigned long long)addr); return addr; } @@ -147,8 +148,8 @@ static inline void wanxl_cable_intr(port_t *port) } dte = (value & STATUS_CABLE_DCE) ? " DCE" : " DTE"; } - printk(KERN_INFO "%s: %s%s module, %s cable%s%s\n", - port->dev->name, pm, dte, cable, dsr, dcd); + netdev_info(port->dev, "%s%s module, %s cable%s%s\n", + pm, dte, cable, dsr, dcd); if (value & STATUS_CABLE_DCD) netif_carrier_on(port->dev); @@ -198,8 +199,8 @@ static inline void wanxl_rx_intr(card_t *card) while (desc = &card->status->rx_descs[card->rx_in], desc->stat != PACKET_EMPTY) { if ((desc->stat & PACKET_PORT_MASK) > card->n_ports) - printk(KERN_CRIT "wanXL %s: received packet for" - " nonexistent port\n", pci_name(card->pdev)); + pr_crit("%s: received packet for nonexistent port\n", + pci_name(card->pdev)); else { struct sk_buff *skb = card->rx_skbs[card->rx_in]; port_t *port = &card->ports[desc->stat & @@ -397,7 +398,7 @@ static int wanxl_open(struct net_device *dev) int i; if (get_status(port)->open) { - printk(KERN_ERR "%s: port already open\n", dev->name); + netdev_err(dev, "port already open\n"); return -EIO; } if ((i = hdlc_open(dev)) != 0) @@ -417,7 +418,7 @@ static int wanxl_open(struct net_device *dev) } } while (time_after(timeout, jiffies)); - printk(KERN_ERR "%s: unable to open port\n", dev->name); + netdev_err(dev, "unable to open port\n"); /* ask the card to close the port, should it be still alive */ writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr); return -EFAULT; @@ -443,7 +444,7 @@ static int wanxl_close(struct net_device *dev) } while (time_after(timeout, jiffies)); if (get_status(port)->open) - printk(KERN_ERR "%s: unable to close port\n", dev->name); + netdev_err(dev, "unable to close port\n"); netif_stop_queue(dev); @@ -568,11 +569,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, int i, ports, alloc_size; #ifndef MODULE - static int printed_version; - if (!printed_version) { - printed_version++; - printk(KERN_INFO "%s\n", version); - } + pr_info_once("%s\n", version); #endif i = pci_enable_device(pdev); @@ -588,7 +585,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, work on most platforms */ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(28)) || pci_set_dma_mask(pdev, DMA_BIT_MASK(28))) { - printk(KERN_ERR "wanXL: No usable DMA configuration\n"); + pr_err("No usable DMA configuration\n"); return -EIO; } @@ -607,8 +604,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, alloc_size = sizeof(card_t) + ports * sizeof(port_t); card = kzalloc(alloc_size, GFP_KERNEL); if (card == NULL) { - printk(KERN_ERR "wanXL %s: unable to allocate memory\n", - pci_name(pdev)); + pr_err("%s: unable to allocate memory\n", pci_name(pdev)); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; @@ -635,7 +631,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, to indicate the card can do 32-bit DMA addressing */ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) || pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { - printk(KERN_ERR "wanXL: No usable DMA configuration\n"); + pr_err("No usable DMA configuration\n"); wanxl_pci_remove_one(pdev); return -EIO; } @@ -645,7 +641,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, card->plx = ioremap_nocache(plx_phy, 0x70); if (!card->plx) { - printk(KERN_ERR "wanxl: ioremap() failed\n"); + pr_err("ioremap() failed\n"); wanxl_pci_remove_one(pdev); return -EFAULT; } @@ -657,8 +653,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, timeout = jiffies + 20 * HZ; while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) { if (time_before(timeout, jiffies)) { - printk(KERN_WARNING "wanXL %s: timeout waiting for" - " PUTS to complete\n", pci_name(pdev)); + pr_warn("%s: timeout waiting for PUTS to complete\n", + pci_name(pdev)); wanxl_pci_remove_one(pdev); return -ENODEV; } @@ -669,8 +665,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, break; default: - printk(KERN_WARNING "wanXL %s: PUTS test 0x%X" - " failed\n", pci_name(pdev), stat & 0x30); + pr_warn("%s: PUTS test 0x%X failed\n", + pci_name(pdev), stat & 0x30); wanxl_pci_remove_one(pdev); return -ENODEV; } @@ -688,17 +684,16 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, /* sanity check the board's reported memory size */ if (ramsize < BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * ports) { - printk(KERN_WARNING "wanXL %s: no enough on-board RAM" - " (%u bytes detected, %u bytes required)\n", - pci_name(pdev), ramsize, BUFFERS_ADDR + - (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * ports); + pr_warn("%s: no enough on-board RAM (%u bytes detected, %u bytes required)\n", + pci_name(pdev), ramsize, + BUFFERS_ADDR + + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * ports); wanxl_pci_remove_one(pdev); return -ENODEV; } if (wanxl_puts_command(card, MBX1_CMD_BSWAP)) { - printk(KERN_WARNING "wanXL %s: unable to Set Byte Swap" - " Mode\n", pci_name(pdev)); + pr_warn("%s: unable to Set Byte Swap Mode\n", pci_name(pdev)); wanxl_pci_remove_one(pdev); return -ENODEV; } @@ -715,7 +710,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, mem = ioremap_nocache(mem_phy, PDM_OFFSET + sizeof(firmware)); if (!mem) { - printk(KERN_ERR "wanxl: ioremap() failed\n"); + pr_err("ioremap() failed\n"); wanxl_pci_remove_one(pdev); return -EFAULT; } @@ -734,8 +729,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, writel(0, card->plx + PLX_MAILBOX_5); if (wanxl_puts_command(card, MBX1_CMD_ABORTJ)) { - printk(KERN_WARNING "wanXL %s: unable to Abort and Jump\n", - pci_name(pdev)); + pr_warn("%s: unable to Abort and Jump\n", pci_name(pdev)); wanxl_pci_remove_one(pdev); return -ENODEV; } @@ -749,8 +743,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, }while (time_after(timeout, jiffies)); if (!stat) { - printk(KERN_WARNING "wanXL %s: timeout while initializing card " - "firmware\n", pci_name(pdev)); + pr_warn("%s: timeout while initializing card firmware\n", + pci_name(pdev)); wanxl_pci_remove_one(pdev); return -ENODEV; } @@ -759,13 +753,13 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, ramsize = stat; #endif - printk(KERN_INFO "wanXL %s: at 0x%X, %u KB of RAM at 0x%X, irq %u\n", - pci_name(pdev), plx_phy, ramsize / 1024, mem_phy, pdev->irq); + pr_info("%s: at 0x%X, %u KB of RAM at 0x%X, irq %u\n", + pci_name(pdev), plx_phy, ramsize / 1024, mem_phy, pdev->irq); /* Allocate IRQ */ if (request_irq(pdev->irq, wanxl_intr, IRQF_SHARED, "wanXL", card)) { - printk(KERN_WARNING "wanXL %s: could not allocate IRQ%i.\n", - pci_name(pdev), pdev->irq); + pr_warn("%s: could not allocate IRQ%i\n", + pci_name(pdev), pdev->irq); wanxl_pci_remove_one(pdev); return -EBUSY; } @@ -776,8 +770,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, port_t *port = &card->ports[i]; struct net_device *dev = alloc_hdlcdev(port); if (!dev) { - printk(KERN_ERR "wanXL %s: unable to allocate" - " memory\n", pci_name(pdev)); + pr_err("%s: unable to allocate memory\n", + pci_name(pdev)); wanxl_pci_remove_one(pdev); return -ENOMEM; } @@ -793,8 +787,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, port->node = i; get_status(port)->clocking = CLOCK_EXT; if (register_hdlc_device(dev)) { - printk(KERN_ERR "wanXL %s: unable to register hdlc" - " device\n", pci_name(pdev)); + pr_err("%s: unable to register hdlc device\n", + pci_name(pdev)); free_netdev(dev); wanxl_pci_remove_one(pdev); return -ENOBUFS; @@ -802,11 +796,11 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, card->n_ports++; } - printk(KERN_INFO "wanXL %s: port", pci_name(pdev)); + pr_info("%s: port", pci_name(pdev)); for (i = 0; i < ports; i++) - printk("%s #%i: %s", i ? "," : "", i, - card->ports[i].dev->name); - printk("\n"); + pr_cont("%s #%i: %s", + i ? "," : "", i, card->ports[i].dev->name); + pr_cont("\n"); for (i = 0; i < ports; i++) wanxl_cable_intr(&card->ports[i]); /* get carrier status etc.*/ @@ -836,7 +830,7 @@ static struct pci_driver wanxl_pci_driver = { static int __init wanxl_init_module(void) { #ifdef MODULE - printk(KERN_INFO "%s\n", version); + pr_info("%s\n", version); #endif return pci_register_driver(&wanxl_pci_driver); } -- cgit v1.2.3-70-g09d2 From 9cbe50d4231773396f529f51a048770d0ee54ac1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:29 +0000 Subject: cosa: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/cosa.c | 226 +++++++++++++++++++++++-------------------------- 1 file changed, 106 insertions(+), 120 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 6fb6f8e667d..6aed238e573 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -74,6 +74,8 @@ * The Sync PPP/Cisco HDLC layer (syncppp.c) ported to Linux by Alan Cox */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -361,14 +363,13 @@ static int __init cosa_init(void) if (cosa_major > 0) { if (register_chrdev(cosa_major, "cosa", &cosa_fops)) { - printk(KERN_WARNING "cosa: unable to get major %d\n", - cosa_major); + pr_warn("unable to get major %d\n", cosa_major); err = -EIO; goto out; } } else { if (!(cosa_major=register_chrdev(0, "cosa", &cosa_fops))) { - printk(KERN_WARNING "cosa: unable to register chardev\n"); + pr_warn("unable to register chardev\n"); err = -EIO; goto out; } @@ -378,7 +379,7 @@ static int __init cosa_init(void) for (i=0; io[i] != 0 && i < MAX_CARDS; i++) cosa_probe(io[i], irq[i], dma[i]); if (!nr_cards) { - printk(KERN_WARNING "cosa: no devices found.\n"); + pr_warn("no devices found\n"); unregister_chrdev(cosa_major, "cosa"); err = -ENODEV; goto out; @@ -447,26 +448,25 @@ static int cosa_probe(int base, int irq, int dma) /* Checking validity of parameters: */ /* IRQ should be 2-7 or 10-15; negative IRQ means autoprobe */ if ((irq >= 0 && irq < 2) || irq > 15 || (irq < 10 && irq > 7)) { - printk (KERN_INFO "cosa_probe: invalid IRQ %d\n", irq); + pr_info("invalid IRQ %d\n", irq); return -1; } /* I/O address should be between 0x100 and 0x3ff and should be * multiple of 8. */ if (base < 0x100 || base > 0x3ff || base & 0x7) { - printk (KERN_INFO "cosa_probe: invalid I/O address 0x%x\n", - base); + pr_info("invalid I/O address 0x%x\n", base); return -1; } /* DMA should be 0,1 or 3-7 */ if (dma < 0 || dma == 4 || dma > 7) { - printk (KERN_INFO "cosa_probe: invalid DMA %d\n", dma); + pr_info("invalid DMA %d\n", dma); return -1; } /* and finally, on 16-bit COSA DMA should be 4-7 and * I/O base should not be multiple of 0x10 */ if (((base & 0x8) && dma < 4) || (!(base & 0x8) && dma > 3)) { - printk (KERN_INFO "cosa_probe: 8/16 bit base and DMA mismatch" - " (base=0x%x, dma=%d)\n", base, dma); + pr_info("8/16 bit base and DMA mismatch (base=0x%x, dma=%d)\n", + base, dma); return -1; } @@ -479,7 +479,7 @@ static int cosa_probe(int base, int irq, int dma) return -1; if (cosa_reset_and_read_id(cosa, cosa->id_string) < 0) { - printk(KERN_DEBUG "cosa: probe at 0x%x failed.\n", base); + printk(KERN_DEBUG "probe at 0x%x failed.\n", base); err = -1; goto err_out; } @@ -492,8 +492,7 @@ static int cosa_probe(int base, int irq, int dma) else { /* Print a warning only if we are not autoprobing */ #ifndef COSA_ISA_AUTOPROBE - printk(KERN_INFO "cosa: valid signature not found at 0x%x.\n", - base); + pr_info("valid signature not found at 0x%x\n", base); #endif err = -1; goto err_out; @@ -501,14 +500,14 @@ static int cosa_probe(int base, int irq, int dma) /* Update the name of the region now we know the type of card */ release_region(base, is_8bit(cosa)?2:4); if (!request_region(base, is_8bit(cosa)?2:4, cosa->type)) { - printk(KERN_DEBUG "cosa: changing name at 0x%x failed.\n", base); + printk(KERN_DEBUG "changing name at 0x%x failed.\n", base); return -1; } /* Now do IRQ autoprobe */ if (irq < 0) { unsigned long irqs; -/* printk(KERN_INFO "IRQ autoprobe\n"); */ +/* pr_info("IRQ autoprobe\n"); */ irqs = probe_irq_on(); /* * Enable interrupt on tx buffer empty (it sure is) @@ -526,13 +525,13 @@ static int cosa_probe(int base, int irq, int dma) cosa_getdata8(cosa); if (irq < 0) { - printk (KERN_INFO "cosa IRQ autoprobe: multiple interrupts obtained (%d, board at 0x%x)\n", + pr_info("multiple interrupts obtained (%d, board at 0x%x)\n", irq, cosa->datareg); err = -1; goto err_out; } if (irq == 0) { - printk (KERN_INFO "cosa IRQ autoprobe: no interrupt obtained (board at 0x%x)\n", + pr_info("no interrupt obtained (board at 0x%x)\n", cosa->datareg); /* return -1; */ } @@ -579,8 +578,7 @@ static int cosa_probe(int base, int irq, int dma) /* Register the network interface */ if (!(chan->netdev = alloc_hdlcdev(chan))) { - printk(KERN_WARNING "%s: alloc_hdlcdev failed.\n", - chan->name); + pr_warn("%s: alloc_hdlcdev failed\n", chan->name); goto err_hdlcdev; } dev_to_hdlc(chan->netdev)->attach = cosa_net_attach; @@ -591,14 +589,14 @@ static int cosa_probe(int base, int irq, int dma) chan->netdev->irq = chan->cosa->irq; chan->netdev->dma = chan->cosa->dma; if (register_hdlc_device(chan->netdev)) { - printk(KERN_WARNING "%s: register_hdlc_device()" - " failed.\n", chan->netdev->name); + netdev_warn(chan->netdev, + "register_hdlc_device() failed\n"); free_netdev(chan->netdev); goto err_hdlcdev; } } - printk (KERN_INFO "cosa%d: %s (%s at 0x%x irq %d dma %d), %d channels\n", + pr_info("cosa%d: %s (%s at 0x%x irq %d dma %d), %d channels\n", cosa->num, cosa->id_string, cosa->type, cosa->datareg, cosa->irq, cosa->dma, cosa->nchannels); @@ -618,8 +616,7 @@ err_out1: free_irq(cosa->irq, cosa); err_out: release_region(cosa->datareg,is_8bit(cosa)?2:4); - printk(KERN_NOTICE "cosa%d: allocating resources failed\n", - cosa->num); + pr_notice("cosa%d: allocating resources failed\n", cosa->num); return err; } @@ -641,14 +638,14 @@ static int cosa_net_open(struct net_device *dev) unsigned long flags; if (!(chan->cosa->firmware_status & COSA_FW_START)) { - printk(KERN_NOTICE "%s: start the firmware first (status %d)\n", - chan->cosa->name, chan->cosa->firmware_status); + pr_notice("%s: start the firmware first (status %d)\n", + chan->cosa->name, chan->cosa->firmware_status); return -EPERM; } spin_lock_irqsave(&chan->cosa->lock, flags); if (chan->usage != 0) { - printk(KERN_WARNING "%s: cosa_net_open called with usage count" - " %d\n", chan->name, chan->usage); + pr_warn("%s: cosa_net_open called with usage count %d\n", + chan->name, chan->usage); spin_unlock_irqrestore(&chan->cosa->lock, flags); return -EBUSY; } @@ -736,8 +733,7 @@ static char *cosa_net_setup_rx(struct channel_data *chan, int size) kfree_skb(chan->rx_skb); chan->rx_skb = dev_alloc_skb(size); if (chan->rx_skb == NULL) { - printk(KERN_NOTICE "%s: Memory squeeze, dropping packet\n", - chan->name); + pr_notice("%s: Memory squeeze, dropping packet\n", chan->name); chan->netdev->stats.rx_dropped++; return NULL; } @@ -748,8 +744,7 @@ static char *cosa_net_setup_rx(struct channel_data *chan, int size) static int cosa_net_rx_done(struct channel_data *chan) { if (!chan->rx_skb) { - printk(KERN_WARNING "%s: rx_done with empty skb!\n", - chan->name); + pr_warn("%s: rx_done with empty skb!\n", chan->name); chan->netdev->stats.rx_errors++; chan->netdev->stats.rx_frame_errors++; return 0; @@ -768,8 +763,7 @@ static int cosa_net_rx_done(struct channel_data *chan) static int cosa_net_tx_done(struct channel_data *chan, int size) { if (!chan->tx_skb) { - printk(KERN_WARNING "%s: tx_done with empty skb!\n", - chan->name); + pr_warn("%s: tx_done with empty skb!\n", chan->name); chan->netdev->stats.tx_errors++; chan->netdev->stats.tx_aborted_errors++; return 1; @@ -794,15 +788,15 @@ static ssize_t cosa_read(struct file *file, char *kbuf; if (!(cosa->firmware_status & COSA_FW_START)) { - printk(KERN_NOTICE "%s: start the firmware first (status %d)\n", - cosa->name, cosa->firmware_status); + pr_notice("%s: start the firmware first (status %d)\n", + cosa->name, cosa->firmware_status); return -EPERM; } if (mutex_lock_interruptible(&chan->rlock)) return -ERESTARTSYS; if ((chan->rxdata = kmalloc(COSA_MTU, GFP_DMA|GFP_KERNEL)) == NULL) { - printk(KERN_INFO "%s: cosa_read() - OOM\n", cosa->name); + pr_info("%s: cosa_read() - OOM\n", cosa->name); mutex_unlock(&chan->rlock); return -ENOMEM; } @@ -869,8 +863,8 @@ static ssize_t cosa_write(struct file *file, char *kbuf; if (!(cosa->firmware_status & COSA_FW_START)) { - printk(KERN_NOTICE "%s: start the firmware first (status %d)\n", - cosa->name, cosa->firmware_status); + pr_notice("%s: start the firmware first (status %d)\n", + cosa->name, cosa->firmware_status); return -EPERM; } if (down_interruptible(&chan->wsem)) @@ -881,8 +875,8 @@ static ssize_t cosa_write(struct file *file, /* Allocate the buffer */ if ((kbuf = kmalloc(count, GFP_KERNEL|GFP_DMA)) == NULL) { - printk(KERN_NOTICE "%s: cosa_write() OOM - dropping packet\n", - cosa->name); + pr_notice("%s: cosa_write() OOM - dropping packet\n", + cosa->name); up(&chan->wsem); return -ENOMEM; } @@ -932,7 +926,7 @@ static int chrdev_tx_done(struct channel_data *chan, int size) static unsigned int cosa_poll(struct file *file, poll_table *poll) { - printk(KERN_INFO "cosa_poll is here\n"); + pr_info("cosa_poll is here\n"); return 0; } @@ -1017,15 +1011,14 @@ static inline int cosa_reset(struct cosa_data *cosa) { char idstring[COSA_MAX_ID_STRING]; if (cosa->usage > 1) - printk(KERN_INFO "cosa%d: WARNING: reset requested with cosa->usage > 1 (%d). Odd things may happen.\n", + pr_info("cosa%d: WARNING: reset requested with cosa->usage > 1 (%d). Odd things may happen.\n", cosa->num, cosa->usage); cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_START); if (cosa_reset_and_read_id(cosa, idstring) < 0) { - printk(KERN_NOTICE "cosa%d: reset failed\n", cosa->num); + pr_notice("cosa%d: reset failed\n", cosa->num); return -EIO; } - printk(KERN_INFO "cosa%d: resetting device: %s\n", cosa->num, - idstring); + pr_info("cosa%d: resetting device: %s\n", cosa->num, idstring); cosa->firmware_status |= COSA_FW_RESET; return 0; } @@ -1037,11 +1030,11 @@ static inline int cosa_download(struct cosa_data *cosa, void __user *arg) int i; if (cosa->usage > 1) - printk(KERN_INFO "%s: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n", + pr_info("%s: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n", cosa->name, cosa->usage); if (!(cosa->firmware_status & COSA_FW_RESET)) { - printk(KERN_NOTICE "%s: reset the card first (status %d).\n", - cosa->name, cosa->firmware_status); + pr_notice("%s: reset the card first (status %d)\n", + cosa->name, cosa->firmware_status); return -EPERM; } @@ -1059,11 +1052,11 @@ static inline int cosa_download(struct cosa_data *cosa, void __user *arg) i = download(cosa, d.code, d.len, d.addr); if (i < 0) { - printk(KERN_NOTICE "cosa%d: microcode download failed: %d\n", - cosa->num, i); + pr_notice("cosa%d: microcode download failed: %d\n", + cosa->num, i); return -EIO; } - printk(KERN_INFO "cosa%d: downloading microcode - 0x%04x bytes at 0x%04x\n", + pr_info("cosa%d: downloading microcode - 0x%04x bytes at 0x%04x\n", cosa->num, d.len, d.addr); cosa->firmware_status |= COSA_FW_RESET|COSA_FW_DOWNLOAD; return 0; @@ -1076,12 +1069,11 @@ static inline int cosa_readmem(struct cosa_data *cosa, void __user *arg) int i; if (cosa->usage > 1) - printk(KERN_INFO "cosa%d: WARNING: readmem requested with " - "cosa->usage > 1 (%d). Odd things may happen.\n", + pr_info("cosa%d: WARNING: readmem requested with cosa->usage > 1 (%d). Odd things may happen.\n", cosa->num, cosa->usage); if (!(cosa->firmware_status & COSA_FW_RESET)) { - printk(KERN_NOTICE "%s: reset the card first (status %d).\n", - cosa->name, cosa->firmware_status); + pr_notice("%s: reset the card first (status %d)\n", + cosa->name, cosa->firmware_status); return -EPERM; } @@ -1093,11 +1085,10 @@ static inline int cosa_readmem(struct cosa_data *cosa, void __user *arg) i = readmem(cosa, d.code, d.len, d.addr); if (i < 0) { - printk(KERN_NOTICE "cosa%d: reading memory failed: %d\n", - cosa->num, i); + pr_notice("cosa%d: reading memory failed: %d\n", cosa->num, i); return -EIO; } - printk(KERN_INFO "cosa%d: reading card memory - 0x%04x bytes at 0x%04x\n", + pr_info("cosa%d: reading card memory - 0x%04x bytes at 0x%04x\n", cosa->num, d.len, d.addr); cosa->firmware_status |= COSA_FW_RESET; return 0; @@ -1109,23 +1100,22 @@ static inline int cosa_start(struct cosa_data *cosa, int address) int i; if (cosa->usage > 1) - printk(KERN_INFO "cosa%d: WARNING: start microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n", + pr_info("cosa%d: WARNING: start microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n", cosa->num, cosa->usage); if ((cosa->firmware_status & (COSA_FW_RESET|COSA_FW_DOWNLOAD)) != (COSA_FW_RESET|COSA_FW_DOWNLOAD)) { - printk(KERN_NOTICE "%s: download the microcode and/or reset the card first (status %d).\n", - cosa->name, cosa->firmware_status); + pr_notice("%s: download the microcode and/or reset the card first (status %d)\n", + cosa->name, cosa->firmware_status); return -EPERM; } cosa->firmware_status &= ~COSA_FW_RESET; if ((i=startmicrocode(cosa, address)) < 0) { - printk(KERN_NOTICE "cosa%d: start microcode at 0x%04x failed: %d\n", - cosa->num, address, i); + pr_notice("cosa%d: start microcode at 0x%04x failed: %d\n", + cosa->num, address, i); return -EIO; } - printk(KERN_INFO "cosa%d: starting microcode at 0x%04x\n", - cosa->num, address); + pr_info("cosa%d: starting microcode at 0x%04x\n", cosa->num, address); cosa->startaddr = address; cosa->firmware_status |= COSA_FW_START; return 0; @@ -1255,11 +1245,11 @@ static int cosa_start_tx(struct channel_data *chan, char *buf, int len) #ifdef DEBUG_DATA int i; - printk(KERN_INFO "cosa%dc%d: starting tx(0x%x)", chan->cosa->num, - chan->num, len); + pr_info("cosa%dc%d: starting tx(0x%x)", + chan->cosa->num, chan->num, len); for (i=0; ilock, flags); chan->txbuf = buf; @@ -1353,7 +1343,7 @@ static void cosa_kick(struct cosa_data *cosa) if (test_bit(TXBIT, &cosa->rxtx)) s = "TX DMA"; - printk(KERN_INFO "%s: %s timeout - restarting.\n", cosa->name, s); + pr_info("%s: %s timeout - restarting\n", cosa->name, s); spin_lock_irqsave(&cosa->lock, flags); cosa->rxtx = 0; @@ -1387,7 +1377,7 @@ static int cosa_dma_able(struct channel_data *chan, char *buf, int len) return 0; if ((b^ (b+len)) & 0x10000) { if (count++ < 5) - printk(KERN_INFO "%s: packet spanning a 64k boundary\n", + pr_info("%s: packet spanning a 64k boundary\n", chan->name); return 0; } @@ -1498,8 +1488,7 @@ static int readmem(struct cosa_data *cosa, char __user *microcode, int length, i char c; int i; if ((i=get_wait_data(cosa)) == -1) { - printk (KERN_INFO "cosa: 0x%04x bytes remaining\n", - length); + pr_info("0x%04x bytes remaining\n", length); return -11; } c=i; @@ -1582,14 +1571,15 @@ static int get_wait_data(struct cosa_data *cosa) short r; r = cosa_getdata8(cosa); #if 0 - printk(KERN_INFO "cosa: get_wait_data returning after %d retries\n", 999-retries); + pr_info("get_wait_data returning after %d retries\n", + 999-retries); #endif return r; } /* sleep if not ready to read */ schedule_timeout_interruptible(1); } - printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n", + pr_info("timeout in get_wait_data (status 0x%x)\n", cosa_getstatus(cosa)); return -1; } @@ -1607,7 +1597,7 @@ static int put_wait_data(struct cosa_data *cosa, int data) if (cosa_getstatus(cosa) & SR_TX_RDY) { cosa_putdata8(cosa, data); #if 0 - printk(KERN_INFO "Putdata: %d retries\n", 999-retries); + pr_info("Putdata: %d retries\n", 999-retries); #endif return 0; } @@ -1616,7 +1606,7 @@ static int put_wait_data(struct cosa_data *cosa, int data) schedule_timeout_interruptible(1); #endif } - printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n", + pr_info("cosa%d: timeout in put_wait_data (status 0x%x)\n", cosa->num, cosa_getstatus(cosa)); return -1; } @@ -1636,13 +1626,13 @@ static int puthexnumber(struct cosa_data *cosa, int number) sprintf(temp, "%04X", number); for (i=0; i<4; i++) { if (put_wait_data(cosa, temp[i]) == -1) { - printk(KERN_NOTICE "cosa%d: puthexnumber failed to write byte %d\n", - cosa->num, i); + pr_notice("cosa%d: puthexnumber failed to write byte %d\n", + cosa->num, i); return -1-2*i; } if (get_wait_data(cosa) != temp[i]) { - printk(KERN_NOTICE "cosa%d: puthexhumber failed to read echo of byte %d\n", - cosa->num, i); + pr_notice("cosa%d: puthexhumber failed to read echo of byte %d\n", + cosa->num, i); return -2-2*i; } } @@ -1687,8 +1677,7 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status) { unsigned long flags, flags1; #ifdef DEBUG_IRQS - printk(KERN_INFO "cosa%d: SR_DOWN_REQUEST status=0x%04x\n", - cosa->num, status); + pr_info("cosa%d: SR_DOWN_REQUEST status=0x%04x\n", cosa->num, status); #endif spin_lock_irqsave(&cosa->lock, flags); set_bit(TXBIT, &cosa->rxtx); @@ -1696,8 +1685,7 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status) /* flow control, see the comment above */ int i=0; if (!cosa->txbitmap) { - printk(KERN_WARNING "%s: No channel wants data " - "in TX IRQ. Expect DMA timeout.", + pr_warn("%s: No channel wants data in TX IRQ. Expect DMA timeout.\n", cosa->name); put_driver_status_nolock(cosa); clear_bit(TXBIT, &cosa->rxtx); @@ -1780,14 +1768,14 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status) if (cosa->busmaster) { unsigned long addr = virt_to_bus(cosa->txbuf); int count=0; - printk(KERN_INFO "busmaster IRQ\n"); + pr_info("busmaster IRQ\n"); while (!(cosa_getstatus(cosa)&SR_TX_RDY)) { count++; udelay(10); if (count > 1000) break; } - printk(KERN_INFO "status %x\n", cosa_getstatus(cosa)); - printk(KERN_INFO "ready after %d loops\n", count); + pr_info("status %x\n", cosa_getstatus(cosa)); + pr_info("ready after %d loops\n", count); cosa_putdata16(cosa, (addr >> 16)&0xffff); count = 0; @@ -1796,7 +1784,7 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status) if (count > 1000) break; udelay(10); } - printk(KERN_INFO "ready after %d loops\n", count); + pr_info("ready after %d loops\n", count); cosa_putdata16(cosa, addr &0xffff); flags1 = claim_dma_lock(); set_dma_mode(cosa->dma, DMA_MODE_CASCADE); @@ -1824,7 +1812,7 @@ static inline void rx_interrupt(struct cosa_data *cosa, int status) { unsigned long flags; #ifdef DEBUG_IRQS - printk(KERN_INFO "cosa%d: SR_UP_REQUEST\n", cosa->num); + pr_info("cosa%d: SR_UP_REQUEST\n", cosa->num); #endif spin_lock_irqsave(&cosa->lock, flags); @@ -1847,7 +1835,7 @@ static inline void rx_interrupt(struct cosa_data *cosa, int status) debug_data_in(cosa, cosa->rxsize & 0xff); #endif #if 0 - printk(KERN_INFO "cosa%d: receive rxsize = (0x%04x).\n", + pr_info("cosa%d: receive rxsize = (0x%04x)\n", cosa->num, cosa->rxsize); #endif } @@ -1857,12 +1845,12 @@ static inline void rx_interrupt(struct cosa_data *cosa, int status) debug_data_in(cosa, cosa->rxsize); #endif #if 0 - printk(KERN_INFO "cosa%d: receive rxsize = (0x%04x).\n", + pr_info("cosa%d: receive rxsize = (0x%04x)\n", cosa->num, cosa->rxsize); #endif } if (((cosa->rxsize & 0xe000) >> 13) >= cosa->nchannels) { - printk(KERN_WARNING "%s: rx for unknown channel (0x%04x)\n", + pr_warn("%s: rx for unknown channel (0x%04x)\n", cosa->name, cosa->rxsize); spin_unlock_irqrestore(&cosa->lock, flags); goto reject; @@ -1877,7 +1865,7 @@ static inline void rx_interrupt(struct cosa_data *cosa, int status) if (!cosa->rxbuf) { reject: /* Reject the packet */ - printk(KERN_INFO "cosa%d: rejecting packet on channel %d\n", + pr_info("cosa%d: rejecting packet on channel %d\n", cosa->num, cosa->rxchan->num); cosa->rxbuf = cosa->bouncebuf; } @@ -1924,11 +1912,11 @@ static inline void eot_interrupt(struct cosa_data *cosa, int status) #ifdef DEBUG_DATA { int i; - printk(KERN_INFO "cosa%dc%d: done rx(0x%x)", cosa->num, - cosa->rxchan->num, cosa->rxsize); + pr_info("cosa%dc%d: done rx(0x%x)", + cosa->num, cosa->rxchan->num, cosa->rxsize); for (i=0; irxsize; i++) - printk (" %02x", cosa->rxbuf[i]&0xff); - printk("\n"); + pr_cont(" %02x", cosa->rxbuf[i]&0xff); + pr_cont("\n"); } #endif /* Packet for unknown channel? */ @@ -1940,8 +1928,7 @@ static inline void eot_interrupt(struct cosa_data *cosa, int status) if (cosa->rxchan->rx_done(cosa->rxchan)) clear_bit(cosa->rxchan->num, &cosa->rxbitmap); } else { - printk(KERN_NOTICE "cosa%d: unexpected EOT interrupt\n", - cosa->num); + pr_notice("cosa%d: unexpected EOT interrupt\n", cosa->num); } /* * Clear the RXBIT, TXBIT and IRQBIT (the latest should be @@ -1963,8 +1950,7 @@ static irqreturn_t cosa_interrupt(int irq, void *cosa_) again: status = cosa_getstatus(cosa); #ifdef DEBUG_IRQS - printk(KERN_INFO "cosa%d: got IRQ, status 0x%02x\n", cosa->num, - status & 0xff); + pr_info("cosa%d: got IRQ, status 0x%02x\n", cosa->num, status & 0xff); #endif #ifdef DEBUG_IO debug_status_in(cosa, status); @@ -1985,15 +1971,15 @@ again: udelay(100); goto again; } - printk(KERN_INFO "cosa%d: unknown status 0x%02x in IRQ after %d retries\n", + pr_info("cosa%d: unknown status 0x%02x in IRQ after %d retries\n", cosa->num, status & 0xff, count); } #ifdef DEBUG_IRQS if (count) - printk(KERN_INFO "%s: %d-times got unknown status in IRQ\n", + pr_info("%s: %d-times got unknown status in IRQ\n", cosa->name, count); else - printk(KERN_INFO "%s: returning from IRQ\n", cosa->name); + pr_info("%s: returning from IRQ\n", cosa->name); #endif return IRQ_HANDLED; } @@ -2024,41 +2010,41 @@ static void debug_status_in(struct cosa_data *cosa, int status) s = "NO_REQ"; break; } - printk(KERN_INFO "%s: IO: status -> 0x%02x (%s%s%s%s)\n", + pr_info("%s: IO: status -> 0x%02x (%s%s%s%s)\n", cosa->name, status, - status & SR_USR_RQ ? "USR_RQ|":"", - status & SR_TX_RDY ? "TX_RDY|":"", - status & SR_RX_RDY ? "RX_RDY|":"", + status & SR_USR_RQ ? "USR_RQ|" : "", + status & SR_TX_RDY ? "TX_RDY|" : "", + status & SR_RX_RDY ? "RX_RDY|" : "", s); } static void debug_status_out(struct cosa_data *cosa, int status) { - printk(KERN_INFO "%s: IO: status <- 0x%02x (%s%s%s%s%s%s)\n", + pr_info("%s: IO: status <- 0x%02x (%s%s%s%s%s%s)\n", cosa->name, status, - status & SR_RX_DMA_ENA ? "RXDMA|":"!rxdma|", - status & SR_TX_DMA_ENA ? "TXDMA|":"!txdma|", - status & SR_RST ? "RESET|":"", - status & SR_USR_INT_ENA ? "USRINT|":"!usrint|", - status & SR_TX_INT_ENA ? "TXINT|":"!txint|", - status & SR_RX_INT_ENA ? "RXINT":"!rxint"); + status & SR_RX_DMA_ENA ? "RXDMA|" : "!rxdma|", + status & SR_TX_DMA_ENA ? "TXDMA|" : "!txdma|", + status & SR_RST ? "RESET|" : "", + status & SR_USR_INT_ENA ? "USRINT|" : "!usrint|", + status & SR_TX_INT_ENA ? "TXINT|" : "!txint|", + status & SR_RX_INT_ENA ? "RXINT" : "!rxint"); } static void debug_data_in(struct cosa_data *cosa, int data) { - printk(KERN_INFO "%s: IO: data -> 0x%04x\n", cosa->name, data); + pr_info("%s: IO: data -> 0x%04x\n", cosa->name, data); } static void debug_data_out(struct cosa_data *cosa, int data) { - printk(KERN_INFO "%s: IO: data <- 0x%04x\n", cosa->name, data); + pr_info("%s: IO: data <- 0x%04x\n", cosa->name, data); } static void debug_data_cmd(struct cosa_data *cosa, int data) { - printk(KERN_INFO "%s: IO: data <- 0x%04x (%s|%s)\n", + pr_info("%s: IO: data <- 0x%04x (%s|%s)\n", cosa->name, data, data & SR_RDY_RCV ? "RX_RDY" : "!rx_rdy", data & SR_RDY_SND ? "TX_RDY" : "!tx_rdy"); -- cgit v1.2.3-70-g09d2 From d6810e1375c9b3b28ed1caccb6fb706945903f49 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:30 +0000 Subject: cyclom: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/cycx_drv.c | 81 +++++++++----------- drivers/net/wan/cycx_main.c | 31 ++++---- drivers/net/wan/cycx_x25.c | 177 ++++++++++++++++++++------------------------ 3 files changed, 133 insertions(+), 156 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c index 164c3624ba8..2a3ecae67a9 100644 --- a/drivers/net/wan/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c @@ -48,6 +48,8 @@ * Aug 8, 1998 acme Initial version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include /* __init */ #include #include /* printk(), and other useful stuff */ @@ -81,10 +83,9 @@ static u16 checksum(u8 *buf, u32 len); /* Global Data */ /* private data */ -static const char modname[] = "cycx_drv"; static const char fullname[] = "Cyclom 2X Support Module"; -static const char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " - ""; +static const char copyright[] = + "(c) 1998-2003 Arnaldo Carvalho de Melo "; /* Hardware configuration options. * These are arrays of configuration options used by verification routines. @@ -110,8 +111,8 @@ static const long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 }; static int __init cycx_drv_init(void) { - printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE, - copyright); + pr_info("%s v%u.%u %s\n", + fullname, MOD_VERSION, MOD_RELEASE, copyright); return 0; } @@ -139,18 +140,16 @@ int cycx_setup(struct cycx_hw *hw, void *cfm, u32 len, unsigned long dpmbase) /* Verify IRQ configuration options */ if (!get_option_index(cycx_2x_irq_options, hw->irq)) { - printk(KERN_ERR "%s: IRQ %d is invalid!\n", modname, hw->irq); + pr_err("IRQ %d is invalid!\n", hw->irq); return -EINVAL; } /* Setup adapter dual-port memory window and test memory */ if (!dpmbase) { - printk(KERN_ERR "%s: you must specify the dpm address!\n", - modname); + pr_err("you must specify the dpm address!\n"); return -EINVAL; } else if (!get_option_index(cyc2x_dpmbase_options, dpmbase)) { - printk(KERN_ERR "%s: memory address 0x%lX is invalid!\n", - modname, dpmbase); + pr_err("memory address 0x%lX is invalid!\n", dpmbase); return -EINVAL; } @@ -158,13 +157,12 @@ int cycx_setup(struct cycx_hw *hw, void *cfm, u32 len, unsigned long dpmbase) hw->dpmsize = CYCX_WINDOWSIZE; if (!detect_cyc2x(hw->dpmbase)) { - printk(KERN_ERR "%s: adapter Cyclom 2X not found at " - "address 0x%lX!\n", modname, dpmbase); + pr_err("adapter Cyclom 2X not found at address 0x%lX!\n", + dpmbase); return -EINVAL; } - printk(KERN_INFO "%s: found Cyclom 2X card at address 0x%lX.\n", - modname, dpmbase); + pr_info("found Cyclom 2X card at address 0x%lX\n", dpmbase); /* Load firmware. If loader fails then shut down adapter */ err = load_cyc2x(hw, cfm, len); @@ -339,7 +337,7 @@ static int cycx_data_boot(void __iomem *addr, u8 *code, u32 len) for (i = 0 ; i < len ; i += CFM_LOAD_BUFSZ) if (buffer_load(addr, code + i, min_t(u32, CFM_LOAD_BUFSZ, (len - i))) < 0) { - printk(KERN_ERR "%s: Error !!\n", modname); + pr_err("Error !!\n"); return -1; } @@ -370,7 +368,7 @@ static int cycx_code_boot(void __iomem *addr, u8 *code, u32 len) for (i = 0 ; i < len ; i += CFM_LOAD_BUFSZ) if (buffer_load(addr, code + i, min_t(u32, CFM_LOAD_BUFSZ, (len - i)))) { - printk(KERN_ERR "%s: Error !!\n", modname); + pr_err("Error !!\n"); return -1; } @@ -391,23 +389,20 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) u16 cksum; /* Announce */ - printk(KERN_INFO "%s: firmware signature=\"%s\"\n", modname, - cfm->signature); + pr_info("firmware signature=\"%s\"\n", cfm->signature); /* Verify firmware signature */ if (strcmp(cfm->signature, CFM_SIGNATURE)) { - printk(KERN_ERR "%s:load_cyc2x: not Cyclom-2X firmware!\n", - modname); + pr_err("load_cyc2x: not Cyclom-2X firmware!\n"); return -EINVAL; } - printk(KERN_INFO "%s: firmware version=%u\n", modname, cfm->version); + pr_info("firmware version=%u\n", cfm->version); /* Verify firmware module format version */ if (cfm->version != CFM_VERSION) { - printk(KERN_ERR "%s:%s: firmware format %u rejected! " - "Expecting %u.\n", - modname, __func__, cfm->version, CFM_VERSION); + pr_err("%s: firmware format %u rejected! Expecting %u.\n", + __func__, cfm->version, CFM_VERSION); return -EINVAL; } @@ -419,23 +414,22 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) if (((len - sizeof(struct cycx_firmware) - 1) != cfm->info.codesize) || */ if (cksum != cfm->checksum) { - printk(KERN_ERR "%s:%s: firmware corrupted!\n", - modname, __func__); - printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n", - len - (int)sizeof(struct cycx_firmware) - 1, - cfm->info.codesize); - printk(KERN_ERR " chksum = 0x%x (expected 0x%x)\n", - cksum, cfm->checksum); + pr_err("%s: firmware corrupted!\n", __func__); + pr_err(" cdsize = 0x%x (expected 0x%lx)\n", + len - (int)sizeof(struct cycx_firmware) - 1, + cfm->info.codesize); + pr_err(" chksum = 0x%x (expected 0x%x)\n", + cksum, cfm->checksum); return -EINVAL; } /* If everything is ok, set reset, data and code pointers */ img_hdr = (struct cycx_fw_header *)&cfm->image; #ifdef FIRMWARE_DEBUG - printk(KERN_INFO "%s:%s: image sizes\n", __func__, modname); - printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size); - printk(KERN_INFO " data=%lu\n", img_hdr->data_size); - printk(KERN_INFO " code=%lu\n", img_hdr->code_size); + pr_info("%s: image sizes\n", __func__); + pr_info(" reset=%lu\n", img_hdr->reset_size); + pr_info(" data=%lu\n", img_hdr->data_size); + pr_info(" code=%lu\n", img_hdr->code_size); #endif reset_image = ((u8 *)img_hdr) + sizeof(struct cycx_fw_header); data_image = reset_image + img_hdr->reset_size; @@ -443,15 +437,14 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) /*---- Start load ----*/ /* Announce */ - printk(KERN_INFO "%s: loading firmware %s (ID=%u)...\n", modname, - cfm->descr[0] ? cfm->descr : "unknown firmware", - cfm->info.codeid); + pr_info("loading firmware %s (ID=%u)...\n", + cfm->descr[0] ? cfm->descr : "unknown firmware", + cfm->info.codeid); for (i = 0 ; i < 5 ; i++) { /* Reset Cyclom hardware */ if (!reset_cyc2x(hw->dpmbase)) { - printk(KERN_ERR "%s: dpm problem or board not found\n", - modname); + pr_err("dpm problem or board not found\n"); return -EINVAL; } @@ -468,19 +461,19 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) msleep_interruptible(1 * 1000); } - printk(KERN_ERR "%s: reset not started.\n", modname); + pr_err("reset not started\n"); return -EINVAL; reset_loaded: /* Load data.bin */ if (cycx_data_boot(hw->dpmbase, data_image, img_hdr->data_size)) { - printk(KERN_ERR "%s: cannot load data file.\n", modname); + pr_err("cannot load data file\n"); return -EINVAL; } /* Load code.bin */ if (cycx_code_boot(hw->dpmbase, code_image, img_hdr->code_size)) { - printk(KERN_ERR "%s: cannot load code file.\n", modname); + pr_err("cannot load code file\n"); return -EINVAL; } @@ -493,7 +486,7 @@ reset_loaded: /* Arthur Ganzert's tip: wait a while after the firmware loading... seg abr 26 17:17:12 EST 1999 - acme */ msleep_interruptible(7 * 1000); - printk(KERN_INFO "%s: firmware loaded!\n", modname); + pr_info("firmware loaded!\n"); /* enable interrupts */ cycx_inten(hw); diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c index a0976d1f97c..81fbbad406b 100644 --- a/drivers/net/wan/cycx_main.c +++ b/drivers/net/wan/cycx_main.c @@ -40,6 +40,8 @@ * 1998/08/08 acme Initial version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include /* offsetof(), etc. */ #include /* return codes */ #include /* inline memset(), etc. */ @@ -107,7 +109,7 @@ static int __init cycx_init(void) { int cnt, err = -ENOMEM; - printk(KERN_INFO "%s v%u.%u %s\n", + pr_info("%s v%u.%u %s\n", cycx_fullname, CYCX_DRV_VERSION, CYCX_DRV_RELEASE, cycx_copyright); @@ -133,9 +135,8 @@ static int __init cycx_init(void) err = register_wan_device(wandev); if (err) { - printk(KERN_ERR "%s: %s registration failed with " - "error %d!\n", - cycx_drvname, card->devname, err); + pr_err("%s registration failed with error %d!\n", + card->devname, err); break; } } @@ -198,14 +199,13 @@ static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf) rc = -EINVAL; if (!conf->data_size || !conf->data) { - printk(KERN_ERR "%s: firmware not found in configuration " - "data!\n", wandev->name); + pr_err("%s: firmware not found in configuration data!\n", + wandev->name); goto out; } if (conf->irq <= 0) { - printk(KERN_ERR "%s: can't configure without IRQ!\n", - wandev->name); + pr_err("%s: can't configure without IRQ!\n", wandev->name); goto out; } @@ -213,8 +213,7 @@ static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf) irq = conf->irq == 2 ? 9 : conf->irq; /* IRQ2 -> IRQ9 */ if (request_irq(irq, cycx_isr, 0, wandev->name, card)) { - printk(KERN_ERR "%s: can't reserve IRQ %d!\n", - wandev->name, irq); + pr_err("%s: can't reserve IRQ %d!\n", wandev->name, irq); goto out; } @@ -246,8 +245,7 @@ static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf) break; #endif default: - printk(KERN_ERR "%s: this firmware is not supported!\n", - wandev->name); + pr_err("%s: this firmware is not supported!\n", wandev->name); rc = -EINVAL; } @@ -288,8 +286,7 @@ static int cycx_wan_shutdown(struct wan_device *wandev) card = wandev->private; wandev->state = WAN_UNCONFIGURED; cycx_down(&card->hw); - printk(KERN_INFO "%s: irq %d being freed!\n", wandev->name, - wandev->irq); + pr_info("%s: irq %d being freed!\n", wandev->name, wandev->irq); free_irq(wandev->irq, card); out: return ret; } @@ -308,8 +305,8 @@ static irqreturn_t cycx_isr(int irq, void *dev_id) goto out; if (card->in_isr) { - printk(KERN_WARNING "%s: interrupt re-entrancy on IRQ %d!\n", - card->devname, card->wandev.irq); + pr_warn("%s: interrupt re-entrancy on IRQ %d!\n", + card->devname, card->wandev.irq); goto out; } @@ -337,7 +334,7 @@ void cycx_set_state(struct cycx_device *card, int state) string_state = "disconnected!"; break; } - printk(KERN_INFO "%s: link %s\n", card->devname, string_state); + pr_info("%s: link %s\n", card->devname, string_state); card->wandev.state = state; } diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index cf9e15fd8d9..06f3f6309e4 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -76,6 +76,8 @@ * 1998/08/08 acme Initial version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define CYCLOMX_X25_DEBUG 1 #include /* isdigit() */ @@ -230,8 +232,8 @@ int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf) /* Verify configuration ID */ if (conf->config_id != WANCONFIG_X25) { - printk(KERN_INFO "%s: invalid configuration ID %u!\n", - card->devname, conf->config_id); + pr_info("%s: invalid configuration ID %u!\n", + card->devname, conf->config_id); return -EINVAL; } @@ -374,8 +376,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev, int err = 0; if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) { - printk(KERN_INFO "%s: invalid interface name!\n", - card->devname); + pr_info("%s: invalid interface name!\n", card->devname); return -EINVAL; } @@ -398,8 +399,8 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev, if (len) { if (len > WAN_ADDRESS_SZ) { - printk(KERN_ERR "%s: %s local addr too long!\n", - wandev->name, chan->name); + pr_err("%s: %s local addr too long!\n", + wandev->name, chan->name); err = -EINVAL; goto error; } else { @@ -429,15 +430,14 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev, if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc) chan->lcn = lcn; else { - printk(KERN_ERR - "%s: PVC %u is out of range on interface %s!\n", - wandev->name, lcn, chan->name); + pr_err("%s: PVC %u is out of range on interface %s!\n", + wandev->name, lcn, chan->name); err = -EINVAL; goto error; } } else { - printk(KERN_ERR "%s: invalid media address on interface %s!\n", - wandev->name, chan->name); + pr_err("%s: invalid media address on interface %s!\n", + wandev->name, chan->name); err = -EINVAL; goto error; } @@ -607,9 +607,8 @@ static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb, ++chan->ifstats.tx_dropped; else if (chan->svc && chan->protocol && chan->protocol != ntohs(skb->protocol)) { - printk(KERN_INFO - "%s: unsupported Ethertype 0x%04X on interface %s!\n", - card->devname, ntohs(skb->protocol), dev->name); + pr_info("%s: unsupported Ethertype 0x%04X on interface %s!\n", + card->devname, ntohs(skb->protocol), dev->name); ++chan->ifstats.tx_errors; } else if (chan->protocol == ETH_P_IP) { switch (chan->state) { @@ -643,9 +642,8 @@ static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb, cycx_x25_chan_disconnect(dev); goto free_packet; default: - printk(KERN_INFO - "%s: unknown %d x25-iface request on %s!\n", - card->devname, skb->data[0], dev->name); + pr_info("%s: unknown %d x25-iface request on %s!\n", + card->devname, skb->data[0], dev->name); ++chan->ifstats.tx_errors; goto free_packet; } @@ -746,8 +744,7 @@ static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd) card->buff_int_mode_unbusy = 1; netif_wake_queue(dev); } else - printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n", - card->devname, lcn); + pr_err("%s:ackvc for inexistent lcn %d\n", card->devname, lcn); } /* Receive interrupt handler. @@ -780,8 +777,8 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd) dev = cycx_x25_get_dev_by_lcn(wandev, lcn); if (!dev) { /* Invalid channel, discard packet */ - printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n", - card->devname, lcn); + pr_info("%s: receiving on orphaned LCN %d!\n", + card->devname, lcn); return; } @@ -802,8 +799,8 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd) if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) + bufsize + dev->hard_header_len)) == NULL) { - printk(KERN_INFO "%s: no socket buffers available!\n", - card->devname); + pr_info("%s: no socket buffers available!\n", + card->devname); chan->drop_sequence = 1; ++chan->ifstats.rx_dropped; return; @@ -826,8 +823,8 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd) if (bitm) chan->drop_sequence = 1; - printk(KERN_INFO "%s: unexpectedly long packet sequence " - "on interface %s!\n", card->devname, dev->name); + pr_info("%s: unexpectedly long packet sequence on interface %s!\n", + card->devname, dev->name); ++chan->ifstats.rx_length_errors; return; } @@ -880,8 +877,8 @@ static void cycx_x25_irq_connect(struct cycx_device *card, dev = cycx_x25_get_dev_by_dte_addr(wandev, rem); if (!dev) { /* Invalid channel, discard packet */ - printk(KERN_INFO "%s: connect not expected: remote %s!\n", - card->devname, rem); + pr_info("%s: connect not expected: remote %s!\n", + card->devname, rem); return; } @@ -909,8 +906,8 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card, if (!dev) { /* Invalid channel, discard packet */ clear_bit(--key, (void*)&card->u.x.connection_keys); - printk(KERN_INFO "%s: connect confirm not expected: lcn %d, " - "key=%d!\n", card->devname, lcn, key); + pr_info("%s: connect confirm not expected: lcn %d, key=%d!\n", + card->devname, lcn, key); return; } @@ -934,8 +931,8 @@ static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card, dev = cycx_x25_get_dev_by_lcn(wandev, lcn); if (!dev) { /* Invalid channel, discard packet */ - printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n", - card->devname, lcn); + pr_info("%s:disconnect confirm not expected!:lcn %d\n", + card->devname, lcn); return; } @@ -980,13 +977,13 @@ static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd) cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1); cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1); - printk(KERN_INFO "cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n"); - printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf); - printk(KERN_INFO "Log message code=0x%X\n", msg_code); - printk(KERN_INFO "Link=%d\n", link); - printk(KERN_INFO "log code=0x%X\n", code); - printk(KERN_INFO "log routine=0x%X\n", routine); - printk(KERN_INFO "Message size=%d\n", size); + pr_info("cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n"); + pr_info("cmd->buf=0x%X\n", cmd->buf); + pr_info("Log message code=0x%X\n", msg_code); + pr_info("Link=%d\n", link); + pr_info("log code=0x%X\n", code); + pr_info("log routine=0x%X\n", routine); + pr_info("Message size=%d\n", size); hex_dump("Message", bf, toread); #endif } @@ -1009,24 +1006,14 @@ static void cycx_x25_irq_stat(struct cycx_device *card, static void cycx_x25_irq_spurious(struct cycx_device *card, struct cycx_x25_cmd *cmd) { - printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n", - card->devname, cmd->command); + pr_info("%s: spurious interrupt (0x%X)!\n", + card->devname, cmd->command); } #ifdef CYCLOMX_X25_DEBUG static void hex_dump(char *msg, unsigned char *p, int len) { - unsigned char hex[1024], - * phex = hex; - - if (len >= (sizeof(hex) / 2)) - len = (sizeof(hex) / 2) - 1; - - while (len--) { - sprintf(phex, "%02x", *p++); - phex += 2; - } - - printk(KERN_INFO "%s: %s\n", msg, hex); + print_hex_dump(KERN_INFO, msg, DUMP_PREFIX_OFFSET, 16, 1, + p, len, true); } #endif @@ -1203,8 +1190,8 @@ static int x25_place_call(struct cycx_device *card, u8 key; if (card->u.x.connection_keys == ~0U) { - printk(KERN_INFO "%s: too many simultaneous connection " - "requests!\n", card->devname); + pr_info("%s: too many simultaneous connection requests!\n", + card->devname); return -EAGAIN; } @@ -1381,8 +1368,8 @@ static void cycx_x25_chan_timer(unsigned long d) if (chan->state == WAN_CONNECTED) cycx_x25_chan_disconnect(dev); else - printk(KERN_ERR "%s: %s for svc (%s) not connected!\n", - chan->card->devname, __func__, dev->name); + pr_err("%s: %s for svc (%s) not connected!\n", + chan->card->devname, __func__, dev->name); } /* Set logical channel state. */ @@ -1433,8 +1420,8 @@ static void cycx_x25_set_chan_state(struct net_device *dev, u8 state) break; } - printk(KERN_INFO "%s: interface %s %s\n", card->devname, - dev->name, string_state); + pr_info("%s: interface %s %s\n", + card->devname, dev->name, string_state); chan->state = state; } @@ -1488,7 +1475,7 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event) unsigned char *ptr; if ((skb = dev_alloc_skb(1)) == NULL) { - printk(KERN_ERR "%s: out of memory\n", __func__); + pr_err("%s: out of memory\n", __func__); return; } @@ -1557,56 +1544,56 @@ static void reset_timer(struct net_device *dev) #ifdef CYCLOMX_X25_DEBUG static void cycx_x25_dump_config(struct cycx_x25_config *conf) { - printk(KERN_INFO "X.25 configuration\n"); - printk(KERN_INFO "-----------------\n"); - printk(KERN_INFO "link number=%d\n", conf->link); - printk(KERN_INFO "line speed=%d\n", conf->speed); - printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In"); - printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2); - printk(KERN_INFO "level 2 window=%d\n", conf->n2win); - printk(KERN_INFO "level 3 window=%d\n", conf->n3win); - printk(KERN_INFO "# logical channels=%d\n", conf->nvc); - printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen); - printk(KERN_INFO "my address=%d\n", conf->locaddr); - printk(KERN_INFO "remote address=%d\n", conf->remaddr); - printk(KERN_INFO "t1=%d seconds\n", conf->t1); - printk(KERN_INFO "t2=%d seconds\n", conf->t2); - printk(KERN_INFO "t21=%d seconds\n", conf->t21); - printk(KERN_INFO "# PVCs=%d\n", conf->npvc); - printk(KERN_INFO "t23=%d seconds\n", conf->t23); - printk(KERN_INFO "flags=0x%x\n", conf->flags); + pr_info("X.25 configuration\n"); + pr_info("-----------------\n"); + pr_info("link number=%d\n", conf->link); + pr_info("line speed=%d\n", conf->speed); + pr_info("clock=%sternal\n", conf->clock == 8 ? "Ex" : "In"); + pr_info("# level 2 retransm.=%d\n", conf->n2); + pr_info("level 2 window=%d\n", conf->n2win); + pr_info("level 3 window=%d\n", conf->n3win); + pr_info("# logical channels=%d\n", conf->nvc); + pr_info("level 3 pkt len=%d\n", conf->pktlen); + pr_info("my address=%d\n", conf->locaddr); + pr_info("remote address=%d\n", conf->remaddr); + pr_info("t1=%d seconds\n", conf->t1); + pr_info("t2=%d seconds\n", conf->t2); + pr_info("t21=%d seconds\n", conf->t21); + pr_info("# PVCs=%d\n", conf->npvc); + pr_info("t23=%d seconds\n", conf->t23); + pr_info("flags=0x%x\n", conf->flags); } static void cycx_x25_dump_stats(struct cycx_x25_stats *stats) { - printk(KERN_INFO "X.25 statistics\n"); - printk(KERN_INFO "--------------\n"); - printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors); - printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors); - printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames); - printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames); - printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts); - printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts); - printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets); - printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets); - printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts); - printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts); + pr_info("X.25 statistics\n"); + pr_info("--------------\n"); + pr_info("rx_crc_errors=%d\n", stats->rx_crc_errors); + pr_info("rx_over_errors=%d\n", stats->rx_over_errors); + pr_info("n2_tx_frames=%d\n", stats->n2_tx_frames); + pr_info("n2_rx_frames=%d\n", stats->n2_rx_frames); + pr_info("tx_timeouts=%d\n", stats->tx_timeouts); + pr_info("rx_timeouts=%d\n", stats->rx_timeouts); + pr_info("n3_tx_packets=%d\n", stats->n3_tx_packets); + pr_info("n3_rx_packets=%d\n", stats->n3_rx_packets); + pr_info("tx_aborts=%d\n", stats->tx_aborts); + pr_info("rx_aborts=%d\n", stats->rx_aborts); } static void cycx_x25_dump_devs(struct wan_device *wandev) { struct net_device *dev = wandev->dev; - printk(KERN_INFO "X.25 dev states\n"); - printk(KERN_INFO "name: addr: txoff: protocol:\n"); - printk(KERN_INFO "---------------------------------------\n"); + pr_info("X.25 dev states\n"); + pr_info("name: addr: txoff: protocol:\n"); + pr_info("---------------------------------------\n"); while(dev) { struct cycx_x25_channel *chan = netdev_priv(dev); - printk(KERN_INFO "%-5.5s %-15.15s %d ETH_P_%s\n", - chan->name, chan->addr, netif_queue_stopped(dev), - chan->protocol == ETH_P_IP ? "IP" : "X25"); + pr_info("%-5.5s %-15.15s %d ETH_P_%s\n", + chan->name, chan->addr, netif_queue_stopped(dev), + chan->protocol == ETH_P_IP ? "IP" : "X25"); dev = chan->slave; } } -- cgit v1.2.3-70-g09d2 From 86fb0ccf90cc34642daf6cd902ee26516a0ff0a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:31 +0000 Subject: frame relay dlci/frad: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/dlci.c | 22 ++++++++++++++------- drivers/net/wan/sdla.c | 52 +++++++++++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 29 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 21b104db5a9..48ab38a34c5 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -28,6 +28,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -112,8 +114,7 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev) dlp = netdev_priv(dev); if (!pskb_may_pull(skb, sizeof(*hdr))) { - printk(KERN_NOTICE "%s: invalid data no header\n", - dev->name); + netdev_notice(dev, "invalid data no header\n"); dev->stats.rx_errors++; kfree_skb(skb); return; @@ -126,7 +127,8 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev) if (hdr->control != FRAD_I_UI) { - printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control); + netdev_notice(dev, "Invalid header flag 0x%02X\n", + hdr->control); dev->stats.rx_errors++; } else @@ -135,14 +137,18 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev) case FRAD_P_PADDING: if (hdr->NLPID != FRAD_P_SNAP) { - printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID); + netdev_notice(dev, "Unsupported NLPID 0x%02X\n", + hdr->NLPID); dev->stats.rx_errors++; break; } if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0) { - printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]); + netdev_notice(dev, "Unsupported organizationally unique identifier 0x%02X-%02X-%02X\n", + hdr->OUI[0], + hdr->OUI[1], + hdr->OUI[2]); dev->stats.rx_errors++; break; } @@ -163,12 +169,14 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev) case FRAD_P_SNAP: case FRAD_P_Q933: case FRAD_P_CLNP: - printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad); + netdev_notice(dev, "Unsupported NLPID 0x%02X\n", + hdr->pad); dev->stats.rx_errors++; break; default: - printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad); + netdev_notice(dev, "Invalid pad byte 0x%02X\n", + hdr->pad); dev->stats.rx_errors++; break; } diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index 3f4e2b5684d..c8531612eea 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -32,6 +32,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -350,24 +352,24 @@ static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int case SDLA_RET_MODEM: state = data; if (*state & SDLA_MODEM_DCD_LOW) - printk(KERN_INFO "%s: Modem DCD unexpectedly low!\n", dev->name); + netdev_info(dev, "Modem DCD unexpectedly low!\n"); if (*state & SDLA_MODEM_CTS_LOW) - printk(KERN_INFO "%s: Modem CTS unexpectedly low!\n", dev->name); + netdev_info(dev, "Modem CTS unexpectedly low!\n"); /* I should probably do something about this! */ break; case SDLA_RET_CHANNEL_OFF: - printk(KERN_INFO "%s: Channel became inoperative!\n", dev->name); + netdev_info(dev, "Channel became inoperative!\n"); /* same here */ break; case SDLA_RET_CHANNEL_ON: - printk(KERN_INFO "%s: Channel became operative!\n", dev->name); + netdev_info(dev, "Channel became operative!\n"); /* same here */ break; case SDLA_RET_DLCI_STATUS: - printk(KERN_INFO "%s: Status change reported by Access Node.\n", dev->name); + netdev_info(dev, "Status change reported by Access Node\n"); len /= sizeof(struct _dlci_stat); for(pstatus = data, i=0;i < len;i++,pstatus++) { @@ -382,29 +384,32 @@ static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int sprintf(line, "unknown status: %02X", pstatus->flags); state = line; } - printk(KERN_INFO "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state); + netdev_info(dev, "DLCI %i: %s\n", + pstatus->dlci, state); /* same here */ } break; case SDLA_RET_DLCI_UNKNOWN: - printk(KERN_INFO "%s: Received unknown DLCIs:", dev->name); + netdev_info(dev, "Received unknown DLCIs:"); len /= sizeof(short); for(pdlci = data,i=0;i < len;i++,pdlci++) - printk(" %i", *pdlci); - printk("\n"); + pr_cont(" %i", *pdlci); + pr_cont("\n"); break; case SDLA_RET_TIMEOUT: - printk(KERN_ERR "%s: Command timed out!\n", dev->name); + netdev_err(dev, "Command timed out!\n"); break; case SDLA_RET_BUF_OVERSIZE: - printk(KERN_INFO "%s: Bc/CIR overflow, acceptable size is %i\n", dev->name, len); + netdev_info(dev, "Bc/CIR overflow, acceptable size is %i\n", + len); break; case SDLA_RET_BUF_TOO_BIG: - printk(KERN_INFO "%s: Buffer size over specified max of %i\n", dev->name, len); + netdev_info(dev, "Buffer size over specified max of %i\n", + len); break; case SDLA_RET_CHANNEL_INACTIVE: @@ -415,7 +420,8 @@ static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int break; default: - printk(KERN_DEBUG "%s: Cmd 0x%2.2X generated return code 0x%2.2X\n", dev->name, cmd, ret); + netdev_dbg(dev, "Cmd 0x%02X generated return code 0x%02X\n", + cmd, ret); /* Further processing could be done here */ break; } @@ -678,12 +684,14 @@ static netdev_tx_t sdla_transmit(struct sk_buff *skb, case ARPHRD_FRAD: if (skb->dev->type != ARPHRD_DLCI) { - printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type); + netdev_warn(dev, "Non DLCI device, type %i, tried to send on FRAD module\n", + skb->dev->type); accept = 0; } break; default: - printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type); + netdev_warn(dev, "unknown firmware type 0x%04X\n", + dev->type); accept = 0; break; } @@ -807,7 +815,8 @@ static void sdla_receive(struct net_device *dev) if (i == CONFIG_DLCI_MAX) { - printk(KERN_NOTICE "%s: Received packet from invalid DLCI %i, ignoring.", dev->name, dlci); + netdev_notice(dev, "Received packet from invalid DLCI %i, ignoring\n", + dlci); dev->stats.rx_errors++; success = 0; } @@ -819,7 +828,7 @@ static void sdla_receive(struct net_device *dev) skb = dev_alloc_skb(len + sizeof(struct frhdr)); if (skb == NULL) { - printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); + netdev_notice(dev, "Memory squeeze, dropping packet\n"); dev->stats.rx_dropped++; success = 0; } @@ -880,8 +889,7 @@ static irqreturn_t sdla_isr(int dummy, void *dev_id) if (!flp->initialized) { - printk(KERN_WARNING "%s: irq %d for uninitialized device.\n", - dev->name, dev->irq); + netdev_warn(dev, "irq %d for uninitialized device\n", dev->irq); return IRQ_NONE; } @@ -901,7 +909,7 @@ static irqreturn_t sdla_isr(int dummy, void *dev_id) case SDLA_INTR_TX: case SDLA_INTR_COMPLETE: case SDLA_INTR_TIMER: - printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte); + netdev_warn(dev, "invalid irq flag 0x%02X\n", byte); break; } @@ -1347,7 +1355,7 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map) return -EINVAL; if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){ - printk(KERN_WARNING "SDLA: io-port 0x%04lx in use\n", dev->base_addr); + pr_warn("io-port 0x%04lx in use\n", dev->base_addr); return -EINVAL; } base = map->base_addr; @@ -1412,7 +1420,7 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map) } } - printk(KERN_NOTICE "%s: Unknown card type\n", dev->name); + netdev_notice(dev, "Unknown card type\n"); err = -ENODEV; goto fail; -- cgit v1.2.3-70-g09d2 From 09a1732bee89fc31e63b1bd999f93acd58843f35 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:32 +0000 Subject: dscc4: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/dscc4.c | 80 +++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 42 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 3590d588327..058e1697c17 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -80,6 +80,8 @@ * - misc crapectomy. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -553,7 +555,7 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv, schedule_timeout_uninterruptible(10); rmb(); } while (++i > 0); - printk(KERN_ERR "%s: %s timeout\n", dev->name, msg); + netdev_err(dev, "%s timeout\n", msg); done: return (i >= 0) ? i : -EAGAIN; } @@ -569,18 +571,18 @@ static int dscc4_do_action(struct net_device *dev, char *msg) u32 state = readl(ioaddr); if (state & ArAck) { - printk(KERN_DEBUG "%s: %s ack\n", dev->name, msg); + netdev_dbg(dev, "%s ack\n", msg); writel(ArAck, ioaddr); goto done; } else if (state & Arf) { - printk(KERN_ERR "%s: %s failed\n", dev->name, msg); + netdev_err(dev, "%s failed\n", msg); writel(Arf, ioaddr); i = -1; goto done; } rmb(); } while (++i > 0); - printk(KERN_ERR "%s: %s timeout\n", dev->name, msg); + netdev_err(dev, "%s timeout\n", msg); done: return i; } @@ -636,7 +638,7 @@ static void dscc4_tx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev) writel(MTFi|Rdt, dpriv->base_addr + dpriv->dev_id*0x0c + CH0CFG); if (dscc4_do_action(dev, "Rdt") < 0) - printk(KERN_ERR "%s: Tx reset failed\n", dev->name); + netdev_err(dev, "Tx reset failed\n"); } #endif @@ -722,22 +724,20 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, rc = pci_request_region(pdev, 0, "registers"); if (rc < 0) { - printk(KERN_ERR "%s: can't reserve MMIO region (regs)\n", - DRV_NAME); + pr_err("can't reserve MMIO region (regs)\n"); goto err_disable_0; } rc = pci_request_region(pdev, 1, "LBI interface"); if (rc < 0) { - printk(KERN_ERR "%s: can't reserve MMIO region (lbi)\n", - DRV_NAME); + pr_err("can't reserve MMIO region (lbi)\n"); goto err_free_mmio_region_1; } ioaddr = pci_ioremap_bar(pdev, 0); if (!ioaddr) { - printk(KERN_ERR "%s: cannot remap MMIO region %llx @ %llx\n", - DRV_NAME, (unsigned long long)pci_resource_len(pdev, 0), - (unsigned long long)pci_resource_start(pdev, 0)); + pr_err("cannot remap MMIO region %llx @ %llx\n", + (unsigned long long)pci_resource_len(pdev, 0), + (unsigned long long)pci_resource_start(pdev, 0)); rc = -EIO; goto err_free_mmio_regions_2; } @@ -757,7 +757,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, rc = request_irq(pdev->irq, dscc4_irq, IRQF_SHARED, DRV_NAME, priv->root); if (rc < 0) { - printk(KERN_WARNING "%s: IRQ %d busy\n", DRV_NAME, pdev->irq); + pr_warn("IRQ %d busy\n", pdev->irq); goto err_release_4; } @@ -904,7 +904,7 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) root = kcalloc(dev_per_card, sizeof(*root), GFP_KERNEL); if (!root) { - printk(KERN_ERR "%s: can't allocate data\n", DRV_NAME); + pr_err("can't allocate data\n"); goto err_out; } @@ -916,7 +916,7 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) ppriv = kzalloc(sizeof(*ppriv), GFP_KERNEL); if (!ppriv) { - printk(KERN_ERR "%s: can't allocate private data\n", DRV_NAME); + pr_err("can't allocate private data\n"); goto err_free_dev; } @@ -952,7 +952,7 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) ret = register_hdlc_device(d); if (ret < 0) { - printk(KERN_ERR "%s: unable to register\n", DRV_NAME); + pr_err("unable to register\n"); dscc4_release_ring(dpriv); goto err_unregister; } @@ -1005,7 +1005,7 @@ static int dscc4_loopback_check(struct dscc4_dev_priv *dpriv) if (settings->loopback && (settings->clock_type != CLOCK_INT)) { struct net_device *dev = dscc4_to_dev(dpriv); - printk(KERN_INFO "%s: loopback requires clock\n", dev->name); + netdev_info(dev, "loopback requires clock\n"); return -1; } return 0; @@ -1078,7 +1078,7 @@ static int dscc4_open(struct net_device *dev) scc_patchl(0, PowerUp, dpriv, dev, CCR0); scc_patchl(0, 0x00050000, dpriv, dev, CCR2); scc_writel(EventsMask, dpriv, dev, IMR); - printk(KERN_INFO "%s: up again.\n", dev->name); + netdev_info(dev, "up again\n"); goto done; } @@ -1095,11 +1095,11 @@ static int dscc4_open(struct net_device *dev) * situations. */ if (scc_readl_star(dpriv, dev) & SccBusy) { - printk(KERN_ERR "%s busy. Try later\n", dev->name); + netdev_err(dev, "busy - try later\n"); ret = -EAGAIN; goto err_out; } else - printk(KERN_INFO "%s: available. Good\n", dev->name); + netdev_info(dev, "available - good\n"); scc_writel(EventsMask, dpriv, dev, IMR); @@ -1117,7 +1117,7 @@ static int dscc4_open(struct net_device *dev) * reset is needed. Suggestions anyone ? */ if ((ret = dscc4_xpr_ack(dpriv)) < 0) { - printk(KERN_ERR "%s: %s timeout\n", DRV_NAME, "XPR"); + pr_err("XPR timeout\n"); goto err_disable_scc_events; } @@ -1342,8 +1342,7 @@ static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EPERM; if (dpriv->flags & FakeReset) { - printk(KERN_INFO "%s: please reset the device" - " before this command\n", dev->name); + netdev_info(dev, "please reset the device before this command\n"); return -EPERM; } if (copy_from_user(&dpriv->settings, line, size)) @@ -1506,8 +1505,7 @@ static irqreturn_t dscc4_irq(int irq, void *token) writel(state, ioaddr + GSTAR); if (state & Arf) { - printk(KERN_ERR "%s: failure (Arf). Harass the maintener\n", - dev->name); + netdev_err(dev, "failure (Arf). Harass the maintainer\n"); goto out; } state &= ~ArAck; @@ -1515,7 +1513,7 @@ static irqreturn_t dscc4_irq(int irq, void *token) if (debug > 0) printk(KERN_DEBUG "%s: CfgIV\n", DRV_NAME); if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & cpu_to_le32(Arf)) - printk(KERN_ERR "%s: %s failed\n", dev->name, "CFG"); + netdev_err(dev, "CFG failed\n"); if (!(state &= ~Cfg)) goto out; } @@ -1596,8 +1594,8 @@ try: ++dpriv->tx_dirty; } else { if (debug > 1) - printk(KERN_ERR "%s Tx: NULL skb %d\n", - dev->name, cur); + netdev_err(dev, "Tx: NULL skb %d\n", + cur); } /* * If the driver ends sending crap on the wire, it @@ -1616,7 +1614,7 @@ try: * Transmit Data Underrun */ if (state & Xdu) { - printk(KERN_ERR "%s: XDU. Ask maintainer\n", DRV_NAME); + netdev_err(dev, "Tx Data Underrun. Ask maintainer\n"); dpriv->flags = NeedIDT; /* Tx reset */ writel(MTFi | Rdt, @@ -1625,13 +1623,13 @@ try: return; } if (state & Cts) { - printk(KERN_INFO "%s: CTS transition\n", dev->name); + netdev_info(dev, "CTS transition\n"); if (!(state &= ~Cts)) /* DEBUG */ goto try; } if (state & Xmr) { /* Frame needs to be sent again - FIXME */ - printk(KERN_ERR "%s: Xmr. Ask maintainer\n", DRV_NAME); + netdev_err(dev, "Tx ReTx. Ask maintainer\n"); if (!(state &= ~Xmr)) /* DEBUG */ goto try; } @@ -1649,7 +1647,7 @@ try: break; } if (!i) - printk(KERN_INFO "%s busy in irq\n", dev->name); + netdev_info(dev, "busy in irq\n"); scc_addr = dpriv->base_addr + 0x0c*dpriv->dev_id; /* Keep this order: IDT before IDR */ @@ -1686,7 +1684,7 @@ try: } if (state & Cd) { if (debug > 0) - printk(KERN_INFO "%s: CD transition\n", dev->name); + netdev_info(dev, "CD transition\n"); if (!(state &= ~Cd)) /* DEBUG */ goto try; } @@ -1695,11 +1693,11 @@ try: #ifdef DSCC4_POLLING while (!dscc4_tx_poll(dpriv, dev)); #endif - printk(KERN_INFO "%s: Tx Hi\n", dev->name); + netdev_info(dev, "Tx Hi\n"); state &= ~Hi; } if (state & Err) { - printk(KERN_INFO "%s: Tx ERR\n", dev->name); + netdev_info(dev, "Tx ERR\n"); dev->stats.tx_errors++; state &= ~Err; } @@ -1769,7 +1767,7 @@ try: goto try; } if (state & Hi ) { /* HI bit */ - printk(KERN_INFO "%s: Rx Hi\n", dev->name); + netdev_info(dev, "Rx Hi\n"); state &= ~Hi; goto try; } @@ -1800,7 +1798,7 @@ try: goto try; } if (state & Cts) { - printk(KERN_INFO "%s: CTS transition\n", dev->name); + netdev_info(dev, "CTS transition\n"); if (!(state &= ~Cts)) /* DEBUG */ goto try; } @@ -1859,14 +1857,12 @@ try: sizeof(struct RxFD), scc_addr + CH0BRDA); writel(MTFi|Rdr|Idr, scc_addr + CH0CFG); if (dscc4_do_action(dev, "RDR") < 0) { - printk(KERN_ERR "%s: RDO recovery failed(%s)\n", - dev->name, "RDR"); + netdev_err(dev, "RDO recovery failed(RDR)\n"); goto rdo_end; } writel(MTFi|Idr, scc_addr + CH0CFG); if (dscc4_do_action(dev, "IDR") < 0) { - printk(KERN_ERR "%s: RDO recovery failed(%s)\n", - dev->name, "IDR"); + netdev_err(dev, "RDO recovery failed(IDR)\n"); goto rdo_end; } rdo_end: @@ -1875,7 +1871,7 @@ try: goto try; } if (state & Cd) { - printk(KERN_INFO "%s: CD transition\n", dev->name); + netdev_info(dev, "CD transition\n"); if (!(state &= ~Cd)) /* DEBUG */ goto try; } -- cgit v1.2.3-70-g09d2 From e8c122f450d0b83d7a15535ba49e55ad21a9e63f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:33 +0000 Subject: farsync: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/farsync.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 0f27f4c5bb7..ebb9f24eefb 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -1665,10 +1665,9 @@ check_started_ok(struct fst_card_info *card) * existing firmware etc so we just report it for the moment. */ if (FST_RDL(card, numberOfPorts) != card->nports) { - pr_warning("Port count mismatch on card %d. " - "Firmware thinks %d we say %d\n", - card->card_no, - FST_RDL(card, numberOfPorts), card->nports); + pr_warn("Port count mismatch on card %d. Firmware thinks %d we say %d\n", + card->card_no, + FST_RDL(card, numberOfPorts), card->nports); } } -- cgit v1.2.3-70-g09d2 From c75bb2c6f0cf455c23e60f14d780e841dd47f801 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:34 +0000 Subject: ixp4xx_hss: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/ixp4xx_hss.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index f1e1643dc3e..aaaca9aa229 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -8,6 +8,8 @@ * as published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -358,9 +360,8 @@ static void hss_npe_send(struct port *port, struct msg *msg, const char* what) { u32 *val = (u32*)msg; if (npe_send_message(port->npe, msg, what)) { - printk(KERN_CRIT "HSS-%i: unable to send command [%08X:%08X]" - " to %s\n", port->id, val[0], val[1], - npe_name(port->npe)); + pr_crit("HSS-%i: unable to send command [%08X:%08X] to %s\n", + port->id, val[0], val[1], npe_name(port->npe)); BUG(); } } @@ -447,8 +448,7 @@ static void hss_config(struct port *port) if (npe_recv_message(port->npe, &msg, "HSS_LOAD_CONFIG") || /* HSS_LOAD_CONFIG for port #1 returns port_id = #4 */ msg.cmd != PORT_CONFIG_LOAD || msg.data32) { - printk(KERN_CRIT "HSS-%i: HSS_LOAD_CONFIG failed\n", - port->id); + pr_crit("HSS-%i: HSS_LOAD_CONFIG failed\n", port->id); BUG(); } @@ -477,8 +477,7 @@ static u32 hss_get_status(struct port *port) msg.hss_port = port->id; hss_npe_send(port, &msg, "PORT_ERROR_READ"); if (npe_recv_message(port->npe, &msg, "PORT_ERROR_READ")) { - printk(KERN_CRIT "HSS-%i: unable to read HSS status\n", - port->id); + pr_crit("HSS-%i: unable to read HSS status\n", port->id); BUG(); } @@ -736,9 +735,8 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget) dev->stats.rx_errors++; break; default: /* FIXME - remove printk */ - printk(KERN_ERR "%s: hss_hdlc_poll: status 0x%02X" - " errors %u\n", dev->name, desc->status, - desc->error_count); + netdev_err(dev, "hss_hdlc_poll: status 0x%02X errors %u\n", + desc->status, desc->error_count); dev->stats.rx_errors++; } @@ -1127,8 +1125,8 @@ static int hss_hdlc_close(struct net_device *dev) buffs--; if (buffs) - printk(KERN_CRIT "%s: unable to drain RX queue, %i buffer(s)" - " left in NPE\n", dev->name, buffs); + netdev_crit(dev, "unable to drain RX queue, %i buffer(s) left in NPE\n", + buffs); buffs = TX_DESCS; while (queue_get_desc(queue_ids[port->id].tx, port, 1) >= 0) @@ -1143,8 +1141,8 @@ static int hss_hdlc_close(struct net_device *dev) } while (++i < MAX_CLOSE_WAIT); if (buffs) - printk(KERN_CRIT "%s: unable to drain TX queue, %i buffer(s) " - "left in NPE\n", dev->name, buffs); + netdev_crit(dev, "unable to drain TX queue, %i buffer(s) left in NPE\n", + buffs); #if DEBUG_CLOSE if (!buffs) printk(KERN_DEBUG "Draining TX queues took %i cycles\n", i); @@ -1364,7 +1362,7 @@ static int __devinit hss_init_one(struct platform_device *pdev) platform_set_drvdata(pdev, port); - printk(KERN_INFO "%s: HSS-%i\n", dev->name, port->id); + netdev_info(dev, "HSS-%i\n", port->id); return 0; err_free_netdev: -- cgit v1.2.3-70-g09d2 From 23efcb738ea51befe0674e0685fc6cfe353aa553 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Jun 2011 19:01:35 +0000 Subject: wan: Update to current logging forms Use pr_fmt, pr_ and netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/wan/hostess_sv11.c | 11 +++---- drivers/net/wan/lapbether.c | 18 ++++++------ drivers/net/wan/pc300_drv.c | 4 ++- drivers/net/wan/sbni.c | 67 ++++++++++++++++++++---------------------- drivers/net/wan/sealevel.c | 11 +++---- drivers/net/wan/x25_asy.c | 47 +++++++++++++++-------------- drivers/net/wan/z85230.c | 34 ++++++++++----------- 7 files changed, 96 insertions(+), 96 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index e817583e6ec..3d80e4267de 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -20,6 +20,8 @@ * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -192,8 +194,7 @@ static struct z8530_dev *sv11_init(int iobase, int irq) */ if (!request_region(iobase, 8, "Comtrol SV11")) { - printk(KERN_WARNING "hostess: I/O 0x%X already in use.\n", - iobase); + pr_warn("I/O 0x%X already in use\n", iobase); return NULL; } @@ -221,7 +222,7 @@ static struct z8530_dev *sv11_init(int iobase, int irq) if (request_irq(irq, z8530_interrupt, IRQF_DISABLED, "Hostess SV11", sv) < 0) { - printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq); + pr_warn("IRQ %d already in use\n", irq); goto err_irq; } @@ -255,7 +256,7 @@ static struct z8530_dev *sv11_init(int iobase, int irq) */ if (z8530_init(sv)) { - printk(KERN_ERR "Z8530 series device not found.\n"); + pr_err("Z8530 series device not found\n"); enable_irq(irq); goto free_dma; } @@ -282,7 +283,7 @@ static struct z8530_dev *sv11_init(int iobase, int irq) netdev->irq = irq; if (register_hdlc_device(netdev)) { - printk(KERN_ERR "hostess: unable to register HDLC device.\n"); + pr_err("unable to register HDLC device\n"); free_netdev(netdev); goto free_dma; } diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index eec463f99c0..a817081737a 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -20,6 +20,8 @@ * 2000-11-14 Henner Eisen dev_hold/put, NETDEV_GOING_DOWN support */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -165,13 +167,11 @@ static netdev_tx_t lapbeth_xmit(struct sk_buff *skb, break; case X25_IFACE_CONNECT: if ((err = lapb_connect_request(dev)) != LAPB_OK) - printk(KERN_ERR "lapbeth: lapb_connect_request " - "error: %d\n", err); + pr_err("lapb_connect_request error: %d\n", err); goto drop; case X25_IFACE_DISCONNECT: if ((err = lapb_disconnect_request(dev)) != LAPB_OK) - printk(KERN_ERR "lapbeth: lapb_disconnect_request " - "err: %d\n", err); + pr_err("lapb_disconnect_request err: %d\n", err); /* Fall thru */ default: goto drop; @@ -180,7 +180,7 @@ static netdev_tx_t lapbeth_xmit(struct sk_buff *skb, skb_pull(skb, 1); if ((err = lapb_data_request(dev, skb)) != LAPB_OK) { - printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err); + pr_err("lapb_data_request error - %d\n", err); goto drop; } out: @@ -220,7 +220,7 @@ static void lapbeth_connected(struct net_device *dev, int reason) struct sk_buff *skb = dev_alloc_skb(1); if (!skb) { - printk(KERN_ERR "lapbeth: out of memory\n"); + pr_err("out of memory\n"); return; } @@ -237,7 +237,7 @@ static void lapbeth_disconnected(struct net_device *dev, int reason) struct sk_buff *skb = dev_alloc_skb(1); if (!skb) { - printk(KERN_ERR "lapbeth: out of memory\n"); + pr_err("out of memory\n"); return; } @@ -277,7 +277,7 @@ static int lapbeth_open(struct net_device *dev) int err; if ((err = lapb_register(dev, &lapbeth_callbacks)) != LAPB_OK) { - printk(KERN_ERR "lapbeth: lapb_register error - %d\n", err); + pr_err("lapb_register error: %d\n", err); return -ENODEV; } @@ -292,7 +292,7 @@ static int lapbeth_close(struct net_device *dev) netif_stop_queue(dev); if ((err = lapb_unregister(dev)) != LAPB_OK) - printk(KERN_ERR "lapbeth: lapb_unregister error - %d\n", err); + pr_err("lapb_unregister error: %d\n", err); return 0; } diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index 9617d3d0ee3..1eeedd6a10b 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -212,6 +212,8 @@ static const char rcsid[] = * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -3242,7 +3244,7 @@ static inline void show_version(void) rcsdate++; tmp = strrchr(rcsdate, ' '); *tmp = '\0'; - printk(KERN_INFO "Cyclades-PC300 driver %s %s\n", rcsvers, rcsdate); + pr_info("Cyclades-PC300 driver %s %s\n", rcsvers, rcsdate); } /* show_version */ static const struct net_device_ops cpc_netdev_ops = { diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index cff13a9597c..40e95facdb6 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -37,6 +37,8 @@ * Known problem: this driver wasn't tested on multiprocessor machine. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -200,8 +202,8 @@ sbni_isa_probe( struct net_device *dev ) return 0; else { - printk( KERN_ERR "sbni: base address 0x%lx is busy, or adapter " - "is malfunctional!\n", dev->base_addr ); + pr_err("base address 0x%lx is busy, or adapter is malfunctional!\n", + dev->base_addr); return -ENODEV; } } @@ -226,7 +228,6 @@ static void __init sbni_devsetup(struct net_device *dev) int __init sbni_probe(int unit) { struct net_device *dev; - static unsigned version_printed __initdata = 0; int err; dev = alloc_netdev(sizeof(struct net_local), "sbni", sbni_devsetup); @@ -250,8 +251,7 @@ int __init sbni_probe(int unit) free_netdev(dev); return err; } - if( version_printed++ == 0 ) - printk( KERN_INFO "%s", version ); + pr_info_once("%s", version); return 0; } @@ -326,9 +326,9 @@ sbni_pci_probe( struct net_device *dev ) } if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs) - printk( KERN_WARNING - " WARNING: The PCI BIOS assigned this PCI card to IRQ %d, which is unlikely to work!.\n" - " You should use the PCI BIOS setup to assign a valid IRQ line.\n", + pr_warn( +"WARNING: The PCI BIOS assigned this PCI card to IRQ %d, which is unlikely to work!.\n" +"You should use the PCI BIOS setup to assign a valid IRQ line.\n", pci_irq_line ); /* avoiding re-enable dual adapters */ @@ -372,8 +372,7 @@ sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq ) outb( 0, ioaddr + CSR0 ); if( !irq ) { - printk( KERN_ERR "%s: can't detect device irq!\n", - dev->name ); + pr_err("%s: can't detect device irq!\n", dev->name); release_region( ioaddr, SBNI_IO_EXTENT ); return NULL; } @@ -386,7 +385,7 @@ sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq ) /* Fill in sbni-specific dev fields. */ nl = netdev_priv(dev); if( !nl ) { - printk( KERN_ERR "%s: unable to get memory!\n", dev->name ); + pr_err("%s: unable to get memory!\n", dev->name); release_region( ioaddr, SBNI_IO_EXTENT ); return NULL; } @@ -415,21 +414,21 @@ sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq ) if( inb( ioaddr + CSR0 ) & 0x01 ) nl->state |= FL_SLOW_MODE; - printk( KERN_NOTICE "%s: ioaddr %#lx, irq %d, " - "MAC: 00:ff:01:%02x:%02x:%02x\n", - dev->name, dev->base_addr, dev->irq, - ((u8 *) dev->dev_addr) [3], - ((u8 *) dev->dev_addr) [4], - ((u8 *) dev->dev_addr) [5] ); + pr_notice("%s: ioaddr %#lx, irq %d, MAC: 00:ff:01:%02x:%02x:%02x\n", + dev->name, dev->base_addr, dev->irq, + ((u8 *)dev->dev_addr)[3], + ((u8 *)dev->dev_addr)[4], + ((u8 *)dev->dev_addr)[5]); - printk( KERN_NOTICE "%s: speed %d, receive level ", dev->name, - ( (nl->state & FL_SLOW_MODE) ? 500000 : 2000000) - / (1 << nl->csr1.rate) ); + pr_notice("%s: speed %d", + dev->name, + ((nl->state & FL_SLOW_MODE) ? 500000 : 2000000) + / (1 << nl->csr1.rate)); if( nl->delta_rxl == 0 ) - printk( "0x%x (fixed)\n", nl->cur_rxl_index ); + pr_cont(", receive level 0x%x (fixed)\n", nl->cur_rxl_index); else - printk( "(auto)\n"); + pr_cont(", receive level (auto)\n"); #ifdef CONFIG_SBNI_MULTILINE nl->master = dev; @@ -568,7 +567,7 @@ handle_channel( struct net_device *dev ) */ csr0 = inb( ioaddr + CSR0 ); if( !(csr0 & TR_RDY) || (csr0 & RC_RDY) ) - printk( KERN_ERR "%s: internal error!\n", dev->name ); + netdev_err(dev, "internal error!\n"); /* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */ if( req_ans || nl->tx_frameno != 0 ) @@ -851,7 +850,7 @@ prepare_to_send( struct sk_buff *skb, struct net_device *dev ) /* nl->tx_buf_p == NULL here! */ if( nl->tx_buf_p ) - printk( KERN_ERR "%s: memory leak!\n", dev->name ); + netdev_err(dev, "memory leak!\n"); nl->outpos = 0; nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND); @@ -1179,16 +1178,15 @@ sbni_open( struct net_device *dev ) ((struct net_local *) (netdev_priv(*p))) ->second = dev; - printk( KERN_NOTICE "%s: using shared irq " - "with %s\n", dev->name, (*p)->name ); + netdev_notice(dev, "using shared irq with %s\n", + (*p)->name); nl->state |= FL_SECONDARY; goto handler_attached; } } if( request_irq(dev->irq, sbni_interrupt, IRQF_SHARED, dev->name, dev) ) { - printk( KERN_ERR "%s: unable to get IRQ %d.\n", - dev->name, dev->irq ); + netdev_err(dev, "unable to get IRQ %d\n", dev->irq); return -EAGAIN; } @@ -1220,8 +1218,8 @@ sbni_close( struct net_device *dev ) struct net_local *nl = netdev_priv(dev); if( nl->second && nl->second->flags & IFF_UP ) { - printk( KERN_NOTICE "Secondary channel (%s) is active!\n", - nl->second->name ); + netdev_notice(dev, "Secondary channel (%s) is active!\n", + nl->second->name); return -EBUSY; } @@ -1363,8 +1361,8 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd ) return -EFAULT; slave_dev = dev_get_by_name(&init_net, slave_name ); if( !slave_dev || !(slave_dev->flags & IFF_UP) ) { - printk( KERN_ERR "%s: trying to enslave non-active " - "device %s\n", dev->name, slave_name ); + netdev_err(dev, "trying to enslave non-active device %s\n", + slave_name); return -EPERM; } @@ -1417,8 +1415,7 @@ enslave( struct net_device *dev, struct net_device *slave_dev ) spin_unlock( &snl->lock ); spin_unlock( &nl->lock ); - printk( KERN_NOTICE "%s: slave device (%s) attached.\n", - dev->name, slave_dev->name ); + netdev_notice(dev, "slave device (%s) attached\n", slave_dev->name); return 0; } @@ -1547,7 +1544,7 @@ sbni_setup( char *p ) break; } bad_param: - printk( KERN_ERR "Error in sbni kernel parameter!\n" ); + pr_err("Error in sbni kernel parameter!\n"); return 0; } diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index e91457d6023..0b4fd05e150 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -12,6 +12,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -190,7 +192,7 @@ static int slvl_setup(struct slvl_device *sv, int iobase, int irq) dev->irq = irq; if (register_hdlc_device(dev)) { - printk(KERN_ERR "sealevel: unable to register HDLC device\n"); + pr_err("unable to register HDLC device\n"); free_netdev(dev); return -1; } @@ -215,8 +217,7 @@ static __init struct slvl_board *slvl_init(int iobase, int irq, */ if (!request_region(iobase, 8, "Sealevel 4021")) { - printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n", - iobase); + pr_warn("I/O 0x%X already in use\n", iobase); return NULL; } @@ -267,7 +268,7 @@ static __init struct slvl_board *slvl_init(int iobase, int irq, if (request_irq(irq, z8530_interrupt, IRQF_DISABLED, "SeaLevel", dev) < 0) { - printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq); + pr_warn("IRQ %d already in use\n", irq); goto err_request_irq; } @@ -292,7 +293,7 @@ static __init struct slvl_board *slvl_init(int iobase, int irq, */ if (z8530_init(dev) != 0) { - printk(KERN_ERR "Z8530 series device not found.\n"); + pr_err("Z8530 series device not found\n"); enable_irq(irq); goto free_hw; } diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 24297b274cd..46ceb3ae907 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -14,6 +14,8 @@ * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include @@ -96,7 +98,7 @@ static struct x25_asy *x25_asy_alloc(void) x25_asy_devs[i] = dev; return sl; } else { - printk(KERN_WARNING "x25_asy_alloc() - register_netdev() failure.\n"); + pr_warn("%s(): register_netdev() failure\n", __func__); free_netdev(dev); } } @@ -114,8 +116,7 @@ static void x25_asy_free(struct x25_asy *sl) sl->xbuff = NULL; if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) - printk(KERN_ERR "%s: x25_asy_free for already free unit.\n", - sl->dev->name); + netdev_err(sl->dev, "x25_asy_free for already free unit\n"); } static int x25_asy_change_mtu(struct net_device *dev, int newmtu) @@ -128,8 +129,7 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu) rbuff = kmalloc(len + 4, GFP_ATOMIC); if (xbuff == NULL || rbuff == NULL) { - printk(KERN_WARNING "%s: unable to grow X.25 buffers, MTU change cancelled.\n", - dev->name); + netdev_warn(dev, "unable to grow X.25 buffers, MTU change cancelled\n"); kfree(xbuff); kfree(rbuff); return -ENOMEM; @@ -198,8 +198,7 @@ static void x25_asy_bump(struct x25_asy *sl) skb = dev_alloc_skb(count+1); if (skb == NULL) { - printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", - sl->dev->name); + netdev_warn(sl->dev, "memory squeeze, dropping packet\n"); dev->stats.rx_dropped++; return; } @@ -287,9 +286,9 @@ static void x25_asy_timeout(struct net_device *dev) /* May be we must check transmitter timeout here ? * 14 Oct 1994 Dmitry Gorodchanin. */ - printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, - (tty_chars_in_buffer(sl->tty) || sl->xleft) ? - "bad line quality" : "driver error"); + netdev_warn(dev, "transmit timed out, %s?\n", + (tty_chars_in_buffer(sl->tty) || sl->xleft) ? + "bad line quality" : "driver error"); sl->xleft = 0; clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); x25_asy_unlock(sl); @@ -306,8 +305,7 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb, int err; if (!netif_running(sl->dev)) { - printk(KERN_ERR "%s: xmit call when iface is down\n", - dev->name); + netdev_err(dev, "xmit call when iface is down\n"); kfree_skb(skb); return NETDEV_TX_OK; } @@ -318,13 +316,15 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb, case X25_IFACE_CONNECT: /* Connection request .. do nothing */ err = lapb_connect_request(dev); if (err != LAPB_OK) - printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err); + netdev_err(dev, "lapb_connect_request error: %d\n", + err); kfree_skb(skb); return NETDEV_TX_OK; case X25_IFACE_DISCONNECT: /* do nothing - hang up ?? */ err = lapb_disconnect_request(dev); if (err != LAPB_OK) - printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err); + netdev_err(dev, "lapb_disconnect_request error: %d\n", + err); default: kfree_skb(skb); return NETDEV_TX_OK; @@ -343,7 +343,7 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb, err = lapb_data_request(dev, skb); if (err != LAPB_OK) { - printk(KERN_ERR "x25_asy: lapb_data_request error - %d\n", err); + netdev_err(dev, "lapb_data_request error: %d\n", err); kfree_skb(skb); return NETDEV_TX_OK; } @@ -378,7 +378,7 @@ static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb) spin_lock(&sl->lock); if (netif_queue_stopped(sl->dev) || sl->tty == NULL) { spin_unlock(&sl->lock); - printk(KERN_ERR "x25_asy: tbusy drop\n"); + netdev_err(dev, "tbusy drop\n"); kfree_skb(skb); return; } @@ -404,7 +404,7 @@ static void x25_asy_connected(struct net_device *dev, int reason) skb = dev_alloc_skb(1); if (skb == NULL) { - printk(KERN_ERR "x25_asy: out of memory\n"); + netdev_err(dev, "out of memory\n"); return; } @@ -423,7 +423,7 @@ static void x25_asy_disconnected(struct net_device *dev, int reason) skb = dev_alloc_skb(1); if (skb == NULL) { - printk(KERN_ERR "x25_asy: out of memory\n"); + netdev_err(dev, "out of memory\n"); return; } @@ -603,8 +603,8 @@ static void x25_asy_close_tty(struct tty_struct *tty) err = lapb_unregister(sl->dev); if (err != LAPB_OK) - printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n", - err); + pr_err("x25_asy_close: lapb_unregister error: %d\n", + err); tty->disc_data = NULL; sl->tty = NULL; @@ -782,14 +782,13 @@ static int __init init_x25_asy(void) if (x25_asy_maxdev < 4) x25_asy_maxdev = 4; /* Sanity */ - printk(KERN_INFO "X.25 async: version 0.00 ALPHA " - "(dynamic channels, max=%d).\n", x25_asy_maxdev); + pr_info("X.25 async: version 0.00 ALPHA (dynamic channels, max=%d)\n", + x25_asy_maxdev); x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *), GFP_KERNEL); if (!x25_asy_devs) { - printk(KERN_WARNING "X25 async: Can't allocate x25_asy_ctrls[] " - "array! Uaargh! (-> No X.25 available)\n"); + pr_warn("Can't allocate x25_asy_ctrls[] array! Uaargh! (-> No X.25 available)\n"); return -ENOMEM; } diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index 0806232e0f8..0e576906170 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c @@ -36,6 +36,8 @@ * Synchronous mode without DMA is unlikely to pass about 2400 baud. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -365,7 +367,7 @@ static void z8530_rx(struct z8530_channel *c) c->count=0; if(stat&Rx_OVR) { - printk(KERN_WARNING "%s: overrun\n", c->dev->name); + pr_warn("%s: overrun\n", c->dev->name); c->rx_overrun++; } if(stat&CRC_ERR) @@ -464,12 +466,12 @@ static void z8530_status(struct z8530_channel *chan) if (altered & chan->dcdcheck) { if (status & chan->dcdcheck) { - printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); + pr_info("%s: DCD raised\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3] | RxENABLE); if (chan->netdevice) netif_carrier_on(chan->netdevice); } else { - printk(KERN_INFO "%s: DCD lost\n", chan->dev->name); + pr_info("%s: DCD lost\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE); z8530_flush_fifo(chan); if (chan->netdevice) @@ -538,12 +540,12 @@ static void z8530_dma_tx(struct z8530_channel *chan) { if(!chan->dma_tx) { - printk(KERN_WARNING "Hey who turned the DMA off?\n"); + pr_warn("Hey who turned the DMA off?\n"); z8530_tx(chan); return; } /* This shouldn't occur in DMA mode */ - printk(KERN_ERR "DMA tx - bogus event!\n"); + pr_err("DMA tx - bogus event!\n"); z8530_tx(chan); } @@ -585,12 +587,12 @@ static void z8530_dma_status(struct z8530_channel *chan) if (altered & chan->dcdcheck) { if (status & chan->dcdcheck) { - printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); + pr_info("%s: DCD raised\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3] | RxENABLE); if (chan->netdevice) netif_carrier_on(chan->netdevice); } else { - printk(KERN_INFO "%s:DCD lost\n", chan->dev->name); + pr_info("%s: DCD lost\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE); z8530_flush_fifo(chan); if (chan->netdevice) @@ -712,7 +714,7 @@ irqreturn_t z8530_interrupt(int irq, void *dev_id) if(locker) { - printk(KERN_ERR "IRQ re-enter\n"); + pr_err("IRQ re-enter\n"); return IRQ_NONE; } locker=1; @@ -758,7 +760,8 @@ irqreturn_t z8530_interrupt(int irq, void *dev_id) } spin_unlock(&dev->lock); if(work==5000) - printk(KERN_ERR "%s: interrupt jammed - abort(0x%X)!\n", dev->name, intr); + pr_err("%s: interrupt jammed - abort(0x%X)!\n", + dev->name, intr); /* Ok all done */ locker=0; return IRQ_HANDLED; @@ -1225,7 +1228,7 @@ static const char *z8530_type_name[]={ void z8530_describe(struct z8530_dev *dev, char *mapping, unsigned long io) { - printk(KERN_INFO "%s: %s found at %s 0x%lX, IRQ %d.\n", + pr_info("%s: %s found at %s 0x%lX, IRQ %d\n", dev->name, z8530_type_name[dev->type], mapping, @@ -1621,8 +1624,7 @@ static void z8530_rx_done(struct z8530_channel *c) else /* Can't occur as we dont reenable the DMA irq until after the flip is done */ - printk(KERN_WARNING "%s: DMA flip overrun!\n", - c->netdevice->name); + netdev_warn(c->netdevice, "DMA flip overrun!\n"); release_dma_lock(flags); @@ -1637,8 +1639,7 @@ static void z8530_rx_done(struct z8530_channel *c) skb = dev_alloc_skb(ct); if (skb == NULL) { c->netdevice->stats.rx_dropped++; - printk(KERN_WARNING "%s: Memory squeeze.\n", - c->netdevice->name); + netdev_warn(c->netdevice, "Memory squeeze\n"); } else { skb_put(skb, ct); skb_copy_to_linear_data(skb, rxb, ct); @@ -1678,8 +1679,7 @@ static void z8530_rx_done(struct z8530_channel *c) c->skb2 = dev_alloc_skb(c->mtu); if (c->skb2 == NULL) - printk(KERN_WARNING "%s: memory squeeze.\n", - c->netdevice->name); + netdev_warn(c->netdevice, "memory squeeze\n"); else skb_put(c->skb2, c->mtu); c->netdevice->stats.rx_packets++; @@ -1693,7 +1693,7 @@ static void z8530_rx_done(struct z8530_channel *c) c->rx_function(c, skb); } else { c->netdevice->stats.rx_dropped++; - printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name); + netdev_err(c->netdevice, "Lost a frame\n"); } } -- cgit v1.2.3-70-g09d2 From 33dd74c7844852afba46f5e19911bcf55a1f04a1 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Sat, 14 May 2011 00:26:18 +0300 Subject: net: wl12xx: sdio: id_tables should be __devinitconst That's only needed during init anyway, let's free some space after we're done probing. Signed-off-by: Felipe Balbi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 536e5065454..d6dd49ace11 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -45,7 +45,7 @@ #define SDIO_DEVICE_ID_TI_WL1271 0x4076 #endif -static const struct sdio_device_id wl1271_devices[] = { +static const struct sdio_device_id wl1271_devices[] __devinitconst = { { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, {} }; -- cgit v1.2.3-70-g09d2 From 6bdaf79623e285242cb977840358dc7d14438475 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Sat, 14 May 2011 00:26:20 +0300 Subject: net: wl12xx: remove some unnecessary prints Those have little value. Remove those to make the driver less noisy. Signed-off-by: Felipe Balbi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index d6dd49ace11..3b78ab57bcc 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -303,8 +303,6 @@ static int __devinit wl1271_probe(struct sdio_func *func, /* Tell PM core that we don't need the card to be powered now */ pm_runtime_put_noidle(&func->dev); - wl1271_notice("initialized"); - return 0; out_irq: @@ -402,23 +400,12 @@ static struct sdio_driver wl1271_sdio_driver = { static int __init wl1271_init(void) { - int ret; - - ret = sdio_register_driver(&wl1271_sdio_driver); - if (ret < 0) { - wl1271_error("failed to register sdio driver: %d", ret); - goto out; - } - -out: - return ret; + return sdio_register_driver(&wl1271_sdio_driver); } static void __exit wl1271_exit(void) { sdio_unregister_driver(&wl1271_sdio_driver); - - wl1271_notice("unloaded"); } module_init(wl1271_init); -- cgit v1.2.3-70-g09d2 From 77d7d7a36d270fee4591c1c99c83c2da1f399d44 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Sat, 14 May 2011 00:26:21 +0300 Subject: net: wl12xx: care for optional operations ->init and ->reset are optional - at least sdio.c doesn't implement them - so allow those pointers to be NULL. Signed-off-by: Felipe Balbi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/io.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c index da5c1ad942a..f37a7933f90 100644 --- a/drivers/net/wireless/wl12xx/io.c +++ b/drivers/net/wireless/wl12xx/io.c @@ -128,12 +128,14 @@ EXPORT_SYMBOL_GPL(wl1271_set_partition); void wl1271_io_reset(struct wl1271 *wl) { - wl->if_ops->reset(wl); + if (wl->if_ops->reset) + wl->if_ops->reset(wl); } void wl1271_io_init(struct wl1271 *wl) { - wl->if_ops->init(wl); + if (wl->if_ops->init) + wl->if_ops->init(wl); } void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) -- cgit v1.2.3-70-g09d2 From 4c4cdfa12f389f0addbbbb6ac984997498a3c3af Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Sat, 14 May 2011 00:26:22 +0300 Subject: net: wl12xx: remove the nops Nops aren't needed. When we actually need those calls, then we add them with meat and barbecue sauce. Signed-off-by: Felipe Balbi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 3b78ab57bcc..4d5b4ce7a5c 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -107,14 +107,6 @@ static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) enable_irq(wl->irq); } -static void wl1271_sdio_reset(struct wl1271 *wl) -{ -} - -static void wl1271_sdio_init(struct wl1271 *wl) -{ -} - static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { @@ -215,8 +207,6 @@ static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) static struct wl1271_if_operations sdio_ops = { .read = wl1271_sdio_raw_read, .write = wl1271_sdio_raw_write, - .reset = wl1271_sdio_reset, - .init = wl1271_sdio_init, .power = wl1271_sdio_set_power, .dev = wl1271_sdio_wl_to_dev, .enable_irq = wl1271_sdio_enable_interrupts, -- cgit v1.2.3-70-g09d2 From ba2274c68e103271ba0c70fb8ad9afb4ede42d20 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Sat, 14 May 2011 00:26:23 +0300 Subject: net: wl12xx: remove unnecessary prints Those have little value. Remove those to make the driver less noisy. Signed-off-by: Felipe Balbi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/spi.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 51662bb6801..b73cee117ad 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -435,8 +435,6 @@ static int __devinit wl1271_probe(struct spi_device *spi) if (ret) goto out_irq; - wl1271_notice("initialized"); - return 0; out_irq: @@ -473,23 +471,12 @@ static struct spi_driver wl1271_spi_driver = { static int __init wl1271_init(void) { - int ret; - - ret = spi_register_driver(&wl1271_spi_driver); - if (ret < 0) { - wl1271_error("failed to register spi driver: %d", ret); - goto out; - } - -out: - return ret; + return spi_register_driver(&wl1271_spi_driver); } static void __exit wl1271_exit(void) { spi_unregister_driver(&wl1271_spi_driver); - - wl1271_notice("unloaded"); } module_init(wl1271_init); -- cgit v1.2.3-70-g09d2 From f84673d59773ded6efab640c5ee5f44b34116b75 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 15 May 2011 11:10:28 +0300 Subject: wl12xx: add support for rx streaming wl12xx supports the "rx streaming" feature: When in ps mode, and @timeout msecs have been passed since the last rx/tx, it issues trigger packets (QoS-null/PS-Poll packets, according to the ac type) in const intervals (in order to reduce the rx time). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 47 ++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/acx.h | 14 ++++++++++++ drivers/net/wireless/wl12xx/conf.h | 25 ++++++++++++++++++++ drivers/net/wireless/wl12xx/main.c | 5 ++++ 4 files changed, 91 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index c6ee530e5bf..edb389d6a29 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1577,6 +1577,53 @@ out: return ret; } +int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable) +{ + struct wl1271_acx_ps_rx_streaming *rx_streaming; + u32 conf_queues, enable_queues; + int i, ret = 0; + + wl1271_debug(DEBUG_ACX, "acx ps rx streaming"); + + rx_streaming = kzalloc(sizeof(*rx_streaming), GFP_KERNEL); + if (!rx_streaming) { + ret = -ENOMEM; + goto out; + } + + conf_queues = wl->conf.rx_streaming.queues; + if (enable) + enable_queues = conf_queues; + else + enable_queues = 0; + + for (i = 0; i < 8; i++) { + /* + * Skip non-changed queues, to avoid redundant acxs. + * this check assumes conf.rx_streaming.queues can't + * be changed while rx_streaming is enabled. + */ + if (!(conf_queues & BIT(i))) + continue; + + rx_streaming->tid = i; + rx_streaming->enable = enable_queues & BIT(i); + rx_streaming->period = wl->conf.rx_streaming.interval; + rx_streaming->timeout = wl->conf.rx_streaming.interval; + + ret = wl1271_cmd_configure(wl, ACX_PS_RX_STREAMING, + rx_streaming, + sizeof(*rx_streaming)); + if (ret < 0) { + wl1271_warning("acx ps rx streaming failed: %d", ret); + goto out; + } + } +out: + kfree(rx_streaming); + return ret; +} + int wl1271_acx_max_tx_retry(struct wl1271 *wl) { struct wl1271_acx_max_tx_retry *acx = NULL; diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 9a895e3cc61..f1d55313617 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1153,6 +1153,19 @@ struct wl1271_acx_fw_tsf_information { u8 padding[3]; } __packed; +struct wl1271_acx_ps_rx_streaming { + struct acx_header header; + + u8 tid; + u8 enable; + + /* interval between triggers (10-100 msec) */ + u8 period; + + /* timeout before first trigger (0-200 msec) */ + u8 timeout; +} __packed; + struct wl1271_acx_max_tx_retry { struct acx_header header; @@ -1384,6 +1397,7 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl, int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, bool enable); int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); +int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable); int wl1271_acx_max_tx_retry(struct wl1271 *wl); int wl1271_acx_config_ps(struct wl1271 *wl); int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index c83fefb6662..94a5c5646bb 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1248,6 +1248,30 @@ struct conf_fm_coex { u8 swallow_clk_diff; }; +struct conf_rx_streaming_settings { + /* + * RX Streaming duration (in msec) from last tx/rx + * + * Range: u32 + */ + u32 duration; + + /* + * Bitmap of tids to be polled during RX streaming. + * (Note: it doesn't look like it really matters) + * + * Range: 0x1-0xff + */ + u8 queues; + + /* + * RX Streaming interval. + * (Note:this value is also used as the rx streaming timeout) + * Range: 0 (disabled), 10 - 100 + */ + u8 interval; +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1263,6 +1287,7 @@ struct conf_drv_settings { struct conf_memory_settings mem_wl127x; struct conf_memory_settings mem_wl128x; struct conf_fm_coex fm_coex; + struct conf_rx_streaming_settings rx_streaming; u8 hci_io_ds; }; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index f37f0b873c7..a2171a4e941 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -362,6 +362,11 @@ static struct conf_drv_settings default_conf = { .fm_disturbed_band_margin = 0xff, /* default */ .swallow_clk_diff = 0xff, /* default */ }, + .rx_streaming = { + .duration = 150, + .queues = 0x1, + .interval = 20, + }, .hci_io_ds = HCI_IO_DS_6MA, }; -- cgit v1.2.3-70-g09d2 From 77ddaa108f727b5ef3be004b952d2c3d3ffc48e5 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 15 May 2011 11:10:29 +0300 Subject: wl12xx: add automatic rx streaming triggers When rx_streaming.interval is non-zero, use automatic rx streaming. Enable rx streaming on the each rx/tx packet, and disable it rx_streaming.duration msecs later. When rx_streaming.always=0 (default), rx streaming is enabled only when there is a coex operation. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/conf.h | 5 ++ drivers/net/wireless/wl12xx/event.c | 25 +++++-- drivers/net/wireless/wl12xx/main.c | 122 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/rx.c | 29 +++++++-- drivers/net/wireless/wl12xx/tx.c | 25 +++++++ drivers/net/wireless/wl12xx/wl12xx.h | 8 +++ 6 files changed, 203 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 94a5c5646bb..aa79b437e60 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1270,6 +1270,11 @@ struct conf_rx_streaming_settings { * Range: 0 (disabled), 10 - 100 */ u8 interval; + + /* + * enable rx streaming also when there is no coex activity + */ + u8 always; }; struct conf_drv_settings { diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 94bbd00ec31..0c60ffea414 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -183,6 +183,21 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed) ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid); } +static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, + u8 enable) +{ + if (enable) { + /* disable dynamic PS when requested by the firmware */ + ieee80211_disable_dyn_ps(wl->vif); + set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); + } else { + ieee80211_enable_dyn_ps(wl->vif); + clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); + wl1271_recalc_rx_streaming(wl); + } + +} + static void wl1271_event_mbox_dump(struct event_mailbox *mbox) { wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); @@ -226,14 +241,10 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) } } - /* disable dynamic PS when requested by the firmware */ if (vector & SOFT_GEMINI_SENSE_EVENT_ID && - wl->bss_type == BSS_TYPE_STA_BSS) { - if (mbox->soft_gemini_sense_info) - ieee80211_disable_dyn_ps(wl->vif); - else - ieee80211_enable_dyn_ps(wl->vif); - } + wl->bss_type == BSS_TYPE_STA_BSS) + wl12xx_event_soft_gemini_sense(wl, + mbox->soft_gemini_sense_info); /* * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index a2171a4e941..15d8166fbf6 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -366,6 +366,7 @@ static struct conf_drv_settings default_conf = { .duration = 150, .queues = 0x1, .interval = 20, + .always = 0, }, .hci_io_ds = HCI_IO_DS_6MA, }; @@ -478,6 +479,117 @@ static int wl1271_reg_notify(struct wiphy *wiphy, return 0; } +static int wl1271_set_rx_streaming(struct wl1271 *wl, bool enable) +{ + int ret = 0; + + /* we should hold wl->mutex */ + ret = wl1271_acx_ps_rx_streaming(wl, enable); + if (ret < 0) + goto out; + + if (enable) + set_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags); + else + clear_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags); +out: + return ret; +} + +/* + * this function is being called when the rx_streaming interval + * has beed changed or rx_streaming should be disabled + */ +int wl1271_recalc_rx_streaming(struct wl1271 *wl) +{ + int ret = 0; + int period = wl->conf.rx_streaming.interval; + + /* don't reconfigure if rx_streaming is disabled */ + if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags)) + goto out; + + /* reconfigure/disable according to new streaming_period */ + if (period && + test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) && + (wl->conf.rx_streaming.always || + test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) + ret = wl1271_set_rx_streaming(wl, true); + else { + ret = wl1271_set_rx_streaming(wl, false); + /* don't cancel_work_sync since we might deadlock */ + del_timer_sync(&wl->rx_streaming_timer); + } +out: + return ret; +} + +static void wl1271_rx_streaming_enable_work(struct work_struct *work) +{ + int ret; + struct wl1271 *wl = + container_of(work, struct wl1271, rx_streaming_enable_work); + + mutex_lock(&wl->mutex); + + if (test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags) || + !test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) || + (!wl->conf.rx_streaming.always && + !test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) + goto out; + + if (!wl->conf.rx_streaming.interval) + goto out; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1271_set_rx_streaming(wl, true); + if (ret < 0) + goto out_sleep; + + /* stop it after some time of inactivity */ + mod_timer(&wl->rx_streaming_timer, + jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration)); + +out_sleep: + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); +} + +static void wl1271_rx_streaming_disable_work(struct work_struct *work) +{ + int ret; + struct wl1271 *wl = + container_of(work, struct wl1271, rx_streaming_disable_work); + + mutex_lock(&wl->mutex); + + if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1271_set_rx_streaming(wl, false); + if (ret) + goto out_sleep; + +out_sleep: + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); +} + +static void wl1271_rx_streaming_timer(unsigned long data) +{ + struct wl1271 *wl = (struct wl1271 *)data; + ieee80211_queue_work(wl->hw, &wl->rx_streaming_disable_work); +} + static void wl1271_conf_init(struct wl1271 *wl) { @@ -1699,6 +1811,9 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, cancel_delayed_work_sync(&wl->scan_complete_work); cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->tx_work); + del_timer_sync(&wl->rx_streaming_timer); + cancel_work_sync(&wl->rx_streaming_enable_work); + cancel_work_sync(&wl->rx_streaming_disable_work); cancel_delayed_work_sync(&wl->pspoll_work); cancel_delayed_work_sync(&wl->elp_work); @@ -3969,6 +4084,11 @@ struct ieee80211_hw *wl1271_alloc_hw(void) INIT_WORK(&wl->tx_work, wl1271_tx_work); INIT_WORK(&wl->recovery_work, wl1271_recovery_work); INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); + INIT_WORK(&wl->rx_streaming_enable_work, + wl1271_rx_streaming_enable_work); + INIT_WORK(&wl->rx_streaming_disable_work, + wl1271_rx_streaming_disable_work); + wl->channel = WL1271_DEFAULT_CHANNEL; wl->beacon_int = WL1271_DEFAULT_BEACON_INT; wl->default_key = 0; @@ -3994,6 +4114,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->quirks = 0; wl->platform_quirks = 0; wl->sched_scanning = false; + setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer, + (unsigned long) wl); memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 70091035e01..db230a503bf 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -95,6 +95,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) struct ieee80211_hdr *hdr; u8 *buf; u8 beacon = 0; + u8 is_data = 0; /* * In PLT mode we seem to get frames and mac80211 warns about them, @@ -137,6 +138,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) hdr = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_beacon(hdr->frame_control)) beacon = 1; + if (ieee80211_is_data_present(hdr->frame_control)) + is_data = 1; wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); @@ -149,7 +152,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) skb_queue_tail(&wl->deferred_rx_queue, skb); ieee80211_queue_work(wl->hw, &wl->netstack_work); - return 0; + return is_data; } void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) @@ -162,6 +165,8 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) u32 mem_block; u32 pkt_length; u32 pkt_offset; + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + bool had_data = false; while (drv_rx_counter != fw_rx_counter) { buf_size = 0; @@ -214,9 +219,11 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) * conditions, in that case the received frame will just * be dropped. */ - wl1271_rx_handle_data(wl, - wl->aggr_buf + pkt_offset, - pkt_length); + if (wl1271_rx_handle_data(wl, + wl->aggr_buf + pkt_offset, + pkt_length) == 1) + had_data = true; + wl->rx_counter++; drv_rx_counter++; drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; @@ -230,6 +237,20 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) */ if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); + + if (!is_ap && wl->conf.rx_streaming.interval && had_data && + (wl->conf.rx_streaming.always || + test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) { + u32 timeout = wl->conf.rx_streaming.duration; + + /* restart rx streaming */ + if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags)) + ieee80211_queue_work(wl->hw, + &wl->rx_streaming_enable_work); + + mod_timer(&wl->rx_streaming_timer, + jiffies + msecs_to_jiffies(timeout)); + } } void wl1271_set_default_filters(struct wl1271 *wl) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index ca3ab1c1ace..6603e60da04 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -562,17 +562,29 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) spin_unlock_irqrestore(&wl->wl_lock, flags); } +static bool wl1271_tx_is_data_present(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + + return ieee80211_is_data_present(hdr->frame_control); +} + void wl1271_tx_work_locked(struct wl1271 *wl) { struct sk_buff *skb; u32 buf_offset = 0; bool sent_packets = false; + bool had_data = false; + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); int ret; if (unlikely(wl->state == WL1271_STATE_OFF)) return; while ((skb = wl1271_skb_dequeue(wl))) { + if (wl1271_tx_is_data_present(skb)) + had_data = true; + ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); if (ret == -EAGAIN) { /* @@ -619,6 +631,19 @@ out_ack: wl1271_handle_tx_low_watermark(wl); } + if (!is_ap && wl->conf.rx_streaming.interval && had_data && + (wl->conf.rx_streaming.always || + test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) { + u32 timeout = wl->conf.rx_streaming.duration; + + /* enable rx streaming */ + if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags)) + ieee80211_queue_work(wl->hw, + &wl->rx_streaming_enable_work); + + mod_timer(&wl->rx_streaming_timer, + jiffies + msecs_to_jiffies(timeout)); + } } void wl1271_tx_work(struct work_struct *work) diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 3bc794a1ee7..4bc22d8b66f 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -359,6 +359,8 @@ enum wl12xx_flags { WL1271_FLAG_DUMMY_PACKET_PENDING, WL1271_FLAG_SUSPENDED, WL1271_FLAG_PENDING_WORK, + WL1271_FLAG_SOFT_GEMINI, + WL1271_FLAG_RX_STREAMING_STARTED, }; struct wl1271_link { @@ -508,6 +510,11 @@ struct wl1271 { /* Default key (for WEP) */ u32 default_key; + /* Rx Streaming */ + struct work_struct rx_streaming_enable_work; + struct work_struct rx_streaming_disable_work; + struct timer_list rx_streaming_timer; + unsigned int filters; unsigned int rx_config; unsigned int rx_filter; @@ -602,6 +609,7 @@ struct wl1271_station { int wl1271_plt_start(struct wl1271 *wl); int wl1271_plt_stop(struct wl1271 *wl); +int wl1271_recalc_rx_streaming(struct wl1271 *wl); #define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ -- cgit v1.2.3-70-g09d2 From c84368e01a00f449d97e8a59e1b0c24dcf70a8b3 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 15 May 2011 11:10:30 +0300 Subject: wl12xx: add rx_streaming debugfs entry Allow control over rx_streaming interval and operation mode (always/only on coex) via debugfs. e.g. echo 100 > /debug/ieee80211/phy0/wl12xx/rx_streaming/interval echo 1 > /debug/ieee80211/phy0/wl12xx/rx_streaming/always Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 136 +++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index f1f8df9b6cd..c3f19463474 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -71,6 +71,14 @@ static const struct file_operations name## _ops = { \ if (!entry || IS_ERR(entry)) \ goto err; \ +#define DEBUGFS_ADD_PREFIX(prefix, name, parent) \ + do { \ + entry = debugfs_create_file(#name, 0400, parent, \ + wl, &prefix## _## name## _ops); \ + if (!entry || IS_ERR(entry)) \ + goto err; \ + } while (0); + #define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ static ssize_t sub## _ ##name## _read(struct file *file, \ char __user *userbuf, \ @@ -527,11 +535,129 @@ static const struct file_operations beacon_interval_ops = { .llseek = default_llseek, }; +static ssize_t rx_streaming_interval_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + char buf[10]; + size_t len; + unsigned long value; + int ret; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + buf[len] = '\0'; + + ret = kstrtoul(buf, 0, &value); + if (ret < 0) { + wl1271_warning("illegal value in rx_streaming_interval!"); + return -EINVAL; + } + + /* valid values: 0, 10-100 */ + if (value && (value < 10 || value > 100)) { + wl1271_warning("value is not in range!"); + return -ERANGE; + } + + mutex_lock(&wl->mutex); + + wl->conf.rx_streaming.interval = value; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + wl1271_recalc_rx_streaming(wl); + + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); + return count; +} + +static ssize_t rx_streaming_interval_read(struct file *file, + char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + return wl1271_format_buffer(userbuf, count, ppos, + "%d\n", wl->conf.rx_streaming.interval); +} + +static const struct file_operations rx_streaming_interval_ops = { + .read = rx_streaming_interval_read, + .write = rx_streaming_interval_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + +static ssize_t rx_streaming_always_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + char buf[10]; + size_t len; + unsigned long value; + int ret; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + buf[len] = '\0'; + + ret = kstrtoul(buf, 0, &value); + if (ret < 0) { + wl1271_warning("illegal value in rx_streaming_write!"); + return -EINVAL; + } + + /* valid values: 0, 10-100 */ + if (!(value == 0 || value == 1)) { + wl1271_warning("value is not in valid!"); + return -EINVAL; + } + + mutex_lock(&wl->mutex); + + wl->conf.rx_streaming.always = value; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + wl1271_recalc_rx_streaming(wl); + + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); + return count; +} + +static ssize_t rx_streaming_always_read(struct file *file, + char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + return wl1271_format_buffer(userbuf, count, ppos, + "%d\n", wl->conf.rx_streaming.always); +} + +static const struct file_operations rx_streaming_always_ops = { + .read = rx_streaming_always_read, + .write = rx_streaming_always_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + static int wl1271_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { int ret = 0; - struct dentry *entry, *stats; + struct dentry *entry, *stats, *streaming; stats = debugfs_create_dir("fw-statistics", rootdir); if (!stats || IS_ERR(stats)) { @@ -640,6 +766,14 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(dtim_interval, rootdir); DEBUGFS_ADD(beacon_interval, rootdir); + streaming = debugfs_create_dir("rx_streaming", rootdir); + if (!streaming || IS_ERR(streaming)) + goto err; + + DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming); + DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming); + + return 0; err: -- cgit v1.2.3-70-g09d2 From 0e44eb209343663ad7041ebf9f5d4c393bd89ae9 Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Mon, 16 May 2011 15:35:30 +0300 Subject: wl12xx: Enable beacon early termination in 2.4GHz band only Beacon early termination doesn't help much in the 5GHz band and masks channel switch IE Beacons. Thus, change the code to use BET only in 2.4GHz. [Reworded the commit log slightly -- Luca.] Signed-off-by: Shahar Levi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/event.c | 11 +++++++---- drivers/net/wireless/wl12xx/ps.c | 8 +++++--- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 0c60ffea414..a16dee58a66 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -133,10 +133,13 @@ static int wl1271_event_ps_report(struct wl1271 *wl, if (ret < 0) break; - /* enable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, true); - if (ret < 0) - break; + /* + * BET has only a minor effect in 5GHz and masks + * channel switch IEs, so we only enable BET on 2.4GHz + */ + if (wl->band == IEEE80211_BAND_2GHZ) + /* enable beacon early termination */ + ret = wl1271_acx_bet_enable(wl, true); if (wl->ps_compl) { complete(wl->ps_compl); diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index b59b67711a1..d3e377d7fe6 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -169,9 +169,11 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, wl1271_debug(DEBUG_PSM, "leaving psm"); /* disable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, false); - if (ret < 0) - return ret; + if (wl->band == IEEE80211_BAND_2GHZ) { + ret = wl1271_acx_bet_enable(wl, false); + if (ret < 0) + return ret; + } /* disable beacon filtering */ ret = wl1271_acx_beacon_filter_opt(wl, false); -- cgit v1.2.3-70-g09d2 From a011130265e999056fe0678a064d828c2fd40174 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 18 May 2011 11:24:16 +0300 Subject: wl12xx: remove unused crc7 references crc7 is used only in wl12xx_spi. Remove redundant crc7.h includes, and update Kconfig to select CRC7 only if WL12XX_SPI is being selected. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/Kconfig | 2 +- drivers/net/wireless/wl12xx/acx.c | 1 - drivers/net/wireless/wl12xx/cmd.c | 1 - drivers/net/wireless/wl12xx/io.c | 1 - drivers/net/wireless/wl12xx/sdio.c | 1 - 5 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 35ce7b0f4a6..07bcb1548d8 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -11,7 +11,6 @@ config WL12XX depends on WL12XX_MENU && GENERIC_HARDIRQS depends on INET select FW_LOADER - select CRC7 ---help--- This module adds support for wireless adapters based on TI wl1271 and TI wl1273 chipsets. This module does *not* include support for wl1251. @@ -33,6 +32,7 @@ config WL12XX_HT config WL12XX_SPI tristate "TI wl12xx SPI support" depends on WL12XX && SPI_MASTER + select CRC7 ---help--- This module adds support for the SPI interface of adapters using TI wl12xx chipsets. Select this if your platform is using diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index edb389d6a29..b5880eba06e 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -25,7 +25,6 @@ #include #include -#include #include #include diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 42935ac7266..b3a4f58249b 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c index f37a7933f90..c2da66f4504 100644 --- a/drivers/net/wireless/wl12xx/io.c +++ b/drivers/net/wireless/wl12xx/io.c @@ -23,7 +23,6 @@ #include #include -#include #include #include "wl12xx.h" diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 4d5b4ce7a5c..6b60caf7e3e 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From d192d268a1fb632148046b8efe9ab78e69890dd2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 24 May 2011 14:33:08 +0300 Subject: wl12xx: fix erroneous commit (cb5ae0) Due to rebase error, the patch for commit cb5ae0 ("wl12xx: configure rates when working in ibss mode") was wrong - a blob was added into the wrong function. fix it. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 15d8166fbf6..f19bf0ba438 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2900,24 +2900,6 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, } } - if (changed & BSS_CHANGED_IBSS) { - wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d", - bss_conf->ibss_joined); - - if (bss_conf->ibss_joined) { - u32 rates = bss_conf->basic_rates; - wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, - rates); - wl->basic_rate = wl1271_tx_min_rate_get(wl); - - /* by default, use 11b rates */ - wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; - ret = wl1271_acx_sta_rate_policies(wl); - if (ret < 0) - goto out; - } - } - ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed); if (ret < 0) goto out; @@ -3143,6 +3125,24 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } } + if (changed & BSS_CHANGED_IBSS) { + wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d", + bss_conf->ibss_joined); + + if (bss_conf->ibss_joined) { + u32 rates = bss_conf->basic_rates; + wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, + rates); + wl->basic_rate = wl1271_tx_min_rate_get(wl); + + /* by default, use 11b rates */ + wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES; + ret = wl1271_acx_sta_rate_policies(wl); + if (ret < 0) + goto out; + } + } + ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed); if (ret < 0) goto out; -- cgit v1.2.3-70-g09d2 From d2c2bb9fccdfe3cb70b276ae69e53d4890b11871 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 31 May 2011 16:38:56 +0300 Subject: wl12xx: split channel array per band in sched_scan The firmware, in practice, treats the channels in three separate blocks, one for each band (bg, a and j). Instead of using a single array and doing some magic with indices, split the array in 3 to make it more readable. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/scan.c | 61 ++++++++++++++++++-------------------- drivers/net/wireless/wl12xx/scan.h | 17 +++++------ 2 files changed, 36 insertions(+), 42 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 56f76abc754..cb84dd5edf4 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -326,7 +326,7 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, struct conn_scan_ch_params *channels, u32 band, bool radar, bool passive, - int start) + int start, int max_channels) { struct conf_sched_scan_settings *c = &wl->conf.sched_scan; int i, j; @@ -334,7 +334,7 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, bool force_passive = !req->n_ssids; for (i = 0, j = start; - i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS; + i < req->n_channels && j < max_channels; i++) { flags = req->channels[i]->flags; @@ -380,46 +380,42 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, return j - start; } -static int +static bool wl1271_scan_sched_scan_channels(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, struct wl1271_cmd_sched_scan_config *cfg) { - int idx = 0; - cfg->passive[0] = - wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, + wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, IEEE80211_BAND_2GHZ, - false, true, idx); - idx += cfg->passive[0]; - + false, true, 0, + MAX_CHANNELS_2GHZ); cfg->active[0] = - wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, + wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, IEEE80211_BAND_2GHZ, - false, false, idx); - /* - * 5GHz channels always start at position 14, not immediately - * after the last 2.4GHz channel - */ - idx = 14; - + false, false, + cfg->passive[0], + MAX_CHANNELS_2GHZ); cfg->passive[1] = - wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, + wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, IEEE80211_BAND_5GHZ, - false, true, idx); - idx += cfg->passive[1]; - + false, true, 0, + MAX_CHANNELS_5GHZ); cfg->dfs = - wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, + wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, IEEE80211_BAND_5GHZ, - true, true, idx); - idx += cfg->dfs; - + true, true, + cfg->passive[1], + MAX_CHANNELS_5GHZ); cfg->active[1] = - wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, + wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, IEEE80211_BAND_5GHZ, - false, false, idx); - idx += cfg->active[1]; + false, false, + cfg->passive[1] + cfg->dfs, + MAX_CHANNELS_5GHZ); + /* 802.11j channels are not supported yet */ + cfg->passive[2] = 0; + cfg->active[2] = 0; wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", cfg->active[0], cfg->passive[0]); @@ -427,7 +423,9 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, cfg->active[1], cfg->passive[1]); wl1271_debug(DEBUG_SCAN, " DFS: %d", cfg->dfs); - return idx; + return cfg->passive[0] || cfg->active[0] || + cfg->passive[1] || cfg->active[1] || cfg->dfs || + cfg->passive[2] || cfg->active[2]; } int wl1271_scan_sched_scan_config(struct wl1271 *wl, @@ -436,7 +434,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, { struct wl1271_cmd_sched_scan_config *cfg = NULL; struct conf_sched_scan_settings *c = &wl->conf.sched_scan; - int i, total_channels, ret; + int i, ret; bool force_passive = !req->n_ssids; wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); @@ -471,8 +469,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, cfg->ssid_len = 0; } - total_channels = wl1271_scan_sched_scan_channels(wl, req, cfg); - if (total_channels == 0) { + if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { wl1271_error("scan channel list is empty"); ret = -EINVAL; goto out; diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h index a0b6c5d67b0..ca81de20ebe 100644 --- a/drivers/net/wireless/wl12xx/scan.h +++ b/drivers/net/wireless/wl12xx/scan.h @@ -112,18 +112,13 @@ struct wl1271_cmd_trigger_scan_to { __le32 timeout; } __packed; -#define MAX_CHANNELS_ALL_BANDS 41 +#define MAX_CHANNELS_2GHZ 14 +#define MAX_CHANNELS_5GHZ 23 +#define MAX_CHANNELS_4GHZ 4 + #define SCAN_MAX_CYCLE_INTERVALS 16 #define SCAN_MAX_BANDS 3 -enum { - SCAN_CHANNEL_TYPE_2GHZ_PASSIVE, - SCAN_CHANNEL_TYPE_2GHZ_ACTIVE, - SCAN_CHANNEL_TYPE_5GHZ_PASSIVE, - SCAN_CHANNEL_TYPE_5GHZ_ACTIVE, - SCAN_CHANNEL_TYPE_5GHZ_DFS, -}; - enum { SCAN_SSID_FILTER_ANY = 0, SCAN_SSID_FILTER_SPECIFIC = 1, @@ -182,7 +177,9 @@ struct wl1271_cmd_sched_scan_config { u8 padding[3]; - struct conn_scan_ch_params channels[MAX_CHANNELS_ALL_BANDS]; + struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ]; + struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ]; + struct conn_scan_ch_params channels_4[MAX_CHANNELS_4GHZ]; } __packed; -- cgit v1.2.3-70-g09d2 From 86046da4afe068991b77e0a4c4b79b99ad961bda Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Sun, 29 May 2011 16:36:03 +0300 Subject: wl12xx: don't bail if mmc isn't MMC_CAP_POWER_OFF_CARD If our SDIO function has its runtime PM disabled, don't try to manipulate its runtime PM status at all. This way we can still power on cards plugged to mmc hosts that are not MMC_CAP_POWER_OFF_CARD. Reported-and-tested-by: Tim Yamin Signed-off-by: Ohad Ben-Cohen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 6b60caf7e3e..25215199049 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -161,10 +161,12 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) struct sdio_func *func = wl_to_func(wl); int ret; - /* Make sure the card will not be powered off by runtime PM */ - ret = pm_runtime_get_sync(&func->dev); - if (ret < 0) - goto out; + /* If enabled, tell runtime PM not to power off the card */ + if (pm_runtime_enabled(&func->dev)) { + ret = pm_runtime_get_sync(&func->dev); + if (ret) + goto out; + } /* Runtime PM might be disabled, so power up the card manually */ ret = mmc_power_restore_host(func->card->host); @@ -191,8 +193,11 @@ static int wl1271_sdio_power_off(struct wl1271 *wl) if (ret < 0) return ret; - /* Let runtime PM know the card is powered off */ - return pm_runtime_put_sync(&func->dev); + /* If enabled, let runtime PM know the card is powered off */ + if (pm_runtime_enabled(&func->dev)) + ret = pm_runtime_put_sync(&func->dev); + + return ret; } static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) -- cgit v1.2.3-70-g09d2 From 0c005048aa3cd3ac7bfdd3c6fcc20ea4f0ab667d Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Sun, 12 Jun 2011 10:34:43 +0300 Subject: wl12xx: Add Support for Low Power DRPw (LPD) Mode The Low Power DRPw (LPD) mode contains several optimizations that designed to reduce power consumption. The purpose is to save current consumption in RX and Listen mode. LPD setting apply only for wl127x AP mode (not wl128x) Signed-off-by: Shahar Levi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 3 +++ drivers/net/wireless/wl12xx/cmd.c | 5 +++++ drivers/net/wireless/wl12xx/ini.h | 3 +++ drivers/net/wireless/wl12xx/main.c | 9 +++++++-- drivers/net/wireless/wl12xx/wl12xx.h | 6 ++++++ 5 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 7ccec07a600..9dcfc6d1e86 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -749,6 +749,9 @@ int wl1271_load_firmware(struct wl1271 *wl) clk |= (wl->ref_clock << 1) << 4; } + if (wl->quirks & WL12XX_QUIRK_LPD_MODE) + clk |= SCRATCH_ENABLE_LPD; + wl1271_write32(wl, DRPW_SCRATCH_START, clk); wl1271_set_partition(wl, &part_table[PART_WORK]); diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index b3a4f58249b..cdcb324093a 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -134,6 +134,11 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) /* Override the REF CLK from the NVS with the one from platform data */ gen_parms->general_params.ref_clock = wl->ref_clock; + /* LPD mode enable (bits 6-7) in WL1271 AP mode only */ + if (wl->quirks & WL12XX_QUIRK_LPD_MODE) + gen_parms->general_params.general_settings |= + GENERAL_SETTINGS_DRPW_LPD; + ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); if (ret < 0) { wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); diff --git a/drivers/net/wireless/wl12xx/ini.h b/drivers/net/wireless/wl12xx/ini.h index 1420c842b8f..4cf9ecc5621 100644 --- a/drivers/net/wireless/wl12xx/ini.h +++ b/drivers/net/wireless/wl12xx/ini.h @@ -24,6 +24,9 @@ #ifndef __INI_H__ #define __INI_H__ +#define GENERAL_SETTINGS_DRPW_LPD 0xc0 +#define SCRATCH_ENABLE_LPD BIT(25) + #define WL1271_INI_MAX_SMART_REFLEX_PARAM 16 struct wl1271_ini_general_params { diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index f19bf0ba438..1b55803de88 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1191,9 +1191,13 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", wl->chip.id); - /* end-of-transaction flag should be set in wl127x AP mode */ + /* + * 'end-of-transaction flag' and 'LPD mode flag' + * should be set in wl127x AP mode only + */ if (wl->bss_type == BSS_TYPE_AP_BSS) - wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; + wl->quirks |= (WL12XX_QUIRK_END_OF_TRANSACTION | + WL12XX_QUIRK_LPD_MODE); ret = wl1271_setup(wl); if (ret < 0) @@ -1206,6 +1210,7 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) ret = wl1271_setup(wl); if (ret < 0) goto out; + if (wl1271_set_block_size(wl)) wl->quirks |= WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT; break; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 4bc22d8b66f..8d6c8f25841 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -645,4 +645,10 @@ int wl1271_recalc_rx_streaming(struct wl1271 *wl); /* WL128X requires aggregated packets to be aligned to the SDIO block size */ #define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2) +/* + * WL127X AP mode requires Low Power DRPw (LPD) enable to reduce power + * consumption + */ +#define WL12XX_QUIRK_LPD_MODE BIT(3) + #endif -- cgit v1.2.3-70-g09d2 From 4a859df85a7855b15f5e1bf4b0869a16757a3e43 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 6 Jun 2011 12:21:52 +0300 Subject: wl12xx: don't check wow param on suspend/resume Since mac80211 calls suspend/resume only when wowlan triggers exist, there is no need to check for triggers existance in the callbacks as well. Add a WARN_ON() to verify it. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 87 +++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 44 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 1b55803de88..8256f247004 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1551,69 +1551,68 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow) { struct wl1271 *wl = hw->priv; + int ret; + wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); - wl->wow_enabled = !!wow; - if (wl->wow_enabled) { - int ret; - ret = wl1271_configure_suspend(wl); - if (ret < 0) { - wl1271_warning("couldn't prepare device to suspend"); - return ret; - } - /* flush any remaining work */ - wl1271_debug(DEBUG_MAC80211, "flushing remaining works"); - flush_delayed_work(&wl->scan_complete_work); + WARN_ON(!wow || !wow->any); - /* - * disable and re-enable interrupts in order to flush - * the threaded_irq - */ - wl1271_disable_interrupts(wl); + wl->wow_enabled = true; + ret = wl1271_configure_suspend(wl); + if (ret < 0) { + wl1271_warning("couldn't prepare device to suspend"); + return ret; + } + /* flush any remaining work */ + wl1271_debug(DEBUG_MAC80211, "flushing remaining works"); + flush_delayed_work(&wl->scan_complete_work); - /* - * set suspended flag to avoid triggering a new threaded_irq - * work. no need for spinlock as interrupts are disabled. - */ - set_bit(WL1271_FLAG_SUSPENDED, &wl->flags); + /* + * disable and re-enable interrupts in order to flush + * the threaded_irq + */ + wl1271_disable_interrupts(wl); + + /* + * set suspended flag to avoid triggering a new threaded_irq + * work. no need for spinlock as interrupts are disabled. + */ + set_bit(WL1271_FLAG_SUSPENDED, &wl->flags); + + wl1271_enable_interrupts(wl); + flush_work(&wl->tx_work); + flush_delayed_work(&wl->pspoll_work); + flush_delayed_work(&wl->elp_work); - wl1271_enable_interrupts(wl); - flush_work(&wl->tx_work); - flush_delayed_work(&wl->pspoll_work); - flush_delayed_work(&wl->elp_work); - } return 0; } static int wl1271_op_resume(struct ieee80211_hw *hw) { struct wl1271 *wl = hw->priv; + unsigned long flags; + bool run_irq_work = false; + wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d", wl->wow_enabled); + WARN_ON(!wl->wow_enabled); /* * re-enable irq_work enqueuing, and call irq_work directly if * there is a pending work. */ - if (wl->wow_enabled) { - struct wl1271 *wl = hw->priv; - unsigned long flags; - bool run_irq_work = false; - - spin_lock_irqsave(&wl->wl_lock, flags); - clear_bit(WL1271_FLAG_SUSPENDED, &wl->flags); - if (test_and_clear_bit(WL1271_FLAG_PENDING_WORK, &wl->flags)) - run_irq_work = true; - spin_unlock_irqrestore(&wl->wl_lock, flags); - - if (run_irq_work) { - wl1271_debug(DEBUG_MAC80211, - "run postponed irq_work directly"); - wl1271_irq(0, wl); - wl1271_enable_interrupts(wl); - } + spin_lock_irqsave(&wl->wl_lock, flags); + clear_bit(WL1271_FLAG_SUSPENDED, &wl->flags); + if (test_and_clear_bit(WL1271_FLAG_PENDING_WORK, &wl->flags)) + run_irq_work = true; + spin_unlock_irqrestore(&wl->wl_lock, flags); - wl1271_configure_resume(wl); + if (run_irq_work) { + wl1271_debug(DEBUG_MAC80211, + "run postponed irq_work directly"); + wl1271_irq(0, wl); + wl1271_enable_interrupts(wl); } + wl1271_configure_resume(wl); return 0; } -- cgit v1.2.3-70-g09d2 From ff91afc90a736c97f24dec31e642411563906cfb Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 6 Jun 2011 12:21:53 +0300 Subject: wl12xx: clear wl->wow_enabled on resume We set wl->wow_enabled on every suspend(), so we need to clear it on every resume(). (we can't rely on setting wl->wow_enabled=false in suspend(), as it being called only when wowlan triggers are configured) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8256f247004..6a21c13761b 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1613,6 +1613,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) wl1271_enable_interrupts(wl); } wl1271_configure_resume(wl); + wl->wow_enabled = false; return 0; } -- cgit v1.2.3-70-g09d2 From 8a7cf3febbb2b7c1ade717ddb3065de67c5983c5 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 6 Jun 2011 12:21:54 +0300 Subject: wl12xx: enable/disable beacon filtering on ap suspend/resume Beacon filtering needs to be enabled so AP won't wake up by by every received beacon. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 49 +++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 6a21c13761b..00ee01e7d4a 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1474,13 +1474,10 @@ static struct notifier_block wl1271_dev_notifier = { }; #ifdef CONFIG_PM -static int wl1271_configure_suspend(struct wl1271 *wl) +static int wl1271_configure_suspend_sta(struct wl1271 *wl) { int ret; - if (wl->bss_type != BSS_TYPE_STA_BSS) - return 0; - mutex_lock(&wl->mutex); ret = wl1271_ps_elp_wakeup(wl); @@ -1525,11 +1522,41 @@ out: } +static int wl1271_configure_suspend_ap(struct wl1271 *wl) +{ + int ret; + + mutex_lock(&wl->mutex); + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out_unlock; + + ret = wl1271_acx_set_ap_beacon_filter(wl, true); + + wl1271_ps_elp_sleep(wl); +out_unlock: + mutex_unlock(&wl->mutex); + return ret; + +} + +static int wl1271_configure_suspend(struct wl1271 *wl) +{ + if (wl->bss_type == BSS_TYPE_STA_BSS) + return wl1271_configure_suspend_sta(wl); + if (wl->bss_type == BSS_TYPE_AP_BSS) + return wl1271_configure_suspend_ap(wl); + return 0; +} + static void wl1271_configure_resume(struct wl1271 *wl) { int ret; + bool is_sta = wl->bss_type == BSS_TYPE_STA_BSS; + bool is_ap = wl->bss_type == BSS_TYPE_AP_BSS; - if (wl->bss_type != BSS_TYPE_STA_BSS) + if (!is_sta && !is_ap) return; mutex_lock(&wl->mutex); @@ -1537,10 +1564,14 @@ static void wl1271_configure_resume(struct wl1271 *wl) if (ret < 0) goto out; - /* exit psm if it wasn't configured */ - if (!test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) - wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - wl->basic_rate, true); + if (is_sta) { + /* exit psm if it wasn't configured */ + if (!test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) + wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, + wl->basic_rate, true); + } else if (is_ap) { + wl1271_acx_set_ap_beacon_filter(wl, false); + } wl1271_ps_elp_sleep(wl); out: -- cgit v1.2.3-70-g09d2 From 6bb043321569ac356c790a8d3bd759742e1f9352 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 6 Jun 2011 12:21:55 +0300 Subject: wl12xx_sdio: enable wowlan only if enable_irq_wake() succeeded Some platforms don't support the wake_irq, so disable wowlan in this case, and avoid the "Unbalanced IRQ wake disable" warning on disable_irq_wake(). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 26 +++++++++++++++----------- drivers/net/wireless/wl12xx/wl12xx.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 25215199049..4dc4573b686 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -272,17 +272,19 @@ static int __devinit wl1271_probe(struct sdio_func *func, goto out_free; } - enable_irq_wake(wl->irq); - device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1); + ret = enable_irq_wake(wl->irq); + if (!ret) { + wl->irq_wake_enabled = true; + device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1); - disable_irq(wl->irq); - - /* if sdio can keep power while host is suspended, enable wow */ - mmcflags = sdio_get_host_pm_caps(func); - wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags); + /* if sdio can keep power while host is suspended, enable wow */ + mmcflags = sdio_get_host_pm_caps(func); + wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags); - if (mmcflags & MMC_PM_KEEP_POWER) - hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; + if (mmcflags & MMC_PM_KEEP_POWER) + hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; + } + disable_irq(wl->irq); ret = wl1271_init_ieee80211(wl); if (ret) @@ -316,8 +318,10 @@ static void __devexit wl1271_remove(struct sdio_func *func) pm_runtime_get_noresume(&func->dev); wl1271_unregister_hw(wl); - device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 0); - disable_irq_wake(wl->irq); + if (wl->irq_wake_enabled) { + device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 0); + disable_irq_wake(wl->irq); + } free_irq(wl->irq, wl); wl1271_free_hw(wl); } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 8d6c8f25841..145a14c2258 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -580,6 +580,7 @@ struct wl1271 { * (currently, only "ANY" trigger is supported) */ bool wow_enabled; + bool irq_wake_enabled; /* * AP-mode - links indexed by HLID. The global and broadcast links -- cgit v1.2.3-70-g09d2 From ef4b29e976f9e0a622dfd2722b443bb65686f47c Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 6 Jun 2011 13:03:12 +0300 Subject: wl12xx: check the vif's operstate after join When resuming while connected (without wowlan), the interface is already IF_OPER_UP, so we won't get the notifier callback, and hence never complete the association (from wl12xx perspective) This situation, among other potential problems, prevents the station from entering psm. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 00ee01e7d4a..8e2f560812d 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -394,6 +394,22 @@ static struct platform_device wl1271_device = { static DEFINE_MUTEX(wl_list_mutex); static LIST_HEAD(wl_list); +static int wl1271_check_operstate(struct wl1271 *wl, unsigned char operstate) +{ + int ret; + if (operstate != IF_OPER_UP) + return 0; + + if (test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) + return 0; + + ret = wl1271_cmd_set_sta_state(wl); + if (ret < 0) + return ret; + + wl1271_info("Association completed."); + return 0; +} static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, void *arg) { @@ -443,11 +459,7 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, if (ret < 0) goto out; - if ((dev->operstate == IF_OPER_UP) && - !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) { - wl1271_cmd_set_sta_state(wl); - wl1271_info("Association completed."); - } + wl1271_check_operstate(wl, dev->operstate); wl1271_ps_elp_sleep(wl); @@ -3217,6 +3229,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, wl1271_warning("cmd join failed %d", ret); goto out; } + wl1271_check_operstate(wl, ieee80211_get_operstate(vif)); } out: -- cgit v1.2.3-70-g09d2 From c27d3accb6f06b0afedfe472dfe0c8e7d87ff0a6 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 7 Jun 2011 10:40:39 +0300 Subject: wl12xx: use _ni version of ieee80211_tx_status wl1271_flush_deferred_work(), which calls ieee80211_rx() and ieee80211_tx_status(), is called from a process context. hence, use ieee80211_tx_status_ni() instead of ieee80211_tx_status(). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 2 +- drivers/net/wireless/wl12xx/ps.c | 2 +- drivers/net/wireless/wl12xx/tx.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8e2f560812d..c9f59ce0474 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -870,7 +870,7 @@ static void wl1271_flush_deferred_work(struct wl1271 *wl) /* Return sent skbs to the network stack */ while ((skb = skb_dequeue(&wl->deferred_tx_queue))) - ieee80211_tx_status(wl->hw, skb); + ieee80211_tx_status_ni(wl->hw, skb); } static void wl1271_netstack_work(struct work_struct *work) diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index d3e377d7fe6..5116db0826f 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -204,7 +204,7 @@ static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid) info = IEEE80211_SKB_CB(skb); info->flags |= IEEE80211_TX_STAT_TX_FILTERED; info->status.rates[0].idx = -1; - ieee80211_tx_status(wl->hw, skb); + ieee80211_tx_status_ni(wl->hw, skb); filtered++; } } diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 6603e60da04..b2635c7ecee 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -782,7 +782,7 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) info = IEEE80211_SKB_CB(skb); info->status.rates[0].idx = -1; info->status.rates[0].count = 0; - ieee80211_tx_status(wl->hw, skb); + ieee80211_tx_status_ni(wl->hw, skb); total++; } } @@ -820,7 +820,7 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) info = IEEE80211_SKB_CB(skb); info->status.rates[0].idx = -1; info->status.rates[0].count = 0; - ieee80211_tx_status(wl->hw, skb); + ieee80211_tx_status_ni(wl->hw, skb); } } } @@ -863,7 +863,7 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) info->status.rates[0].idx = -1; info->status.rates[0].count = 0; - ieee80211_tx_status(wl->hw, skb); + ieee80211_tx_status_ni(wl->hw, skb); } } } -- cgit v1.2.3-70-g09d2 From 92ef8960aee2f840c6a54c968d40199843f015c0 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 7 Jun 2011 12:50:46 +0300 Subject: wl12xx: use freezable workqueue for netstack_work When resuming (after wowlan), we want the rx packets (which is usually the wake-up packet itself) to be passed to mac80211 only after the resume notifier was completed, and mac80211 is up and running (otherwise, the packets will be dropped). By enqueueing the netstack_work to a freezable workqueue, we can guarantee the rx processing to occur only after mac80211 was resumed. Signed-off-by: Eliad Peller Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 12 +++++++++++- drivers/net/wireless/wl12xx/rx.c | 2 +- drivers/net/wireless/wl12xx/tx.c | 2 +- drivers/net/wireless/wl12xx/wl12xx.h | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index c9f59ce0474..ab3aa45db07 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4138,6 +4138,12 @@ struct ieee80211_hw *wl1271_alloc_hw(void) INIT_WORK(&wl->rx_streaming_disable_work, wl1271_rx_streaming_disable_work); + wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); + if (!wl->freezable_wq) { + ret = -ENOMEM; + goto err_hw; + } + wl->channel = WL1271_DEFAULT_CHANNEL; wl->beacon_int = WL1271_DEFAULT_BEACON_INT; wl->default_key = 0; @@ -4182,7 +4188,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); if (!wl->aggr_buf) { ret = -ENOMEM; - goto err_hw; + goto err_wq; } wl->dummy_packet = wl12xx_alloc_dummy_packet(wl); @@ -4227,6 +4233,9 @@ err_dummy_packet: err_aggr: free_pages((unsigned long)wl->aggr_buf, order); +err_wq: + destroy_workqueue(wl->freezable_wq); + err_hw: wl1271_debugfs_exit(wl); kfree(plat_dev); @@ -4257,6 +4266,7 @@ int wl1271_free_hw(struct wl1271 *wl) kfree(wl->fw_status); kfree(wl->tx_res_if); + destroy_workqueue(wl->freezable_wq); ieee80211_free_hw(wl->hw); diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index db230a503bf..9357695340c 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -150,7 +150,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) skb_trim(skb, skb->len - desc->pad_len); skb_queue_tail(&wl->deferred_rx_queue, skb); - ieee80211_queue_work(wl->hw, &wl->netstack_work); + queue_work(wl->freezable_wq, &wl->netstack_work); return is_data; } diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index b2635c7ecee..200590c0d9e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -727,7 +727,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, /* return the packet to the stack */ skb_queue_tail(&wl->deferred_tx_queue, skb); - ieee80211_queue_work(wl->hw, &wl->netstack_work); + queue_work(wl->freezable_wq, &wl->netstack_work); wl1271_free_tx_id(wl, result->id); } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 145a14c2258..bbf4ee6d410 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -445,6 +445,7 @@ struct wl1271 { struct sk_buff_head deferred_tx_queue; struct work_struct tx_work; + struct workqueue_struct *freezable_wq; /* Pending TX frames */ unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)]; -- cgit v1.2.3-70-g09d2 From 842f1a6c71551ac10fbdff4a4e65821228df9ea7 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 6 Jun 2011 14:57:04 +0300 Subject: wl12xx: Check for FW quirks as soon as the FW boots The FW initialization might depend on the FW revision, so check for any FW quirks right after booting it. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 21 +++++++++++++++++++++ drivers/net/wireless/wl12xx/main.c | 23 ----------------------- 2 files changed, 21 insertions(+), 23 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 9dcfc6d1e86..2f0fb6a5bfd 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -102,6 +102,24 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); } +static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl) +{ + unsigned int quirks = 0; + unsigned int *fw_ver = wl->chip.fw_ver; + + /* Only for wl127x */ + if ((fw_ver[FW_VER_CHIP] == FW_VER_CHIP_WL127X) && + /* Check STA version */ + (((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) && + (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_STA_MIN)) || + /* Check AP version */ + ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) && + (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN)))) + quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS; + + return quirks; +} + static void wl1271_parse_fw_ver(struct wl1271 *wl) { int ret; @@ -116,6 +134,9 @@ static void wl1271_parse_fw_ver(struct wl1271 *wl) memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver)); return; } + + /* Check if any quirks are needed with older fw versions */ + wl->quirks |= wl12xx_get_fw_ver_quirks(wl); } static void wl1271_boot_fw_version(struct wl1271 *wl) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index ab3aa45db07..2c03b4716d3 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1251,24 +1251,6 @@ out: return ret; } -static unsigned int wl1271_get_fw_ver_quirks(struct wl1271 *wl) -{ - unsigned int quirks = 0; - unsigned int *fw_ver = wl->chip.fw_ver; - - /* Only for wl127x */ - if ((fw_ver[FW_VER_CHIP] == FW_VER_CHIP_WL127X) && - /* Check STA version */ - (((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) && - (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_STA_MIN)) || - /* Check AP version */ - ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) && - (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN)))) - quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS; - - return quirks; -} - int wl1271_plt_start(struct wl1271 *wl) { int retries = WL1271_BOOT_RETRIES; @@ -1305,8 +1287,6 @@ int wl1271_plt_start(struct wl1271 *wl) wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver_str); - /* Check if any quirks are needed with older fw versions */ - wl->quirks |= wl1271_get_fw_ver_quirks(wl); goto out; irq_disable: @@ -1794,9 +1774,6 @@ power_off: strncpy(wiphy->fw_version, wl->chip.fw_ver_str, sizeof(wiphy->fw_version)); - /* Check if any quirks are needed with older fw versions */ - wl->quirks |= wl1271_get_fw_ver_quirks(wl); - /* * Now we know if 11a is supported (info from the NVS), so disable * 11a channels if not supported -- cgit v1.2.3-70-g09d2 From baacb9aed020b890ddf6a57837a169092a25fc9b Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 6 Jun 2011 14:57:05 +0300 Subject: wl12xx: Avoid recovery while one is already in progress During recovery work commands sent to the FW could fail and schedule additional recovery work. Since the chip is going to be powered off, avoid recursive recoveries. Signed-off-by: Ido Yariv Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 4 ++-- drivers/net/wireless/wl12xx/debugfs.c | 2 +- drivers/net/wireless/wl12xx/main.c | 14 +++++++++++++- drivers/net/wireless/wl12xx/ps.c | 2 +- drivers/net/wireless/wl12xx/scan.c | 2 +- drivers/net/wireless/wl12xx/testmode.c | 2 +- drivers/net/wireless/wl12xx/wl12xx.h | 2 ++ 7 files changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index cdcb324093a..f3d332d11f8 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -105,7 +105,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, fail: WARN_ON(1); - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl12xx_queue_recovery_work(wl); return ret; } @@ -356,7 +356,7 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask); if (ret != 0) { - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl12xx_queue_recovery_work(wl); return ret; } diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index c3f19463474..da212701830 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -306,7 +306,7 @@ static ssize_t start_recovery_write(struct file *file, struct wl1271 *wl = file->private_data; mutex_lock(&wl->mutex); - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl12xx_queue_recovery_work(wl); mutex_unlock(&wl->mutex); return count; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 2c03b4716d3..6926d0a3e5c 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -937,7 +937,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie) if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { wl1271_error("watchdog interrupt received! " "starting recovery."); - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl12xx_queue_recovery_work(wl); /* restarting the chip. ignore any other interrupt. */ goto out; @@ -1099,6 +1099,12 @@ out: return ret; } +void wl12xx_queue_recovery_work(struct wl1271 *wl) +{ + if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) + ieee80211_queue_work(wl->hw, &wl->recovery_work); +} + static void wl1271_recovery_work(struct work_struct *work) { struct wl1271 *wl = @@ -1109,6 +1115,9 @@ static void wl1271_recovery_work(struct work_struct *work) if (wl->state != WL1271_STATE_ON) goto out; + /* Avoid a recursive recovery */ + set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); + wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); @@ -1125,6 +1134,9 @@ static void wl1271_recovery_work(struct work_struct *work) /* reboot the chipset */ __wl1271_op_remove_interface(wl, false); + + clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); + ieee80211_restart_hw(wl->hw); /* diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 5116db0826f..3e68a664c9d 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -118,7 +118,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl) &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); if (ret == 0) { wl1271_error("ELP wakeup timeout!"); - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl12xx_queue_recovery_work(wl); ret = -ETIMEDOUT; goto err; } else if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index cb84dd5edf4..5e5c66dd06d 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -62,7 +62,7 @@ void wl1271_scan_complete_work(struct work_struct *work) if (wl->scan.failed) { wl1271_info("Scan completed due to error."); - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl12xx_queue_recovery_work(wl); } out: diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index da351d7cd1f..5d5e1ef8720 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -260,7 +260,7 @@ static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[]) { wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover"); - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl12xx_queue_recovery_work(wl); return 0; } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index bbf4ee6d410..754a16ce5bc 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -361,6 +361,7 @@ enum wl12xx_flags { WL1271_FLAG_PENDING_WORK, WL1271_FLAG_SOFT_GEMINI, WL1271_FLAG_RX_STREAMING_STARTED, + WL1271_FLAG_RECOVERY_IN_PROGRESS, }; struct wl1271_link { @@ -612,6 +613,7 @@ struct wl1271_station { int wl1271_plt_start(struct wl1271 *wl); int wl1271_plt_stop(struct wl1271 *wl); int wl1271_recalc_rx_streaming(struct wl1271 *wl); +void wl12xx_queue_recovery_work(struct wl1271 *wl); #define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ -- cgit v1.2.3-70-g09d2 From 95dac04f881322b510c45e5ae83f0dbee4f823a2 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 6 Jun 2011 14:57:06 +0300 Subject: wl12xx: Support routing FW logs to the host A recently added feature to the firmware enables the driver to retrieve firmware logs via the host bus (SDIO or SPI). There are two modes of operation: 1. On-demand: The FW collects its log in an internal ring buffer. This buffer can later be read, for example, upon recovery. 2. Continuous: The FW pushes the FW logs as special packets in the RX path. Reading the internal ring buffer does not involve the FW. Thus, as long as the HW is not in ELP, it should be possible to read the logs, even if the FW crashes. A sysfs binary file named "fwlog" was added to support this feature, letting a monitor process read the FW messages. The log is transferred from the FW only when available, so the reading process might block. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 1 + drivers/net/wireless/wl12xx/acx.h | 2 + drivers/net/wireless/wl12xx/boot.c | 9 ++ drivers/net/wireless/wl12xx/cmd.c | 84 ++++++++++++++ drivers/net/wireless/wl12xx/cmd.h | 62 +++++++++++ drivers/net/wireless/wl12xx/conf.h | 25 +++++ drivers/net/wireless/wl12xx/init.c | 19 ++++ drivers/net/wireless/wl12xx/io.h | 14 +++ drivers/net/wireless/wl12xx/main.c | 207 ++++++++++++++++++++++++++++++++++- drivers/net/wireless/wl12xx/rx.c | 8 ++ drivers/net/wireless/wl12xx/rx.h | 12 ++ drivers/net/wireless/wl12xx/wl12xx.h | 20 +++- 12 files changed, 459 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index b5880eba06e..87caa94fd81 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1067,6 +1067,7 @@ int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) mem_conf->tx_free_req = mem->min_req_tx_blocks; mem_conf->rx_free_req = mem->min_req_rx_blocks; mem_conf->tx_min = mem->tx_min; + mem_conf->fwlog_blocks = wl->conf.fwlog.mem_blocks; ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, sizeof(*mem_conf)); diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index f1d55313617..d303265f163 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -828,6 +828,8 @@ struct wl1271_acx_sta_config_memory { u8 tx_free_req; u8 rx_free_req; u8 tx_min; + u8 fwlog_blocks; + u8 padding[3]; } __packed; struct wl1271_acx_mem_map { diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 2f0fb6a5bfd..101f7e0f632 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -117,6 +117,15 @@ static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl) (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN)))) quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS; + /* Only new station firmwares support routing fw logs to the host */ + if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) && + (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN)) + quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED; + + /* This feature is not yet supported for AP mode */ + if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) + quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED; + return quirks; } diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index f3d332d11f8..c9a1fa52327 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -1234,3 +1234,87 @@ out_free: out: return ret; } + +int wl12xx_cmd_config_fwlog(struct wl1271 *wl) +{ + struct wl12xx_cmd_config_fwlog *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd config firmware logger"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->logger_mode = wl->conf.fwlog.mode; + cmd->log_severity = wl->conf.fwlog.severity; + cmd->timestamp = wl->conf.fwlog.timestamp; + cmd->output = wl->conf.fwlog.output; + cmd->threshold = wl->conf.fwlog.threshold; + + ret = wl1271_cmd_send(wl, CMD_CONFIG_FWLOGGER, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to send config firmware logger command"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} + +int wl12xx_cmd_start_fwlog(struct wl1271 *wl) +{ + struct wl12xx_cmd_start_fwlog *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd start firmware logger"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + ret = wl1271_cmd_send(wl, CMD_START_FWLOGGER, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to send start firmware logger command"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} + +int wl12xx_cmd_stop_fwlog(struct wl1271 *wl) +{ + struct wl12xx_cmd_stop_fwlog *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd stop firmware logger"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + ret = wl1271_cmd_send(wl, CMD_STOP_FWLOGGER, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to send stop firmware logger command"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 5cac95d9480..1f7037292c1 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -70,6 +70,9 @@ int wl1271_cmd_start_bss(struct wl1271 *wl); int wl1271_cmd_stop_bss(struct wl1271 *wl); int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid); int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid); +int wl12xx_cmd_config_fwlog(struct wl1271 *wl); +int wl12xx_cmd_start_fwlog(struct wl1271 *wl); +int wl12xx_cmd_stop_fwlog(struct wl1271 *wl); enum wl1271_commands { CMD_INTERROGATE = 1, /*use this to read information elements*/ @@ -107,6 +110,9 @@ enum wl1271_commands { CMD_START_PERIODIC_SCAN = 50, CMD_STOP_PERIODIC_SCAN = 51, CMD_SET_STA_STATE = 52, + CMD_CONFIG_FWLOGGER = 53, + CMD_START_FWLOGGER = 54, + CMD_STOP_FWLOGGER = 55, /* AP mode commands */ CMD_BSS_START = 60, @@ -575,4 +581,60 @@ struct wl1271_cmd_remove_sta { u8 padding1; } __packed; +/* + * Continuous mode - packets are transferred to the host periodically + * via the data path. + * On demand - Log messages are stored in a cyclic buffer in the + * firmware, and only transferred to the host when explicitly requested + */ +enum wl12xx_fwlogger_log_mode { + WL12XX_FWLOG_CONTINUOUS, + WL12XX_FWLOG_ON_DEMAND +}; + +/* Include/exclude timestamps from the log messages */ +enum wl12xx_fwlogger_timestamp { + WL12XX_FWLOG_TIMESTAMP_DISABLED, + WL12XX_FWLOG_TIMESTAMP_ENABLED +}; + +/* + * Logs can be routed to the debug pinouts (where available), to the host bus + * (SDIO/SPI), or dropped + */ +enum wl12xx_fwlogger_output { + WL12XX_FWLOG_OUTPUT_NONE, + WL12XX_FWLOG_OUTPUT_DBG_PINS, + WL12XX_FWLOG_OUTPUT_HOST, +}; + +struct wl12xx_cmd_config_fwlog { + struct wl1271_cmd_header header; + + /* See enum wl12xx_fwlogger_log_mode */ + u8 logger_mode; + + /* Minimum log level threshold */ + u8 log_severity; + + /* Include/exclude timestamps from the log messages */ + u8 timestamp; + + /* See enum wl1271_fwlogger_output */ + u8 output; + + /* Regulates the frequency of log messages */ + u8 threshold; + + u8 padding[3]; +} __packed; + +struct wl12xx_cmd_start_fwlog { + struct wl1271_cmd_header header; +} __packed; + +struct wl12xx_cmd_stop_fwlog { + struct wl1271_cmd_header header; +} __packed; + #endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index aa79b437e60..b5a7b30afda 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1277,6 +1277,30 @@ struct conf_rx_streaming_settings { u8 always; }; +struct conf_fwlog { + /* Continuous or on-demand */ + u8 mode; + + /* + * Number of memory blocks dedicated for the FW logger + * + * Range: 1-3, or 0 to disable the FW logger + */ + u8 mem_blocks; + + /* Minimum log level threshold */ + u8 severity; + + /* Include/exclude timestamps from the log messages */ + u8 timestamp; + + /* See enum wl1271_fwlogger_output */ + u8 output; + + /* Regulates the frequency of log messages */ + u8 threshold; +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1293,6 +1317,7 @@ struct conf_drv_settings { struct conf_memory_settings mem_wl128x; struct conf_fm_coex fm_coex; struct conf_rx_streaming_settings rx_streaming; + struct conf_fwlog fwlog; u8 hci_io_ds; }; diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index f5c2c9e6f84..cf40ac93cea 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -321,6 +321,20 @@ static int wl1271_init_beacon_broadcast(struct wl1271 *wl) return 0; } +static int wl12xx_init_fwlog(struct wl1271 *wl) +{ + int ret; + + if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) + return 0; + + ret = wl12xx_cmd_config_fwlog(wl); + if (ret < 0) + return ret; + + return 0; +} + static int wl1271_sta_hw_init(struct wl1271 *wl) { int ret; @@ -382,6 +396,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + /* Configure the FW logger */ + ret = wl12xx_init_fwlog(wl); + if (ret < 0) + return ret; + return 0; } diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index beed621a8ae..cfb3588a4dd 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h @@ -128,6 +128,20 @@ static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, wl1271_raw_write(wl, physical, buf, len, fixed); } +static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, + void *buf, size_t len, bool fixed) +{ + int physical; + int addr; + + /* Addresses are stored internally as addresses to 32 bytes blocks */ + addr = hwaddr << 5; + + physical = wl1271_translate_addr(wl, addr); + + wl1271_raw_read(wl, physical, buf, len, fixed); +} + static inline u32 wl1271_read32(struct wl1271 *wl, int addr) { return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 6926d0a3e5c..a3734bdf511 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "wl12xx.h" #include "wl12xx_80211.h" @@ -368,9 +369,19 @@ static struct conf_drv_settings default_conf = { .interval = 20, .always = 0, }, + .fwlog = { + .mode = WL12XX_FWLOG_ON_DEMAND, + .mem_blocks = 2, + .severity = 0, + .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, + .output = WL12XX_FWLOG_OUTPUT_HOST, + .threshold = 0, + }, .hci_io_ds = HCI_IO_DS_6MA, }; +static char *fwlog_param; + static void __wl1271_op_remove_interface(struct wl1271 *wl, bool reset_tx_queues); static void wl1271_free_ap_keys(struct wl1271 *wl); @@ -617,8 +628,24 @@ static void wl1271_conf_init(struct wl1271 *wl) /* apply driver default configuration */ memcpy(&wl->conf, &default_conf, sizeof(default_conf)); -} + /* Adjust settings according to optional module parameters */ + if (fwlog_param) { + if (!strcmp(fwlog_param, "continuous")) { + wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS; + } else if (!strcmp(fwlog_param, "ondemand")) { + wl->conf.fwlog.mode = WL12XX_FWLOG_ON_DEMAND; + } else if (!strcmp(fwlog_param, "dbgpins")) { + wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS; + wl->conf.fwlog.output = WL12XX_FWLOG_OUTPUT_DBG_PINS; + } else if (!strcmp(fwlog_param, "disable")) { + wl->conf.fwlog.mem_blocks = 0; + wl->conf.fwlog.output = WL12XX_FWLOG_OUTPUT_NONE; + } else { + wl1271_error("Unknown fwlog parameter %s", fwlog_param); + } + } +} static int wl1271_plt_init(struct wl1271 *wl) { @@ -1105,6 +1132,83 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl) ieee80211_queue_work(wl->hw, &wl->recovery_work); } +size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) +{ + size_t len = 0; + + /* The FW log is a length-value list, find where the log end */ + while (len < maxlen) { + if (memblock[len] == 0) + break; + if (len + memblock[len] + 1 > maxlen) + break; + len += memblock[len] + 1; + } + + /* Make sure we have enough room */ + len = min(len, (size_t)(PAGE_SIZE - wl->fwlog_size)); + + /* Fill the FW log file, consumed by the sysfs fwlog entry */ + memcpy(wl->fwlog + wl->fwlog_size, memblock, len); + wl->fwlog_size += len; + + return len; +} + +static void wl12xx_read_fwlog_panic(struct wl1271 *wl) +{ + u32 addr; + u32 first_addr; + u8 *block; + + if ((wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) || + (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) || + (wl->conf.fwlog.mem_blocks == 0)) + return; + + wl1271_info("Reading FW panic log"); + + block = kmalloc(WL12XX_HW_BLOCK_SIZE, GFP_KERNEL); + if (!block) + return; + + /* + * Make sure the chip is awake and the logger isn't active. + * This might fail if the firmware hanged. + */ + if (!wl1271_ps_elp_wakeup(wl)) + wl12xx_cmd_stop_fwlog(wl); + + /* Read the first memory block address */ + wl1271_fw_status(wl, wl->fw_status); + first_addr = __le32_to_cpu(wl->fw_status->sta.log_start_addr); + if (!first_addr) + goto out; + + /* Traverse the memory blocks linked list */ + addr = first_addr; + do { + memset(block, 0, WL12XX_HW_BLOCK_SIZE); + wl1271_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, + false); + + /* + * Memory blocks are linked to one another. The first 4 bytes + * of each memory block hold the hardware address of the next + * one. The last memory block points to the first one. + */ + addr = __le32_to_cpup((__le32 *)block); + if (!wl12xx_copy_fwlog(wl, block + sizeof(addr), + WL12XX_HW_BLOCK_SIZE - sizeof(addr))) + break; + } while (addr && (addr != first_addr)); + + wake_up_interruptible(&wl->fwlog_waitq); + +out: + kfree(block); +} + static void wl1271_recovery_work(struct work_struct *work) { struct wl1271 *wl = @@ -1118,6 +1222,8 @@ static void wl1271_recovery_work(struct work_struct *work) /* Avoid a recursive recovery */ set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); + wl12xx_read_fwlog_panic(wl); + wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); @@ -3942,6 +4048,69 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev, static DEVICE_ATTR(hw_pg_ver, S_IRUGO | S_IWUSR, wl1271_sysfs_show_hw_pg_ver, NULL); +static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t pos, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct wl1271 *wl = dev_get_drvdata(dev); + ssize_t len; + int ret; + + ret = mutex_lock_interruptible(&wl->mutex); + if (ret < 0) + return -ERESTARTSYS; + + /* Let only one thread read the log at a time, blocking others */ + while (wl->fwlog_size == 0) { + DEFINE_WAIT(wait); + + prepare_to_wait_exclusive(&wl->fwlog_waitq, + &wait, + TASK_INTERRUPTIBLE); + + if (wl->fwlog_size != 0) { + finish_wait(&wl->fwlog_waitq, &wait); + break; + } + + mutex_unlock(&wl->mutex); + + schedule(); + finish_wait(&wl->fwlog_waitq, &wait); + + if (signal_pending(current)) + return -ERESTARTSYS; + + ret = mutex_lock_interruptible(&wl->mutex); + if (ret < 0) + return -ERESTARTSYS; + } + + /* Check if the fwlog is still valid */ + if (wl->fwlog_size < 0) { + mutex_unlock(&wl->mutex); + return 0; + } + + /* Seeking is not supported - old logs are not kept. Disregard pos. */ + len = min(count, (size_t)wl->fwlog_size); + wl->fwlog_size -= len; + memcpy(buffer, wl->fwlog, len); + + /* Make room for new messages */ + memmove(wl->fwlog, wl->fwlog + len, wl->fwlog_size); + + mutex_unlock(&wl->mutex); + + return len; +} + +static struct bin_attribute fwlog_attr = { + .attr = {.name = "fwlog", .mode = S_IRUSR}, + .read = wl1271_sysfs_read_fwlog, +}; + int wl1271_register_hw(struct wl1271 *wl) { int ret; @@ -4160,6 +4329,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->sched_scanning = false; setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer, (unsigned long) wl); + wl->fwlog_size = 0; + init_waitqueue_head(&wl->fwlog_waitq); memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) @@ -4186,11 +4357,18 @@ struct ieee80211_hw *wl1271_alloc_hw(void) goto err_aggr; } + /* Allocate one page for the FW log */ + wl->fwlog = (u8 *)get_zeroed_page(GFP_KERNEL); + if (!wl->fwlog) { + ret = -ENOMEM; + goto err_dummy_packet; + } + /* Register platform device */ ret = platform_device_register(wl->plat_dev); if (ret) { wl1271_error("couldn't register platform device"); - goto err_dummy_packet; + goto err_fwlog; } dev_set_drvdata(&wl->plat_dev->dev, wl); @@ -4208,14 +4386,27 @@ struct ieee80211_hw *wl1271_alloc_hw(void) goto err_bt_coex_state; } + /* Create sysfs file for the FW log */ + ret = device_create_bin_file(&wl->plat_dev->dev, &fwlog_attr); + if (ret < 0) { + wl1271_error("failed to create sysfs file fwlog"); + goto err_hw_pg_ver; + } + return hw; +err_hw_pg_ver: + device_remove_file(&wl->plat_dev->dev, &dev_attr_hw_pg_ver); + err_bt_coex_state: device_remove_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); err_platform: platform_device_unregister(wl->plat_dev); +err_fwlog: + free_page((unsigned long)wl->fwlog); + err_dummy_packet: dev_kfree_skb(wl->dummy_packet); @@ -4240,7 +4431,15 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw); int wl1271_free_hw(struct wl1271 *wl) { + /* Unblock any fwlog readers */ + mutex_lock(&wl->mutex); + wl->fwlog_size = -1; + wake_up_interruptible_all(&wl->fwlog_waitq); + mutex_unlock(&wl->mutex); + + device_remove_bin_file(&wl->plat_dev->dev, &fwlog_attr); platform_device_unregister(wl->plat_dev); + free_page((unsigned long)wl->fwlog); dev_kfree_skb(wl->dummy_packet); free_pages((unsigned long)wl->aggr_buf, get_order(WL1271_AGGR_BUFFER_SIZE)); @@ -4268,6 +4467,10 @@ EXPORT_SYMBOL_GPL(wl12xx_debug_level); module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); +module_param_named(fwlog, fwlog_param, charp, 0); +MODULE_PARM_DESC(keymap, + "FW logger options: continuous, ondemand, dbgpins or disable"); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 9357695340c..0450fb49dbb 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -22,6 +22,7 @@ */ #include +#include #include "wl12xx.h" #include "acx.h" @@ -107,6 +108,13 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) /* the data read starts with the descriptor */ desc = (struct wl1271_rx_descriptor *) data; + if (desc->packet_class == WL12XX_RX_CLASS_LOGGER) { + size_t len = length - sizeof(*desc); + wl12xx_copy_fwlog(wl, data + sizeof(*desc), len); + wake_up_interruptible(&wl->fwlog_waitq); + return 0; + } + switch (desc->status & WL1271_RX_DESC_STATUS_MASK) { /* discard corrupted packets */ case WL1271_RX_DESC_DRIVER_RX_Q_FAIL: diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h index 75fabf83649..c88e3fa1d60 100644 --- a/drivers/net/wireless/wl12xx/rx.h +++ b/drivers/net/wireless/wl12xx/rx.h @@ -97,6 +97,18 @@ #define RX_BUF_SIZE_MASK 0xFFF00 #define RX_BUF_SIZE_SHIFT_DIV 6 +enum { + WL12XX_RX_CLASS_UNKNOWN, + WL12XX_RX_CLASS_MANAGEMENT, + WL12XX_RX_CLASS_DATA, + WL12XX_RX_CLASS_QOS_DATA, + WL12XX_RX_CLASS_BCN_PRBRSP, + WL12XX_RX_CLASS_EAPOL, + WL12XX_RX_CLASS_BA_EVENT, + WL12XX_RX_CLASS_AMSDU, + WL12XX_RX_CLASS_LOGGER, +}; + struct wl1271_rx_descriptor { __le16 length; u8 status; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 754a16ce5bc..d7db6e77047 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -226,6 +226,8 @@ enum { #define FW_VER_MINOR_1_SPARE_STA_MIN 58 #define FW_VER_MINOR_1_SPARE_AP_MIN 47 +#define FW_VER_MINOR_FWLOG_STA_MIN 70 + struct wl1271_chip { u32 id; char fw_ver_str[ETHTOOL_BUSINFO_LEN]; @@ -284,8 +286,7 @@ struct wl1271_fw_sta_status { u8 tx_total; u8 reserved1; __le16 reserved2; - /* Total structure size is 68 bytes */ - u32 padding; + __le32 log_start_addr; } __packed; struct wl1271_fw_full_status { @@ -472,6 +473,15 @@ struct wl1271 { /* Network stack work */ struct work_struct netstack_work; + /* FW log buffer */ + u8 *fwlog; + + /* Number of valid bytes in the FW log buffer */ + ssize_t fwlog_size; + + /* Sysfs FW log entry readers wait queue */ + wait_queue_head_t fwlog_waitq; + /* Hardware recovery work */ struct work_struct recovery_work; @@ -614,6 +624,7 @@ int wl1271_plt_start(struct wl1271 *wl); int wl1271_plt_stop(struct wl1271 *wl); int wl1271_recalc_rx_streaming(struct wl1271 *wl); void wl12xx_queue_recovery_work(struct wl1271 *wl); +size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); #define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ @@ -655,4 +666,9 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl); */ #define WL12XX_QUIRK_LPD_MODE BIT(3) +/* Older firmwares did not implement the FW logger over bus feature */ +#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4) + +#define WL12XX_HW_BLOCK_SIZE 256 + #endif -- cgit v1.2.3-70-g09d2 From 23a8c61416955718dfa7ecbb88184b8307ef7c90 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:09:09 -0500 Subject: rtlwifi: rtl8192de: Merge def.h Introduce routine def.h for rtl8192de. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/def.h | 269 +++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/def.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h new file mode 100644 index 00000000000..f0f5f9bfbb7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92D_DEF_H__ +#define __RTL92D_DEF_H__ + +/* Min Spacing related settings. */ +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG 0x3F +#define RF6052_MAX_PATH 2 + +#define HAL_RETRY_LIMIT_INFRA 48 +#define HAL_RETRY_LIMIT_AP_ADHOC 7 + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +#define RESET_DELAY_8185 20 + +#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) + +#define NUM_OF_FIRMWARE_QUEUE 10 +#define NUM_OF_PAGES_IN_FW 0x100 +#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1 + +#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00 + +#define MAX_LINES_HWCONFIG_TXT 1000 +#define MAX_BYTES_LINE_HWCONFIG_TXT 256 + +#define SW_THREE_WIRE 0 +#define HW_THREE_WIRE 2 + +#define BT_DEMO_BOARD 0 +#define BT_QA_BOARD 1 +#define BT_FPGA 2 + +#define RX_SMOOTH_FACTOR 20 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define MAX_H2C_QUEUE_NUM 10 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 +#define RX_MAX_QUEUE 2 + +#define C2H_RX_CMD_HDR_LEN 8 +#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 0, 16) +#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 16, 8) +#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 24, 7) +#define GET_C2H_CMD_CONTINUE(__prxhdr) \ + LE_BITS_TO_4BYTE((__prxhdr), 31, 1) +#define GET_C2H_CMD_CONTENT(__prxhdr) \ + ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN) + +#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8) +#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8) +#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16) +#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5) +#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1) +#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5) +#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1) +#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4) +#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \ + LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) + +/* + * 92D chip ver: + * BIT8: IS 92D + * BIT9: single phy + * BIT10: C-cut + * BIT11: D-cut + */ + +/* Chip specific */ +#define CHIP_92C BIT(0) +#define CHIP_92C_1T2R BIT(1) +#define CHIP_8723 BIT(2) /* RTL8723 With BT feature */ +#define CHIP_8723_DRV_REV BIT(3) /* RTL8723 Driver Revised */ +#define NORMAL_CHIP BIT(4) +#define CHIP_VENDOR_UMC BIT(5) +#define CHIP_VENDOR_UMC_B_CUT BIT(6) /* Chip version for ECO */ + +/* for 92D */ +#define CHIP_92D BIT(8) +#define CHIP_92D_SINGLEPHY BIT(9) +#define CHIP_92D_C_CUT BIT(10) +#define CHIP_92D_D_CUT BIT(11) + +enum version_8192d { + VERSION_TEST_CHIP_88C = 0x00, + VERSION_TEST_CHIP_92C = 0x01, + VERSION_NORMAL_TSMC_CHIP_88C = 0x10, + VERSION_NORMAL_TSMC_CHIP_92C = 0x11, + VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13, + VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30, + VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33, + VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34, + VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c, + VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70, + VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73, + VERSION_TEST_CHIP_92D_SINGLEPHY = 0x300, + VERSION_TEST_CHIP_92D_DUALPHY = 0x100, + VERSION_NORMAL_CHIP_92D_SINGLEPHY = 0x310, + VERSION_NORMAL_CHIP_92D_DUALPHY = 0x110, + VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x710, + VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x510, + VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0xB10, + VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x910, +}; + +#define IS_92D_SINGLEPHY(version) \ + ((version & CHIP_92D_SINGLEPHY) ? true : false) +#define IS_92D_C_CUT(version) \ + ((version & CHIP_92D_C_CUT) ? true : false) +#define IS_92D_D_CUT(version) \ + ((version & CHIP_92D_D_CUT) ? true : false) + +enum rf_optype { + RF_OP_BY_SW_3WIRE = 0, + RF_OP_BY_FW, + RF_OP_MAX +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum rtl_desc92d_rate { + DESC92D_RATE1M = 0x00, + DESC92D_RATE2M = 0x01, + DESC92D_RATE5_5M = 0x02, + DESC92D_RATE11M = 0x03, + + DESC92D_RATE6M = 0x04, + DESC92D_RATE9M = 0x05, + DESC92D_RATE12M = 0x06, + DESC92D_RATE18M = 0x07, + DESC92D_RATE24M = 0x08, + DESC92D_RATE36M = 0x09, + DESC92D_RATE48M = 0x0a, + DESC92D_RATE54M = 0x0b, + + DESC92D_RATEMCS0 = 0x0c, + DESC92D_RATEMCS1 = 0x0d, + DESC92D_RATEMCS2 = 0x0e, + DESC92D_RATEMCS3 = 0x0f, + DESC92D_RATEMCS4 = 0x10, + DESC92D_RATEMCS5 = 0x11, + DESC92D_RATEMCS6 = 0x12, + DESC92D_RATEMCS7 = 0x13, + DESC92D_RATEMCS8 = 0x14, + DESC92D_RATEMCS9 = 0x15, + DESC92D_RATEMCS10 = 0x16, + DESC92D_RATEMCS11 = 0x17, + DESC92D_RATEMCS12 = 0x18, + DESC92D_RATEMCS13 = 0x19, + DESC92D_RATEMCS14 = 0x1a, + DESC92D_RATEMCS15 = 0x1b, + DESC92D_RATEMCS15_SG = 0x1c, + DESC92D_RATEMCS32 = 0x20, +}; + +enum channel_plan { + CHPL_FCC = 0, + CHPL_IC = 1, + CHPL_ETSI = 2, + CHPL_SPAIN = 3, + CHPL_FRANCE = 4, + CHPL_MKK = 5, + CHPL_MKK1 = 6, + CHPL_ISRAEL = 7, + CHPL_TELEC = 8, + CHPL_GLOBAL = 9, + CHPL_WORLD = 10, +}; + +struct phy_sts_cck_8192d { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + +struct h2c_cmd_8192c { + u8 element_id; + u32 cmd_len; + u8 *p_cmdbuffer; +}; + +struct txpower_info { + u8 cck_index[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht40_1sindex[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht40_2sindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht20indexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ofdmindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht40maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 ht20maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX]; + u8 tssi_a[3]; /* 5GL/5GM/5GH */ + u8 tssi_b[3]; +}; + +#endif -- cgit v1.2.3-70-g09d2 From 4f01358e5b8a4b0f67cfc7bf785756193006de96 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:09:25 -0500 Subject: rtlwifi: rtl8192de: Merge dynamic management routines Merge routines dm.c and dm.h for RTL8192DE. Signed-off-by: Larry Finger Signed-off-by: Chaoming_Li Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 1355 +++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/dm.h | 212 +++++ 2 files changed, 1567 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/dm.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/dm.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c new file mode 100644 index 00000000000..d0baaf269a1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -0,0 +1,1355 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" + +#define UNDEC_SM_PWDB entry_min_undecoratedsmoothed_pwdb + +struct dig_t dm_digtable; + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = { + 0x7f8001fe, /* 0, +6.0dB */ + 0x788001e2, /* 1, +5.5dB */ + 0x71c001c7, /* 2, +5.0dB */ + 0x6b8001ae, /* 3, +4.5dB */ + 0x65400195, /* 4, +4.0dB */ + 0x5fc0017f, /* 5, +3.5dB */ + 0x5a400169, /* 6, +3.0dB */ + 0x55400155, /* 7, +2.5dB */ + 0x50800142, /* 8, +2.0dB */ + 0x4c000130, /* 9, +1.5dB */ + 0x47c0011f, /* 10, +1.0dB */ + 0x43c0010f, /* 11, +0.5dB */ + 0x40000100, /* 12, +0dB */ + 0x3c8000f2, /* 13, -0.5dB */ + 0x390000e4, /* 14, -1.0dB */ + 0x35c000d7, /* 15, -1.5dB */ + 0x32c000cb, /* 16, -2.0dB */ + 0x300000c0, /* 17, -2.5dB */ + 0x2d4000b5, /* 18, -3.0dB */ + 0x2ac000ab, /* 19, -3.5dB */ + 0x288000a2, /* 20, -4.0dB */ + 0x26000098, /* 21, -4.5dB */ + 0x24000090, /* 22, -5.0dB */ + 0x22000088, /* 23, -5.5dB */ + 0x20000080, /* 24, -6.0dB */ + 0x1e400079, /* 25, -6.5dB */ + 0x1c800072, /* 26, -7.0dB */ + 0x1b00006c, /* 27. -7.5dB */ + 0x19800066, /* 28, -8.0dB */ + 0x18000060, /* 29, -8.5dB */ + 0x16c0005b, /* 30, -9.0dB */ + 0x15800056, /* 31, -9.5dB */ + 0x14400051, /* 32, -10.0dB */ + 0x1300004c, /* 33, -10.5dB */ + 0x12000048, /* 34, -11.0dB */ + 0x11000044, /* 35, -11.5dB */ + 0x10000040, /* 36, -12.0dB */ + 0x0f00003c, /* 37, -12.5dB */ + 0x0e400039, /* 38, -13.0dB */ + 0x0d800036, /* 39, -13.5dB */ + 0x0cc00033, /* 40, -14.0dB */ + 0x0c000030, /* 41, -14.5dB */ + 0x0b40002d, /* 42, -15.0dB */ +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */ + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */ +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */ + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */ +}; + +static void rtl92d_dm_diginit(struct ieee80211_hw *hw) +{ + dm_digtable.dig_enable_flag = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0x0; + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; + dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; + dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; + dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; + dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + dm_digtable.rx_gain_range_max = DM_DIG_FA_UPPER; + dm_digtable.rx_gain_range_min = DM_DIG_FA_LOWER; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI; + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; + dm_digtable.large_fa_hit = 0; + dm_digtable.recover_cnt = 0; + dm_digtable.forbidden_igi = DM_DIG_FA_LOWER; +} + +static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + unsigned long flag = 0; + + /* hold ofdm counter */ + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); /* hold page C counter */ + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); /*hold page D counter */ + + ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, BMASKDWORD); + falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, BMASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, BMASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, BMASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail; + + if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) { + /* hold cck counter */ + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, BMASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, BMASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } else { + falsealm_cnt->cnt_cck_fail = 0; + } + + /* reset false alarm counter registers */ + falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail + + falsealm_cnt->cnt_sb_search_fail + + falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail; + + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + /* update ofdm counter */ + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + /* update page C counter */ + rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0); + /* update page D counter */ + rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0); + if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) { + /* reset cck counter */ + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + /* enable cck counter */ + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Fast_Fsync_fail = %x, " + "Cnt_SB_Search_fail = %x\n", + falsealm_cnt->cnt_fast_fsync_fail, + falsealm_cnt->cnt_sb_search_fail)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %x, " + "Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, " + "Cnt_Mcs_fail = %x\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, + falsealm_cnt->cnt_mcs_fail)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("Cnt_Ofdm_fail = %x, " "Cnt_Cck_fail = %x, " + "Cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, + falsealm_cnt->cnt_all)); +} + +static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtlpriv); + + /* Determine the minimum RSSI */ + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { + dm_digtable.min_undecorated_pwdb_for_dm = 0; + RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + ("Not connected to any\n")); + } + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + dm_digtable.min_undecorated_pwdb_for_dm = + rtlpriv->dm.UNDEC_SM_PWDB; + RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + rtlpriv->dm.UNDEC_SM_PWDB)); + } else { + dm_digtable.min_undecorated_pwdb_for_dm = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + ("STA Default Port PWDB = 0x%x\n", + dm_digtable.min_undecorated_pwdb_for_dm)); + } + } else { + dm_digtable.min_undecorated_pwdb_for_dm = + rtlpriv->dm.UNDEC_SM_PWDB; + RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, + ("AP Ext Port or disconnet PWDB = 0x%x\n", + dm_digtable.min_undecorated_pwdb_for_dm)); + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n", + dm_digtable.min_undecorated_pwdb_for_dm)); +} + +static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned long flag = 0; + + if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + if (dm_digtable.min_undecorated_pwdb_for_dm <= 25) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } else { + if (dm_digtable.min_undecorated_pwdb_for_dm <= 20) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LOWRSSI; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HIGHRSSI; + } + } else { + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; + } + if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { + if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0x83); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } else { + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0xcd); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; + } + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n", + (dm_digtable.cursta_connectctate == DIG_STA_CONNECT ? + "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n", + (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? + "Low RSSI " : "High RSSI "))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n", + IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))); + +} + +void rtl92d_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, " + "pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val)); + if (dm_digtable.dig_enable_flag == false) { + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n")); + dm_digtable.pre_igvalue = 0x17; + return; + } + if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; + } +} + +static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) +{ + if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && + (rtlpriv->mac80211.vendor == PEER_CISCO)) { + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("IOT_PEER = CISCO\n")); + if (dm_digtable.last_min_undecorated_pwdb_for_dm >= 50 + && dm_digtable.min_undecorated_pwdb_for_dm < 50) { + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("Early Mode Off\n")); + } else if (dm_digtable.last_min_undecorated_pwdb_for_dm <= 55 && + dm_digtable.min_undecorated_pwdb_for_dm > 55) { + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("Early Mode On\n")); + } + } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) { + rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n")); + } +} + +static void rtl92d_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value_igi = dm_digtable.cur_igvalue; + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n")); + if (rtlpriv->rtlhal.earlymode_enable) { + rtl92d_early_mode_enabled(rtlpriv); + dm_digtable.last_min_undecorated_pwdb_for_dm = + dm_digtable.min_undecorated_pwdb_for_dm; + } + if (rtlpriv->dm.dm_initialgain_enable == false) + return; + + /* because we will send data pkt when scanning + * this will cause some ap like gear-3700 wep TP + * lower if we retrun here, this is the diff of + * mac80211 driver vs ieee80211 driver */ + /* if (rtlpriv->mac80211.act_scanning) + * return; */ + + /* Not STA mode return tmp */ + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + return; + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n")); + /* Decide the current status and if modify initial gain or not */ + if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) + dm_digtable.cursta_connectctate = DIG_STA_CONNECT; + else + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + + /* adjust initial gain according to false alarm counter */ + if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", + dm_digtable.large_fa_hit, dm_digtable.forbidden_igi)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", + dm_digtable.recover_cnt, dm_digtable.rx_gain_range_min)); + + /* deal with abnorally large false alarm */ + if (falsealm_cnt->cnt_all > 10000) { + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("dm_DIG(): Abnornally false alarm case.\n")); + + dm_digtable.large_fa_hit++; + if (dm_digtable.forbidden_igi < dm_digtable.cur_igvalue) { + dm_digtable.forbidden_igi = dm_digtable.cur_igvalue; + dm_digtable.large_fa_hit = 1; + } + if (dm_digtable.large_fa_hit >= 3) { + if ((dm_digtable.forbidden_igi + 1) > DM_DIG_MAX) + dm_digtable.rx_gain_range_min = DM_DIG_MAX; + else + dm_digtable.rx_gain_range_min = + (dm_digtable.forbidden_igi + 1); + dm_digtable.recover_cnt = 3600; /* 3600=2hr */ + } + } else { + /* Recovery mechanism for IGI lower bound */ + if (dm_digtable.recover_cnt != 0) { + dm_digtable.recover_cnt--; + } else { + if (dm_digtable.large_fa_hit == 0) { + if ((dm_digtable.forbidden_igi - 1) < + DM_DIG_FA_LOWER) { + dm_digtable.forbidden_igi = + DM_DIG_FA_LOWER; + dm_digtable.rx_gain_range_min = + DM_DIG_FA_LOWER; + + } else { + dm_digtable.forbidden_igi--; + dm_digtable.rx_gain_range_min = + (dm_digtable.forbidden_igi + 1); + } + } else if (dm_digtable.large_fa_hit == 3) { + dm_digtable.large_fa_hit = 0; + } + } + } + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", + dm_digtable.large_fa_hit, dm_digtable.forbidden_igi)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", + dm_digtable.recover_cnt, dm_digtable.rx_gain_range_min)); + + if (value_igi > DM_DIG_MAX) + value_igi = DM_DIG_MAX; + else if (value_igi < dm_digtable.rx_gain_range_min) + value_igi = dm_digtable.rx_gain_range_min; + dm_digtable.cur_igvalue = value_igi; + rtl92d_dm_write_dig(hw); + if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) + rtl92d_dm_cck_packet_detection_thresh(hw); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("<<==\n")); +} + +static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dynamic_txpower_enable = true; + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb; + + if ((!rtlpriv->dm.dynamic_txpower_enable) + || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("Not connected to any\n")); + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undecorated_smoothed_pwdb = + rtlpriv->dm.UNDEC_SM_PWDB; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("IBSS Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.UNDEC_SM_PWDB; + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + if (rtlhal->current_bandtype == BAND_ON_5G) { + if (undecorated_smoothed_pwdb >= 0x33) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL2; + RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, + ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n")); + } else if ((undecorated_smoothed_pwdb < 0x33) + && (undecorated_smoothed_pwdb >= 0x2b)) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, + ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } else if (undecorated_smoothed_pwdb < 0x2b) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_NORMAL; + RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, + ("5G:TxHighPwrLevel_Normal\n")); + } + } else { + if (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL2; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + } else + if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) + && (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = + TXHIGHPWRLEVEL_NORMAL; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_NORMAL\n")); + } + } + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel)); + rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); + } + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} + +static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* AP & ADHOC & MESH will return tmp */ + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + return; + /* Indicate Rx signal strength to FW. */ + if (rtlpriv->dm.useramask) { + u32 temp = rtlpriv->dm.undecorated_smoothed_pwdb; + + temp <<= 16; + temp |= 0x100; + /* fw v12 cmdid 5:use max macid ,for nic , + * default macid is 0 ,max macid is 1 */ + rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp)); + } else { + rtl_write_byte(rtlpriv, 0x4fe, + (u8) rtlpriv->dm.undecorated_smoothed_pwdb); + } +} + +void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; +} + +static void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt; + u64 cur_rxok_cnt; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.current_turbo_edca = false; + goto exit; + } + + /* Enable BEQ TxOP limit configuration in wireless G-mode. */ + /* To check whether we shall force turn on TXOP configuration. */ + if ((!rtlpriv->dm.disable_framebursting) && + (rtlpriv->sec.pairwise_enc_algorithm == WEP40_ENCRYPTION || + rtlpriv->sec.pairwise_enc_algorithm == WEP104_ENCRYPTION || + rtlpriv->sec.pairwise_enc_algorithm == TKIP_ENCRYPTION)) { + /* Force TxOP limit to 0x005e for UL. */ + if (!(edca_be_ul & 0xffff0000)) + edca_be_ul |= 0x005e0000; + /* Force TxOP limit to 0x005e for DL. */ + if (!(edca_be_dl & 0xffff0000)) + edca_be_dl |= 0x005e0000; + } + + if ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.is_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.is_cur_rdlstate = false; + } + } + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *) (&tmp)); + rtlpriv->dm.current_turbo_edca = false; + } + } + +exit: + rtlpriv->dm.is_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 index_mapping[RX_INDEX_MAPPING_NUM] = { + 0x0f, 0x0f, 0x0d, 0x0c, 0x0b, + 0x0a, 0x09, 0x08, 0x07, 0x06, + 0x05, 0x04, 0x04, 0x03, 0x02 + }; + int i; + u32 u4tmp; + + u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter - + rtlpriv->dm.thermalvalue_rxgain)]) << 12; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("===> Rx Gain %x\n", u4tmp)); + for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++) + rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK, + (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp); +} + +static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg, + u8 *cck_index_old) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + unsigned long flag = 0; + long temp_cck; + + /* Query CCK default setting From 0xa24 */ + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, + BMASKDWORD) & BMASKCCK; + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.cck_inch14) { + if (!memcmp((void *)&temp_cck, + (void *)&cckswing_table_ch14[i][2], 4)) { + *cck_index_old = (u8) i; + RT_TRACE(rtlpriv, + COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, + temp_cck, *cck_index_old, + rtlpriv->dm.cck_inch14)); + break; + } + } else { + if (!memcmp((void *) &temp_cck, + &cckswing_table_ch1ch13[i][2], 4)) { + *cck_index_old = (u8) i; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index = 0x%x, ch14 %d\n", + RCCK0_TXFILTER2, + temp_cck, *cck_index_old, + rtlpriv->dm.cck_inch14)); + break; + } + } + } + *temp_cckg = temp_cck; +} + +static void rtl92d_bandtype_5G(struct rtl_hal *rtlhal, u8 *ofdm_index, + bool *internal_pa, u8 thermalvalue, u8 delta, + u8 rf, struct rtl_efuse *rtlefuse, + struct rtl_priv *rtlpriv, struct rtl_phy *rtlphy, + u8 index_mapping[5][INDEX_MAPPING_NUM], + u8 index_mapping_pa[8][INDEX_MAPPING_NUM]) +{ + int i; + u8 index; + u8 offset = 0; + + for (i = 0; i < rf; i++) { + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 1) /* MAC 1 5G */ + *internal_pa = rtlefuse->internal_pa_5g[1]; + else + *internal_pa = rtlefuse->internal_pa_5g[i]; + if (*internal_pa) { + if (rtlhal->interfaceindex == 1 || i == rf) + offset = 4; + else + offset = 0; + if (rtlphy->current_channel >= 100 && + rtlphy->current_channel <= 165) + offset += 2; + } else { + if (rtlhal->interfaceindex == 1 || i == rf) + offset = 2; + else + offset = 0; + } + if (thermalvalue > rtlefuse->eeprom_thermalmeter) + offset++; + if (*internal_pa) { + if (delta > INDEX_MAPPING_NUM - 1) + index = index_mapping_pa[offset] + [INDEX_MAPPING_NUM - 1]; + else + index = + index_mapping_pa[offset][delta]; + } else { + if (delta > INDEX_MAPPING_NUM - 1) + index = + index_mapping[offset][INDEX_MAPPING_NUM - 1]; + else + index = index_mapping[offset][delta]; + } + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + if (*internal_pa && thermalvalue > 0x12) { + ofdm_index[i] = rtlpriv->dm.ofdm_index[i] - + ((delta / 2) * 3 + (delta % 2)); + } else { + ofdm_index[i] -= index; + } + } else { + ofdm_index[i] += index; + } + } +} + +static void rtl92d_dm_txpower_tracking_callback_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 thermalvalue, delta, delta_lck, delta_iqk, delta_rxgain; + u8 offset, thermalvalue_avg_count = 0; + u32 thermalvalue_avg = 0; + bool internal_pa = false; + long ele_a = 0, ele_d, temp_cck, val_x, value32; + long val_y, ele_c = 0; + u8 ofdm_index[2]; + u8 cck_index = 0; + u8 ofdm_index_old[2]; + u8 cck_index_old = 0; + u8 index; + int i; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + u8 ofdm_min_index = 6, ofdm_min_index_internal_pa = 3, rf; + u8 indexforchannel = + rtl92d_get_rightchnlplace_for_iqk(rtlphy->current_channel); + u8 index_mapping[5][INDEX_MAPPING_NUM] = { + /* 5G, path A/MAC 0, decrease power */ + {0, 1, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18}, + /* 5G, path A/MAC 0, increase power */ + {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18}, + /* 5G, path B/MAC 1, decrease power */ + {0, 2, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18}, + /* 5G, path B/MAC 1, increase power */ + {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18}, + /* 2.4G, for decreas power */ + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10}, + }; + u8 index_mapping_internal_pa[8][INDEX_MAPPING_NUM] = { + /* 5G, path A/MAC 0, ch36-64, decrease power */ + {0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16}, + /* 5G, path A/MAC 0, ch36-64, increase power */ + {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18}, + /* 5G, path A/MAC 0, ch100-165, decrease power */ + {0, 1, 2, 3, 5, 6, 8, 10, 11, 13, 14, 15, 15}, + /* 5G, path A/MAC 0, ch100-165, increase power */ + {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18}, + /* 5G, path B/MAC 1, ch36-64, decrease power */ + {0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16}, + /* 5G, path B/MAC 1, ch36-64, increase power */ + {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18}, + /* 5G, path B/MAC 1, ch100-165, decrease power */ + {0, 1, 2, 3, 5, 6, 8, 9, 10, 12, 13, 14, 14}, + /* 5G, path B/MAC 1, ch100-165, increase power */ + {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18}, + }; + + rtlpriv->dm.txpower_trackinginit = true; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("\n")); + thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x\n", thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); + rtl92d_phy_ap_calibrate(hw, (thermalvalue - + rtlefuse->eeprom_thermalmeter)); + if (is2t) + rf = 2; + else + rf = 1; + if (thermalvalue) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD) & BMASKOFDM_D; + for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { + if (ele_d == (ofdmswing_table[i] & BMASKOFDM_D)) { + ofdm_index_old[0] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Initial pathA ele_d reg0x%x = 0x%lx," + " ofdm_index=0x%x\n", + ROFDM0_XATxIQIMBALANCE, + ele_d, ofdm_index_old[0])); + break; + } + } + if (is2t) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, + BMASKDWORD) & BMASKOFDM_D; + for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { + if (ele_d == + (ofdmswing_table[i] & BMASKOFDM_D)) { + ofdm_index_old[1] = (u8) i; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial pathB ele_d reg " + "0x%x = 0x%lx, ofdm_index " + "= 0x%x\n", + ROFDM0_XBTxIQIMBALANCE, ele_d, + ofdm_index_old[1])); + break; + } + } + } + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + rtl92d_bandtype_2_4G(hw, &temp_cck, &cck_index_old); + } else { + temp_cck = 0x090e1317; + cck_index_old = 12; + } + + if (!rtlpriv->dm.thermalvalue) { + rtlpriv->dm.thermalvalue = + rtlefuse->eeprom_thermalmeter; + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtlpriv->dm.thermalvalue_rxgain = + rtlefuse->eeprom_thermalmeter; + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + } + if (rtlhal->reloadtxpowerindex) { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("reload ofdm index for band switch\n")); + } + rtlpriv->dm.thermalvalue_avg + [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue; + rtlpriv->dm.thermalvalue_avg_index++; + if (rtlpriv->dm.thermalvalue_avg_index == AVG_THERMAL_NUM) + rtlpriv->dm.thermalvalue_avg_index = 0; + for (i = 0; i < AVG_THERMAL_NUM; i++) { + if (rtlpriv->dm.thermalvalue_avg[i]) { + thermalvalue_avg += + rtlpriv->dm.thermalvalue_avg[i]; + thermalvalue_avg_count++; + } + } + if (thermalvalue_avg_count) + thermalvalue = (u8) (thermalvalue_avg / + thermalvalue_avg_count); + if (rtlhal->reloadtxpowerindex) { + delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? + (thermalvalue - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermalvalue); + rtlhal->reloadtxpowerindex = false; + rtlpriv->dm.done_txpower = false; + } else if (rtlpriv->dm.done_txpower) { + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + } else { + delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? + (thermalvalue - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermalvalue); + } + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + delta_rxgain = + (thermalvalue > rtlpriv->dm.thermalvalue_rxgain) ? + (thermalvalue - rtlpriv->dm.thermalvalue_rxgain) : + (rtlpriv->dm.thermalvalue_rxgain - thermalvalue); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x" + " eeprom_thermalmeter 0x%x delta 0x%x " + "delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk)); + if ((delta_lck > rtlefuse->delta_lck) && + (rtlefuse->delta_lck != 0)) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl92d_phy_lc_calibrate(hw); + } + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + rtlpriv->dm.done_txpower = true; + delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? + (thermalvalue - rtlefuse->eeprom_thermalmeter) : + (rtlefuse->eeprom_thermalmeter - thermalvalue); + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + offset = 4; + if (delta > INDEX_MAPPING_NUM - 1) + index = index_mapping[offset] + [INDEX_MAPPING_NUM - 1]; + else + index = index_mapping[offset][delta]; + if (thermalvalue > rtlpriv->dm.thermalvalue) { + for (i = 0; i < rf; i++) + ofdm_index[i] -= delta; + cck_index -= delta; + } else { + for (i = 0; i < rf; i++) + ofdm_index[i] += index; + cck_index += index; + } + } else if (rtlhal->current_bandtype == BAND_ON_5G) { + rtl92d_bandtype_5G(rtlhal, ofdm_index, + &internal_pa, thermalvalue, + delta, rf, rtlefuse, rtlpriv, + rtlphy, index_mapping, + index_mapping_internal_pa); + } + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x, OFDM_B_index" + " = 0x%x,cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x,cck_index = " + "0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index)); + } + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1) + ofdm_index[i] = OFDM_TABLE_SIZE_92D - 1; + else if (ofdm_index[i] < ofdm_min_index) + ofdm_index[i] = ofdm_min_index; + } + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (cck_index > CCK_TABLE_SIZE - 1) { + cck_index = CCK_TABLE_SIZE - 1; + } else if (internal_pa || + rtlhal->current_bandtype == + BAND_ON_2_4G) { + if (ofdm_index[i] < + ofdm_min_index_internal_pa) + ofdm_index[i] = + ofdm_min_index_internal_pa; + } else if (cck_index < 0) { + cck_index = 0; + } + } + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x, OFDM_B_index " + "= 0x%x, cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x,cck_index = " + "0x%x\n", + ofdm_index[0], cck_index)); + } + ele_d = (ofdmswing_table[(u8) ofdm_index[0]] & + 0xFFC00000) >> 22; + val_x = rtlphy->iqk_matrix_regsetting + [indexforchannel].value[0][0]; + val_y = rtlphy->iqk_matrix_regsetting + [indexforchannel].value[0][1]; + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = + ((val_x * ele_d) >> 8) & 0x000003FF; + + /* new element C = element D x Y */ + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; + + /* wirte new elements A, C, D to regC80 and + * regC94, element B is always 0 */ + value32 = (ele_d << 22) | ((ele_c & 0x3F) << + 16) | ele_a; + rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS, + value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), + value32); + + } else { + rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD, + ofdmswing_table + [(u8)ofdm_index[0]]); + rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS, + 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(24), 0x00); + } + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("TxPwrTracking for interface %d path A: X =" + " 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = " + "0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = " + "0x%lx\n", rtlhal->interfaceindex, + val_x, val_y, ele_a, ele_c, ele_d, + val_x, val_y)); + + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* Adjust CCK according to IQK result */ + if (!rtlpriv->dm.cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch1ch13 + [(u8)cck_index][0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch1ch13 + [(u8)cck_index][1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch1ch13 + [(u8)cck_index][2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch1ch13 + [(u8)cck_index][3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch1ch13 + [(u8)cck_index][4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch1ch13 + [(u8)cck_index][5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch1ch13 + [(u8)cck_index][6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch1ch13 + [(u8)cck_index][7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch14 + [(u8)cck_index][0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch14 + [(u8)cck_index][1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch14 + [(u8)cck_index][2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch14 + [(u8)cck_index][3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch14 + [(u8)cck_index][4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch14 + [(u8)cck_index][5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch14 + [(u8)cck_index][6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch14 + [(u8)cck_index][7]); + } + } + if (is2t) { + ele_d = (ofdmswing_table[(u8) ofdm_index[1]] & + 0xFFC00000) >> 22; + val_x = rtlphy->iqk_matrix_regsetting + [indexforchannel].value[0][4]; + val_y = rtlphy->iqk_matrix_regsetting + [indexforchannel].value[0][5]; + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + /* consider minus */ + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & + 0x000003FF; + /* new element C = element D x Y */ + if ((val_y & 0x00000200) != 0) + val_y = + val_y | 0xFFFFFC00; + ele_c = + ((val_y * + ele_d) >> 8) & 0x00003FF; + /* write new elements A, C, D to regC88 + * and regC9C, element B is always 0 + */ + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | + ele_a; + rtl_set_bbreg(hw, + ROFDM0_XBTxIQIMBALANCE, + BMASKDWORD, value32); + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTxAFE, + BMASKH4BITS, value32); + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(28), value32); + } else { + rtl_set_bbreg(hw, + ROFDM0_XBTxIQIMBALANCE, + BMASKDWORD, + ofdmswing_table + [(u8) ofdm_index[1]]); + rtl_set_bbreg(hw, ROFDM0_XDTxAFE, + BMASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(28), 0x00); + } + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("TxPwrTracking path B: X = 0x%lx, " + "Y = 0x%lx ele_A = 0x%lx ele_C = 0x" + "%lx ele_D = 0x%lx 0xeb4 = 0x%lx " + "0xebc = 0x%lx\n", + val_x, val_y, ele_a, ele_c, + ele_d, val_x, val_y)); + } + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = " + "0x%x RF 0x24 = 0x%x\n", + rtl_get_bbreg(hw, 0xc80, BMASKDWORD), + rtl_get_bbreg(hw, 0xc94, BMASKDWORD), + rtl_get_rfreg(hw, RF90_PATH_A, 0x24, + BRFREGOFFSETMASK))); + } + if ((delta_iqk > rtlefuse->delta_iqk) && + (rtlefuse->delta_iqk != 0)) { + rtl92d_phy_reset_iqk_result(hw); + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtl92d_phy_iq_calibrate(hw); + } + if (delta_rxgain > 0 && rtlhal->current_bandtype == BAND_ON_5G + && thermalvalue <= rtlefuse->eeprom_thermalmeter) { + rtlpriv->dm.thermalvalue_rxgain = thermalvalue; + rtl92d_dm_rxgain_tracking_thermalmeter(hw); + } + if (rtlpriv->dm.txpower_track_control) + rtlpriv->dm.thermalvalue = thermalvalue; + } + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); +} + +static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpower_trackinginit = false; + rtlpriv->dm.txpower_track_control = true; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking)); +} + +void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + static u8 tm_trigger; + + if (!rtlpriv->dm.txpower_tracking) + return; + + if (!tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | + BIT(16), 0x03); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Trigger 92S Thermal Meter!!\n")); + tm_trigger = 1; + return; + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Schedule TxPowerTracking direct call!!\n")); + rtl92d_dm_txpower_tracking_callback_thermalmeter(hw); + tm_trigger = 0; + } +} + +void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *ra = &(rtlpriv->ra); + + ra->ratr_state = DM_RATR_STA_INIT; + ra->pre_ratr_state = DM_RATR_STA_INIT; + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.useramask = true; + else + rtlpriv->dm.useramask = false; +} + +void rtl92d_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl92d_dm_diginit(hw); + rtl92d_dm_init_dynamic_txpower(hw); + rtl92d_dm_init_edca_turbo(hw); + rtl92d_dm_init_rate_adaptive_mask(hw); + rtl92d_dm_initialize_txpower_tracking(hw); +} + +void rtl92d_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool fw_current_inpsmode = false; + bool fwps_awake = true; + + /* 1. RF is OFF. (No need to do DM.) + * 2. Fw is under power saving mode for FwLPS. + * (Prevent from SW/FW I/O racing.) + * 3. IPS workitem is scheduled. (Prevent from IPS sequence + * to be swapped with DM. + * 4. RFChangeInProgress is TRUE. + * (Prevent from broken by IPS/HW/SW Rf off.) */ + + if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) && + fwps_awake) && (!ppsc->rfchange_inprogress)) { + rtl92d_dm_pwdb_monitor(hw); + rtl92d_dm_false_alarm_counter_statistics(hw); + rtl92d_dm_find_minimum_rssi(hw); + rtl92d_dm_dig(hw); + /* rtl92d_dm_dynamic_bb_powersaving(hw); */ + rtl92d_dm_dynamic_txpower(hw); + /* rtl92d_dm_check_txpower_tracking_thermal_meter(hw); */ + /* rtl92d_dm_refresh_rate_adaptive_mask(hw); */ + /* rtl92d_dm_interrupt_migration(hw); */ + rtl92d_dm_check_edca_turbo(hw); + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h new file mode 100644 index 00000000000..b3a42ff8145 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h @@ -0,0 +1,212 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_DM_H__ +#define __RTL92C_DM_H__ + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define OFDM_TABLE_SIZE_92D 43 +#define CCK_TABLE_LENGTH 33 + +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX 0x3e +#define DM_DIG_MIN 0x1c + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x100 +#define DM_DIG_FA_TH1 0x400 +#define DM_DIG_FA_TH2 0x600 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define RXPATHSELECTION_SS_TH_lOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVAL 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define INDEX_MAPPING_NUM 13 + +struct ps_t { + u8 pre_ccastate; + u8 cur_ccasate; + + u8 pre_rfstate; + u8 cur_rfstate; + + long rssi_val_min; +}; + +struct dig_t { + u8 dig_enable_flag; + u8 dig_ext_port_stage; + + u32 rssi_lowthresh; + u32 rssi_highthresh; + + u32 fa_lowthresh; + u32 fa_highthresh; + + u8 cursta_connectctate; + u8 presta_connectstate; + u8 curmultista_connectstate; + + u8 pre_igvalue; + u8 cur_igvalue; + + char backoff_val; + char backoff_val_range_max; + char backoff_val_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 min_undecorated_pwdb_for_dm; + long last_min_undecorated_pwdb_for_dm; + + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + + u8 pre_cck_fa_state; + u8 cur_cck_fa_state; + + u8 pre_ccastate; + u8 cur_ccasate; + + u8 large_fa_hit; + u8 forbidden_igi; + u32 recover_cnt; +}; + +struct swat { + u8 failure_cnt; + u8 try_flag; + u8 stop_trying; + long pre_rssi; + long trying_threshold; + u8 cur_antenna; + u8 pre_antenna; +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum tag_cck_packet_detection_threshold_type_definition { + CCK_PD_STAGE_LOWRSSI = 0, + CCK_PD_STAGE_HIGHRSSI = 1, + CCK_FA_STAGE_LOW = 2, + CCK_FA_STAGE_HIGH = 3, + CCK_PD_STAGE_MAX = 4, +}; + +enum dm_1r_cca { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +enum dm_dig_ext_port_alg { + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}; + +enum dm_dig_connect { + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MULTISTA_DISCONNECT = 3, + DIG_MULTISTA_CONNECT = 4, + DIG_CONNECT_MAX +}; + +extern struct dig_t dm_digtable; + +void rtl92d_dm_init(struct ieee80211_hw *hw); +void rtl92d_dm_watchdog(struct ieee80211_hw *hw); +void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92d_dm_write_dig(struct ieee80211_hw *hw); +void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw); +void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); + +#endif -- cgit v1.2.3-70-g09d2 From 985d4d3f6dced76f37c8c8d2528fcfe7773cc5f0 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:09:40 -0500 Subject: rtlwifi: rtl8192de: Merge firmware routines Merge routines fw.c and fw.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 790 ++++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/fw.h | 155 ++++++ 2 files changed, 945 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/fw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/fw.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c new file mode 100644 index 00000000000..82f060bdbc0 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -0,0 +1,790 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "fw.h" +#include "sw.h" + +static bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv) +{ + return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ? + true : false; +} + +static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + if (enable) { + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + /* Reserved for fw extension. + * 0x81[7] is used for mac0 status , + * so don't write this reg here + * rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/ + } +} + +static void _rtl92d_fw_block_write(struct ieee80211_hw *hw, + const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 blocksize = sizeof(u32); + u8 *bufferptr = (u8 *) buffer; + u32 *pu4BytePtr = (u32 *) buffer; + u32 i, offset, blockCount, remainSize; + + blockCount = size / blocksize; + remainSize = size % blocksize; + for (i = 0; i < blockCount; i++) { + offset = i * blocksize; + rtl_write_dword(rtlpriv, (FW_8192D_START_ADDRESS + offset), + *(pu4BytePtr + i)); + } + if (remainSize) { + offset = blockCount * blocksize; + bufferptr += offset; + for (i = 0; i < remainSize; i++) { + rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS + + offset + i), *(bufferptr + i)); + } + } +} + +static void _rtl92d_fw_page_write(struct ieee80211_hw *hw, + u32 page, const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value8; + u8 u8page = (u8) (page & 0x07); + + value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; + rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); + _rtl92d_fw_block_write(hw, buffer, size); +} + +static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ + u32 fwlen = *pfwlen; + u8 remain = (u8) (fwlen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + while (remain > 0) { + pfwbuf[fwlen] = 0; + fwlen++; + remain--; + } + *pfwlen = fwlen; +} + +static void _rtl92d_write_fw(struct ieee80211_hw *hw, + enum version_8192d version, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 *bufferPtr = (u8 *) buffer; + u32 pagenums, remainSize; + u32 page, offset; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) + _rtl92d_fill_dummy(bufferPtr, &size); + pagenums = size / FW_8192D_PAGE_SIZE; + remainSize = size % FW_8192D_PAGE_SIZE; + if (pagenums > 8) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Page numbers should not greater then 8\n")); + } + for (page = 0; page < pagenums; page++) { + offset = page * FW_8192D_PAGE_SIZE; + _rtl92d_fw_page_write(hw, page, (bufferPtr + offset), + FW_8192D_PAGE_SIZE); + } + if (remainSize) { + offset = pagenums * FW_8192D_PAGE_SIZE; + page = pagenums; + _rtl92d_fw_page_write(hw, page, (bufferPtr + offset), + remainSize); + } +} + +static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_ChkSum_rpt))); + if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", + value32)); + return -EIO; + } + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + return 0; +} + +void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1b_tmp; + u8 delay = 100; + + /* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */ + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + while (u1b_tmp & BIT(2)) { + delay--; + if (delay == 0) + break; + udelay(50); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + } + RT_ASSERT((delay > 0), ("8051 reset failed!\n")); + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("=====> 8051 reset success (%d) .\n", delay)); +} + +static int _rtl92d_fw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 counter; + + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n")); + /* polling for FW ready */ + counter = 0; + do { + if (rtlhal->interfaceindex == 0) { + if (rtl_read_byte(rtlpriv, FW_MAC0_READY) & + MAC0_READY) { + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Polling FW ready success!! " + "REG_MCUFWDL: 0x%x .\n", + rtl_read_byte(rtlpriv, + FW_MAC0_READY))); + return 0; + } + udelay(5); + } else { + if (rtl_read_byte(rtlpriv, FW_MAC1_READY) & + MAC1_READY) { + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Polling FW ready success!! " + "REG_MCUFWDL: 0x%x .\n", + rtl_read_byte(rtlpriv, + FW_MAC1_READY))); + return 0; + } + udelay(5); + } + } while (counter++ < POLLING_READY_TIMEOUT_COUNT); + + if (rtlhal->interfaceindex == 0) { + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Polling FW ready fail!! MAC0 FW init not ready: " + "0x%x .\n", + rtl_read_byte(rtlpriv, FW_MAC0_READY))); + } else { + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Polling FW ready fail!! MAC1 FW init not ready: " + "0x%x .\n", + rtl_read_byte(rtlpriv, FW_MAC1_READY))); + } + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n", + rtl_read_dword(rtlpriv, REG_MCUFWDL))); + return -1; +} + +int rtl92d_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8192d version = rtlhal->version; + u8 value; + u32 count; + bool fw_downloaded = false, fwdl_in_process = false; + unsigned long flags; + + if (!rtlhal->pfirmware) + return 1; + fwsize = rtlhal->fwsize; + pfwheader = (u8 *) rtlhal->pfirmware; + pfwdata = (u8 *) rtlhal->pfirmware; + rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); + rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d)," + "FirmwareSubVersion(%d), Signature(%#x)\n", + rtlhal->fw_version, rtlhal->fw_subversion, + GET_FIRMWARE_HDR_SIGNATURE(pfwheader))); + if (IS_FW_HEADER_EXIST(pfwheader)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Shift 32 bytes for FW header!!\n")); + pfwdata = pfwdata + 32; + fwsize = fwsize - 32; + } + + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv); + if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5)) + fwdl_in_process = true; + else + fwdl_in_process = false; + if (fw_downloaded) { + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + goto exit; + } else if (fwdl_in_process) { + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + for (count = 0; count < 5000; count++) { + udelay(500); + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv); + if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5)) + fwdl_in_process = true; + else + fwdl_in_process = false; + spin_unlock_irqrestore(&globalmutex_for_fwdownload, + flags); + if (fw_downloaded) + goto exit; + else if (!fwdl_in_process) + break; + else + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Wait for another mac " + "download fw\n")); + } + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + value = rtl_read_byte(rtlpriv, 0x1f); + value |= BIT(5); + rtl_write_byte(rtlpriv, 0x1f, value); + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + } else { + value = rtl_read_byte(rtlpriv, 0x1f); + value |= BIT(5); + rtl_write_byte(rtlpriv, 0x1f, value); + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + } + + /* If 8051 is running in RAM code, driver should + * inform Fw to reset by itself, or it will cause + * download Fw fail.*/ + /* 8051 RAM code */ + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { + rtl92d_firmware_selfreset(hw); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + } + _rtl92d_enable_fw_download(hw, true); + _rtl92d_write_fw(hw, version, pfwdata, fwsize); + _rtl92d_enable_fw_download(hw, false); + spin_lock_irqsave(&globalmutex_for_fwdownload, flags); + err = _rtl92d_fw_free_to_go(hw); + /* download fw over,clear 0x1f[5] */ + value = rtl_read_byte(rtlpriv, 0x1f); + value &= (~BIT(5)); + rtl_write_byte(rtlpriv, 0x1f, value); + spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("fw is not ready to run!\n")); + goto exit; + } else { + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("fw is ready to run!\n")); + } +exit: + err = _rtl92d_fw_init(hw); + return err; +} + +static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + result = true; + return result; +} + +static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index = 0; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limmit = 100; + u8 boxcontent[4], boxextcontent[2]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Return as RF is off!!!\n")); + return; + } + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("H2C set in progress! Wait to set.." + "element_id(%d).\n", element_id)); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wait 100 us (%d times)...\n", + h2c_waitcounter)); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + while (!bwrite_sucess) { + wait_writeh2c_limmit--; + if (wait_writeh2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Write H2C fail because no trigger " + "for FW INT!\n")); + break; + } + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating too long for FW read " + "clear HMEBox(%d)!\n", boxnum)); + break; + } + udelay(10); + isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating for FW read clear HMEBox(%d)!!! " + "0x1BF = %2x\n", boxnum, u1b_tmp)); + } + if (!isfw_read) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write H2C register BOX[%d] fail!!!!! " + "Fw do not read.\n", boxnum)); + break; + } + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id)); + switch (cmd_len) { + case 1: + boxcontent[0] &= ~(BIT(7)); + memcpy(boxcontent + 1, cmdbuffer + buf_index, 1); + for (idx = 0; idx < 4; idx++) + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + break; + case 2: + boxcontent[0] &= ~(BIT(7)); + memcpy(boxcontent + 1, cmdbuffer + buf_index, 2); + for (idx = 0; idx < 4; idx++) + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + break; + case 3: + boxcontent[0] &= ~(BIT(7)); + memcpy(boxcontent + 1, cmdbuffer + buf_index, 3); + for (idx = 0; idx < 4; idx++) + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + break; + case 4: + boxcontent[0] |= (BIT(7)); + memcpy(boxextcontent, cmdbuffer + buf_index, 2); + memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2); + for (idx = 0; idx < 2; idx++) + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + for (idx = 0; idx < 4; idx++) + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + break; + case 5: + boxcontent[0] |= (BIT(7)); + memcpy(boxextcontent, cmdbuffer + buf_index, 2); + memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3); + for (idx = 0; idx < 2; idx++) + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + for (idx = 0; idx < 4; idx++) + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + bwrite_sucess = true; + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum)); + } + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); +} + +void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (rtlhal->fw_ready == false) { + RT_ASSERT(false, ("return H2C cmd because of Fw " + "download fail!!!\n")); + return; + } + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); + return; +} + +void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[3] = { 0 }; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); + SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, + ppsc->reg_max_lps_awakeintvl); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, 3); + rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); +} + +static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + u8 idx = 0; + unsigned long flags; + struct sk_buff *pskb; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + pskb = __skb_dequeue(&ring->queue); + if (pskb) + kfree_skb(pskb); + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + pdesc = &ring->desc[idx]; + /* discard output from call below */ + rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); + __skb_queue_tail(&ring->queue, skb); + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + return true; +} + +#define BEACON_PG 0 /*->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /*->5 */ +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + u32 totalpacketlen; + bool rtstatus; + u8 u1RsvdPageLoc[3] = { 0 }; + bool dlok = false; + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + /*--------------------------------------------------------- + (1) beacon + ---------------------------------------------------------*/ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + /*------------------------------------------------------- + (2) ps-poll + --------------------------------------------------------*/ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); + /*-------------------------------------------------------- + (3) null data + ---------------------------------------------------------*/ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); + /*--------------------------------------------------------- + (4) probe response + ----------------------------------------------------------*/ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1RsvdPageLoc, 3); + skb = dev_alloc_skb(totalpacketlen); + memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, + totalpacketlen); + rtstatus = _rtl92d_cmd_send_packet(hw, skb); + + if (rtstatus) + dlok = true; + if (dlok) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Set RSVD page location to Fw.\n")); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3); + rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, + sizeof(u1RsvdPageLoc), u1RsvdPageLoc); + } else + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Set RSVD page location to Fw FAIL!!!!!!.\n")); +} + +void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = {0}; + + SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h new file mode 100644 index 00000000000..0c4d489eaa4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h @@ -0,0 +1,155 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92D__FW__H__ +#define __RTL92D__FW__H__ + +#define FW_8192D_START_ADDRESS 0x1000 +#define FW_8192D_PAGE_SIZE 4096 +#define FW_8192D_POLLING_TIMEOUT_COUNT 1000 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x92C0 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x88C0 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D0 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D1 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D2 || \ + (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D3) + +/* Define a macro that takes an le32 word, converts it to host ordering, + * right shifts by a specified count, creates a mask of the specified + * bit count, and extracts that number of bits. + */ + +#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \ + ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ + BIT_LEN_MASK_32(__mask)) + +/* Firmware Header(8-byte alinment required) */ +/* --- LONG WORD 0 ---- */ +#define GET_FIRMWARE_HDR_SIGNATURE(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr, 0, 16) +#define GET_FIRMWARE_HDR_CATEGORY(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr, 16, 8) +#define GET_FIRMWARE_HDR_FUNCTION(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr, 24, 8) +#define GET_FIRMWARE_HDR_VERSION(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 4, 0, 16) +#define GET_FIRMWARE_HDR_SUB_VER(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 4, 16, 8) +#define GET_FIRMWARE_HDR_RSVD1(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 4, 24, 8) + +/* --- LONG WORD 1 ---- */ +#define GET_FIRMWARE_HDR_MONTH(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 8, 0, 8) +#define GET_FIRMWARE_HDR_DATE(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 8, 8, 8) +#define GET_FIRMWARE_HDR_HOUR(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 8, 16, 8) +#define GET_FIRMWARE_HDR_MINUTE(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 8, 24, 8) +#define GET_FIRMWARE_HDR_ROMCODE_SIZE(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 12, 0, 16) +#define GET_FIRMWARE_HDR_RSVD2(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 12, 16, 16) + +/* --- LONG WORD 2 ---- */ +#define GET_FIRMWARE_HDR_SVN_IDX(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 16, 0, 32) +#define GET_FIRMWARE_HDR_RSVD3(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 20, 0, 32) + +/* --- LONG WORD 3 ---- */ +#define GET_FIRMWARE_HDR_RSVD4(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 24, 0, 32) +#define GET_FIRMWARE_HDR_RSVD5(__fwhdr) \ + SHIFT_AND_MASK_LE(__fwhdr + 28, 0, 32) + +#define pagenum_128(_len) \ + (u32)(((_len) >> 7) + ((_len) & 0x7F ? 1 : 0)) + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val) +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val) + +struct rtl92d_firmware_header { + u16 signature; + u8 category; + u8 function; + u16 version; + u8 subversion; + u8 rsvd1; + + u8 month; + u8 date; + u8 hour; + u8 minute; + u16 ramcodeSize; + u16 rsvd2; + + u32 svnindex; + u32 rsvd3; + + u32 rsvd4; + u32 rsvd5; +}; + +enum rtl8192d_h2c_cmd { + H2C_AP_OFFLOAD = 0, + H2C_SETPWRMODE = 1, + H2C_JOINBSSRPT = 2, + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + H2C_MAC_MODE_SEL = 9, + H2C_PWRM = 15, + MAX_H2CCMD +}; + +int rtl92d_download_fw(struct ieee80211_hw *hw); +void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl92d_firmware_selfreset(struct ieee80211_hw *hw); +void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); + +#endif -- cgit v1.2.3-70-g09d2 From 3affdf42373e9f2913238c1881610a258b044648 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:09:55 -0500 Subject: rtlwifi: rtl8192de: Merge hardware routines Merge routines hw.c and hw.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2325 +++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/hw.h | 66 + 2 files changed, 2391 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/hw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/hw.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c new file mode 100644 index 00000000000..eedfb38bec8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -0,0 +1,2325 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" +#include "led.h" +#include "sw.h" +#include "hw.h" + +u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 value; + + rtl_write_word(rtlpriv, REG_DBI_CTRL, (offset & 0xFFC)); + rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(1) | direct); + udelay(10); + value = rtl_read_dword(rtlpriv, REG_DBI_RDATA); + return value; +} + +void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, + u16 offset, u32 value, u8 direct) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_DBI_CTRL, ((offset & 0xFFC) | 0xF000)); + rtl_write_dword(rtlpriv, REG_DBI_WDATA, value); + rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(0) | direct); +} + +static void _rtl92de_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl92de_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92de_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp1byte; + + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl92de_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl92de_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl92de_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *) (val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfState; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *) (&rfState)); + if (rfState == ERFOFF) { + *((bool *) (val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *) (val)) = false; + else + *((bool *) (val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *) (val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + *((u64 *) (val)) = tsf; + break; + } + case HW_VAR_INT_MIGRATION: + *((bool *)(val)) = rtlpriv->dm.interrupt_migration; + break; + case HW_VAR_INT_AC: + *((bool *)(val)) = rtlpriv->dm.disable_tx_int; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } +} + +void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 idx; + + switch (variable) { + case HW_VAR_ETHER_ADDR: + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + case HW_VAR_BASIC_RATE: { + u16 rate_cfg = ((u16 *) val)[0]; + u8 rate_index = 0; + + rate_cfg = rate_cfg & 0x15f; + if (mac->vendor == PEER_CISCO && + ((rate_cfg & 0x150) == 0)) + rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (rate_cfg >> 8) & 0xff); + while (rate_cfg > 0x1) { + rate_cfg = (rate_cfg >> 1); + rate_index++; + } + if (rtlhal->fw_version > 0xe) + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID: + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, + *((u16 *) val)); + break; + case HW_VAR_SLOT_TIME: { + u8 e_aci; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("HW_VAR_SLOT_TIME %x\n", val[0])); + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + for (e_aci = 0; e_aci < AC_MAX; e_aci++) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *) (&e_aci)); + break; + } + case HW_VAR_ACK_PREAMBLE: { + u8 reg_tmp; + u8 short_preamble = (bool) (*(u8 *) val); + + reg_tmp = (mac->cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE: { + u8 min_spacing_to_set; + u8 sec_min_space; + + min_spacing_to_set = *((u8 *) val); + if (min_spacing_to_set <= 7) { + sec_min_space = 0; + if (min_spacing_to_set < sec_min_space) + min_spacing_to_set = sec_min_space; + mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) | + min_spacing_to_set); + *val = min_spacing_to_set; + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg)); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY: { + u8 density_to_set; + + density_to_set = *((u8 *) val); + mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; + mac->min_space_cfg |= (density_to_set << 3); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg)); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + break; + } + case HW_VAR_AMPDU_FACTOR: { + u8 factor_toset; + u32 regtoSet; + u8 *ptmp_byte = NULL; + u8 index; + + if (rtlhal->macphymode == DUALMAC_DUALPHY) + regtoSet = 0xb9726641; + else if (rtlhal->macphymode == DUALMAC_SINGLEPHY) + regtoSet = 0x66626641; + else + regtoSet = 0xb972a841; + factor_toset = *((u8 *) val); + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + for (index = 0; index < 4; index++) { + ptmp_byte = (u8 *) (®toSet) + index; + if ((*ptmp_byte & 0xf0) > + (factor_toset << 4)) + *ptmp_byte = (*ptmp_byte & 0x0f) + | (factor_toset << 4); + if ((*ptmp_byte & 0x0f) > factor_toset) + *ptmp_byte = (*ptmp_byte & 0xf0) + | (factor_toset); + } + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoSet); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset)); + } + break; + } + case HW_VAR_AC_PARAM: { + u8 e_aci = *((u8 *) val); + rtl92d_dm_init_edca_turbo(hw); + if (rtlpci->acm_method != eAcmWay2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, + (u8 *) (&e_aci)); + break; + } + case HW_VAR_ACM_CTRL: { + u8 e_aci = *((u8 *) val); + union aci_aifsn *p_aci_aifsn = + (union aci_aifsn *)(&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQEN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQEN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQEN; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("HW_VAR_ACM_CTRL acm set " + "failed: eACI is %d\n", acm)); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQEN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQEN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQEN); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } + RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, + ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " + "Write 0x%X\n", acm_ctrl)); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR: + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); + rtlpci->receive_config = ((u32 *) (val))[0]; + break; + case HW_VAR_RETRY_LIMIT: { + u8 retry_limit = ((u8 *) (val))[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *) val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *((u8 *) val); + break; + case HW_VAR_IO_CMD: + rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); + break; + case HW_VAR_SET_RPWM: + rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (u8 *) (val)); + break; + case HW_VAR_H2C_FW_PWRMODE: + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *) val); + break; + case HW_VAR_H2C_FW_JOINBSSRPT: { + u8 mstatus = (*(u8 *) val); + u8 tmp_regcr, tmp_reg422; + bool recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AID, NULL); + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr | BIT(0))); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0); + tmp_reg422 = rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + rtl92d_set_fw_rsvdpagepkt(hw, 0); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); + if (recover) + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422); + rtl_write_byte(rtlpriv, REG_CR + 1, + (tmp_regcr & ~(BIT(0)))); + } + rtl92d_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); + break; + } + case HW_VAR_AID: { + u16 u2btmp; + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | + mac->assoc_id)); + break; + } + case HW_VAR_CORRECT_TSF: { + u8 btype_ibss = ((u8 *) (val))[0]; + + if (btype_ibss == true) + _rtl92de_stop_tx_beacon(hw); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3)); + rtl_write_dword(rtlpriv, REG_TSFTR, + (u32) (mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32) ((mac->tsf >> 32) & 0xffffffff)); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0); + if (btype_ibss == true) + _rtl92de_resume_tx_beacon(hw); + + break; + } + case HW_VAR_INT_MIGRATION: { + bool int_migration = *(bool *) (val); + + if (int_migration) { + /* Set interrrupt migration timer and + * corresponging Tx/Rx counter. + * timer 25ns*0xfa0=100us for 0xf packets. + * 0x306:Rx, 0x307:Tx */ + rtl_write_dword(rtlpriv, REG_INT_MIG, 0xfe000fa0); + rtlpriv->dm.interrupt_migration = int_migration; + } else { + /* Reset all interrupt migration settings. */ + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + rtlpriv->dm.interrupt_migration = int_migration; + } + break; + } + case HW_VAR_INT_AC: { + bool disable_ac_int = *((bool *) val); + + /* Disable four ACs interrupts. */ + if (disable_ac_int) { + /* Disable VO, VI, BE and BK four AC interrupts + * to gain more efficient CPU utilization. + * When extremely highly Rx OK occurs, + * we will disable Tx interrupts. + */ + rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, + RT_AC_INT_MASKS); + rtlpriv->dm.disable_tx_int = disable_ac_int; + /* Enable four ACs interrupts. */ + } else { + rtlpriv->cfg->ops->update_interrupt_mask(hw, + RT_AC_INT_MASKS, 0); + rtlpriv->dm.disable_tx_int = disable_ac_int; + } + break; + } + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } +} + +static bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + if (count > POLLING_LLT_THRESHOLD) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to polling write LLT done at " + "address %d!\n", address)); + status = false; + break; + } + } while (++count); + return status; +} + +static bool _rtl92de_llt_table_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned short i; + u8 txpktbuf_bndy; + u8 maxPage; + bool status; + u32 value32; /* High+low page number */ + u8 value8; /* normal page number */ + + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { + maxPage = 255; + txpktbuf_bndy = 246; + value8 = 0; + value32 = 0x80bf0d29; + } else if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { + maxPage = 127; + txpktbuf_bndy = 123; + value8 = 0; + value32 = 0x80750005; + } + + /* Set reserved page for each queue */ + /* 11. RQPN 0x200[31:0] = 0x80BD1C1C */ + /* load RQPN */ + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); + rtl_write_dword(rtlpriv, REG_RQPN, value32); + + /* 12. TXRKTBUG_PG_BNDY 0x114[31:0] = 0x27FF00F6 */ + /* TXRKTBUG_PG_BNDY */ + rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, + (rtl_read_word(rtlpriv, REG_TRXFF_BNDY + 2) << 16 | + txpktbuf_bndy)); + + /* 13. TDECTRL[15:8] 0x209[7:0] = 0xF6 */ + /* Beacon Head for TXDMA */ + rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + + /* 14. BCNQ_PGBNDY 0x424[7:0] = 0xF6 */ + /* BCNQ_PGBNDY */ + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + + /* 15. WMAC_LBK_BF_HD 0x45D[7:0] = 0xF6 */ + /* WMAC_LBK_BF_HD */ + rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); + + /* Set Tx/Rx page size (Tx must be 128 Bytes, */ + /* Rx can be 64,128,256,512,1024 bytes) */ + /* 16. PBP [7:0] = 0x11 */ + /* TRX page size */ + rtl_write_byte(rtlpriv, REG_PBP, 0x11); + + /* 17. DRV_INFO_SZ = 0x04 */ + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + + /* 18. LLT_table_init(Adapter); */ + for (i = 0; i < (txpktbuf_bndy - 1); i++) { + status = _rtl92de_llt_write(hw, i, i + 1); + if (true != status) + return status; + } + + /* end of list */ + status = _rtl92de_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + if (true != status) + return status; + + /* Make the other pages as ring buffer */ + /* This ring buffer is used as beacon buffer if we */ + /* config this MAC as two MAC transfer. */ + /* Otherwise used as local loopback buffer. */ + for (i = txpktbuf_bndy; i < maxPage; i++) { + status = _rtl92de_llt_write(hw, i, (i + 1)); + if (true != status) + return status; + } + + /* Let last entry point to the start entry of ring buffer */ + status = _rtl92de_llt_write(hw, maxPage, txpktbuf_bndy); + if (true != status) + return status; + + return true; +} + +static void _rtl92de_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); + + if (rtlpci->up_first_time) + return; + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl92ce_sw_led_on(hw, pLed0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl92ce_sw_led_on(hw, pLed0); + else + rtl92ce_sw_led_off(hw, pLed0); +} + +static bool _rtl92de_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + unsigned char bytetmp; + unsigned short wordtmp; + u16 retry; + + rtl92d_phy_set_poweron(hw); + /* Add for resume sequence of power domain according + * to power document V11. Chapter V.11.... */ + /* 0. RSV_CTRL 0x1C[7:0] = 0x00 */ + /* unlock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x05); + + /* 1. AFE_XTAL_CTRL [7:0] = 0x0F enable XTAL */ + /* 2. SPS0_CTRL 0x11[7:0] = 0x2b enable SPS into PWM mode */ + /* 3. delay (1ms) this is not necessary when initially power on */ + + /* C. Resume Sequence */ + /* a. SPS0_CTRL 0x11[7:0] = 0x2b */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + + /* b. AFE_XTAL_CTRL [7:0] = 0x0F */ + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); + + /* c. DRV runs power on init flow */ + + /* auto enable WLAN */ + /* 4. APS_FSMCO 0x04[8] = 1; wait till 0x04[8] = 0 */ + /* Power On Reset for MAC Block */ + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); + udelay(2); + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + udelay(2); + + /* 5. Wait while 0x04[8] == 0 goto 2, otherwise goto 1 */ + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + udelay(50); + retry = 0; + while ((bytetmp & BIT(0)) && retry < 1000) { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); + udelay(50); + } + + /* Enable Radio off, GPIO, and LED function */ + /* 6. APS_FSMCO 0x04[15:0] = 0x0012 when enable HWPDN */ + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012); + + /* release RF digital isolation */ + /* 7. SYS_ISO_CTRL 0x01[1] = 0x0; */ + /*Set REG_SYS_ISO_CTRL 0x1=0x82 to prevent wake# problem. */ + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); + udelay(2); + + /* make sure that BB reset OK. */ + /* rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); */ + + /* Disable REG_CR before enable it to assure reset */ + rtl_write_word(rtlpriv, REG_CR, 0x0); + + /* Release MAC IO register reset */ + rtl_write_word(rtlpriv, REG_CR, 0x2ff); + + /* clear stopping tx/rx dma */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0x0); + + /* rtl_write_word(rtlpriv,REG_CR+2, 0x2); */ + + /* System init */ + /* 18. LLT_table_init(Adapter); */ + if (_rtl92de_llt_table_init(hw) == false) + return false; + + /* Clear interrupt and enable interrupt */ + /* 19. HISR 0x124[31:0] = 0xffffffff; */ + /* HISRE 0x12C[7:0] = 0xFF */ + rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); + rtl_write_byte(rtlpriv, REG_HISRE, 0xff); + + /* 20. HIMR 0x120[31:0] |= [enable INT mask bit map]; */ + /* 21. HIMRE 0x128[7:0] = [enable INT mask bit map] */ + /* The IMR should be enabled later after all init sequence + * is finished. */ + + /* 22. PCIE configuration space configuration */ + /* 23. Ensure PCIe Device 0x80[15:0] = 0x0143 (ASPM+CLKREQ), */ + /* and PCIe gated clock function is enabled. */ + /* PCIE configuration space will be written after + * all init sequence.(Or by BIOS) */ + + rtl92d_phy_config_maccoexist_rfpage(hw); + + /* THe below section is not related to power document Vxx . */ + /* This is only useful for driver and OS setting. */ + /* -------------------Software Relative Setting---------------------- */ + wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); + wordtmp &= 0xf; + wordtmp |= 0xF771; + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + + /* Reported Tx status from HW for rate adaptive. */ + /* This should be realtive to power on step 14. But in document V11 */ + /* still not contain the description.!!! */ + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); + + /* Set Tx/Rx page size (Tx must be 128 Bytes, + * Rx can be 64,128,256,512,1024 bytes) */ + /* rtl_write_byte(rtlpriv,REG_PBP, 0x11); */ + + /* Set RCR register */ + rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); + /* rtl_write_byte(rtlpriv,REG_RX_DRVINFO_SZ, 4); */ + + /* Set TCR register */ + rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + + /* disable earlymode */ + rtl_write_byte(rtlpriv, 0x4d0, 0x0); + + /* Set TX/RX descriptor physical address(from OS API). */ + rtl_write_dword(rtlpriv, REG_BCNQ_DESA, + rtlpci->tx_ring[BEACON_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_MGQ_DESA, rtlpci->tx_ring[MGNT_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_VOQ_DESA, rtlpci->tx_ring[VO_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_VIQ_DESA, rtlpci->tx_ring[VI_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_BEQ_DESA, rtlpci->tx_ring[BE_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_BKQ_DESA, rtlpci->tx_ring[BK_QUEUE].dma); + rtl_write_dword(rtlpriv, REG_HQ_DESA, rtlpci->tx_ring[HIGH_QUEUE].dma); + /* Set RX Desc Address */ + rtl_write_dword(rtlpriv, REG_RX_DESA, + rtlpci->rx_ring[RX_MPDU_QUEUE].dma); + + /* if we want to support 64 bit DMA, we should set it here, + * but now we do not support 64 bit DMA*/ + + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x33); + + /* Reset interrupt migration setting when initialization */ + rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + + /* Reconsider when to do this operation after asking HWSD. */ + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); + do { + retry++; + bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); + } while ((retry < 200) && !(bytetmp & BIT(7))); + + /* After MACIO reset,we must refresh LED state. */ + _rtl92de_gen_refresh_led_state(hw); + + /* Reset H2C protection register */ + rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + + return true; +} + +static void _rtl92de_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 reg_bw_opmode = BW_OPMODE_20MHZ; + u32 reg_rrsr; + + reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr); + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); + rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); + rtl_write_word(rtlpriv, REG_RL, 0x0707); + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); + rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); + /* Aggregation threshold */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb9726641); + else if (rtlhal->macphymode == DUALMAC_SINGLEPHY) + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x66626641); + else + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a); + rtlpci->reg_bcn_ctrl_val = 0x1f; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); + /* For throughput */ + rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x6666); + /* ACKTO for IOT issue. */ + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); + /* Set Spec SIFS (used in NAV) */ + rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); + rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); + /* Set SIFS for CCK */ + rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); + /* Set SIFS for OFDM */ + rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); + /* Set Multicast Address. */ + rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); + switch (rtlpriv->phy.rf_type) { + case RF_1T2R: + case RF_1T1R: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3); + break; + case RF_2T2R: + case RF_2T2R_GREEN: + rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3); + break; + } +} + +static void _rtl92de_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + rtl_write_byte(rtlpriv, 0x34b, 0x93); + rtl_write_word(rtlpriv, 0x350, 0x870c); + rtl_write_byte(rtlpriv, 0x352, 0x1); + if (ppsc->support_backdoor) + rtl_write_byte(rtlpriv, 0x349, 0x1b); + else + rtl_write_byte(rtlpriv, 0x349, 0x03); + rtl_write_word(rtlpriv, 0x350, 0x2718); + rtl_write_byte(rtlpriv, 0x352, 0x1); +} + +void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm)); + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("not open hw encryption\n")); + return; + } + sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TXUSEDK; + sec_reg_value |= SCR_RXUSEDK; + } + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The SECR-value %x\n", sec_reg_value)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +int rtl92de_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool rtstatus = true; + u8 tmp_u1b, i; + int err; + unsigned long flags; + + rtlpci->being_init_adapter = true; + rtlpci->init_ready = false; + spin_lock_irqsave(&globalmutex_for_power_and_efuse, flags); + /* we should do iqk after disable/enable */ + rtl92d_phy_reset_iqk_result(hw); + /* rtlpriv->intf_ops->disable_aspm(hw); */ + rtstatus = _rtl92de_init_mac(hw); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + err = 1; + spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); + return err; + } + err = rtl92d_download_fw(hw); + spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Failed to download FW. Init HW " + "without FW..\n")); + err = 1; + rtlhal->fw_ready = false; + } else { + rtlhal->fw_ready = true; + } + rtlhal->last_hmeboxnum = 0; + rtlpriv->psc.fw_current_inpsmode = false; + + tmp_u1b = rtl_read_byte(rtlpriv, 0x605); + tmp_u1b = tmp_u1b | 0x30; + rtl_write_byte(rtlpriv, 0x605, tmp_u1b); + + if (rtlhal->earlymode_enable) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EarlyMode Enabled!!!\n")); + + tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0); + tmp_u1b = tmp_u1b | 0x1f; + rtl_write_byte(rtlpriv, 0x4d0, tmp_u1b); + + rtl_write_byte(rtlpriv, 0x4d3, 0x80); + + tmp_u1b = rtl_read_byte(rtlpriv, 0x605); + tmp_u1b = tmp_u1b | 0x40; + rtl_write_byte(rtlpriv, 0x605, tmp_u1b); + } + + if (mac->rdg_en) { + rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xff); + rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200); + rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05); + } + + rtl92d_phy_mac_config(hw); + /* because last function modify RCR, so we update + * rcr var here, or TP will unstable for receive_config + * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx + * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ + rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + + rtl92d_phy_bb_config(hw); + + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + /* set before initialize RF */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + + /* config RF */ + rtl92d_phy_rf_config(hw); + + /* After read predefined TXT, we must set BB/MAC/RF + * register as our requirement */ + /* After load BB,RF params,we need do more for 92D. */ + rtl92d_update_bbrf_configuration(hw); + /* set default value after initialize RF, */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, BRFREGOFFSETMASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, BRFREGOFFSETMASK); + + /*---- Set CCK and OFDM Block "ON"----*/ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + if (rtlhal->interfaceindex == 0) { + /* RFPGA0_ANALOGPARAMETER2: cck clock select, + * set to 20MHz by default */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | + BIT(11), 3); + } else { + /* Mac1 */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(11) | + BIT(10), 3); + } + + _rtl92de_hw_configure(hw); + + /* reset hw sec */ + rtl_cam_reset_all_entry(hw); + rtl92de_enable_hw_security_config(hw); + + /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */ + /* TX power index for different rate set. */ + rtl92d_phy_get_hw_reg_originalvalue(hw); + rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + + _rtl92de_enable_aspm_back_door(hw); + /* rtlpriv->intf_ops->enable_aspm(hw); */ + + rtl92d_dm_init(hw); + rtlpci->being_init_adapter = false; + + if (ppsc->rfpwr_state == ERFON) { + rtl92d_phy_lc_calibrate(hw); + /* 5G and 2.4G must wait sometime to let RF LO ready */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + u32 tmp_rega; + for (i = 0; i < 10000; i++) { + udelay(MAX_STALL_TIME); + + tmp_rega = rtl_get_rfreg(hw, + (enum radio_path)RF90_PATH_A, + 0x2a, BMASKDWORD); + + if (((tmp_rega & BIT(11)) == BIT(11))) + break; + } + } + } + rtlpci->init_ready = true; + return err; +} + +static enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum version_8192d version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (!(value32 & 0x000f0000)) { + version = VERSION_TEST_CHIP_92D_SINGLEPHY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("TEST CHIP!!!\n")); + } else { + version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Normal CHIP!!!\n")); + } + return version; +} + +static int _rtl92de_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 bcnfunc_enable; + + bt_msr &= 0xfc; + + if (type == NL80211_IFTYPE_UNSPECIFIED || + type == NL80211_IFTYPE_STATION) { + _rtl92de_stop_tx_beacon(hw); + _rtl92de_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || + type == NL80211_IFTYPE_AP) { + _rtl92de_resume_tx_beacon(hw); + _rtl92de_disable_bcn_sub_func(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Set HW_VAR_MEDIA_STATUS: No such media " + "status(%x).\n", type)); + } + bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL); + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + bcnfunc_enable &= 0xF7; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to NO LINK!\n")); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + bcnfunc_enable |= 0x08; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to Ad Hoc!\n")); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + bcnfunc_enable &= 0xF7; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to STA!\n")); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + bcnfunc_enable |= 0x08; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to AP!\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Network type %d not support!\n", type)); + return 1; + break; + + } + rtl_write_byte(rtlpriv, REG_CR + 2, bt_msr); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if ((bt_msr & 0xfc) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +} + +void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + if (check_bssid == true) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (check_bssid == false) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + } +} + +int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl92de_set_media_status(hw, type)) + return -EOPNOTSUPP; + + /* check bssid */ + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl92de_set_check_bssid(hw, true); + } else { + rtl92de_set_check_bssid(hw, false); + } + return 0; +} + +/* do iqk or reload iqk */ +/* windows just rtl92d_phy_reload_iqk_setting in set channel, + * but it's very strict for time sequence so we add + * rtl92d_phy_reload_iqk_setting here */ +void rtl92d_linked_set_reg(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 indexforchannel; + u8 channel = rtlphy->current_channel; + + indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); + if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) { + RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, + ("Do IQK for channel:%d.\n", channel)); + rtl92d_phy_iq_calibrate(hw); + } +} + +/* don't set REG_EDCA_BE_PARAM here because + * mac80211 will send pkt when scan */ +void rtl92de_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl92d_dm_init_edca_turbo(hw); + return; + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + break; + } +} + +void rtl92de_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl92de_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); + rtlpci->irq_enabled = false; + synchronize_irq(rtlpci->pdev->irq); +} + +static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1b_tmp; + unsigned long flags; + + rtlpriv->intf_ops->enable_aspm(hw); + rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); + rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(15), 0); + + /* 0x20:value 05-->04 */ + rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); + + /* ==== Reset digital sequence ====== */ + rtl92d_firmware_selfreset(hw); + + /* f. SYS_FUNC_EN 0x03[7:0]=0x51 reset MCU, MAC register, DCORE */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); + + /* g. MCUFWDL 0x80[1:0]=0 reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + + /* h. GPIO_PIN_CTRL 0x44[31:0]=0x000 */ + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); + + /* i. Value = GPIO_PIN_CTRL[7:0] */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); + + /* j. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); */ + /* write external PIN level */ + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, + 0x00FF0000 | (u1b_tmp << 8)); + + /* k. GPIO_MUXCFG 0x42 [15:0] = 0x0780 */ + rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); + + /* l. LEDCFG 0x4C[15:0] = 0x8080 */ + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); + + /* ==== Disable analog sequence === */ + + /* m. AFE_PLL_CTRL[7:0] = 0x80 disable PLL */ + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); + + /* n. SPS0_CTRL 0x11[7:0] = 0x22 enter PFM mode */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + + /* o. AFE_XTAL_CTRL 0x24[7:0] = 0x0E disable XTAL, if No BT COEX */ + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); + + /* p. RSV_CTRL 0x1C[7:0] = 0x0E lock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); + + /* ==== interface into suspend === */ + + /* q. APS_FSMCO[15:8] = 0x58 PCIe suspend mode */ + /* According to power document V11, we need to set this */ + /* value as 0x18. Otherwise, we may not L0s sometimes. */ + /* This indluences power consumption. Bases on SD1's test, */ + /* set as 0x00 do not affect power current. And if it */ + /* is set as 0x18, they had ever met auto load fail problem. */ + rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("In PowerOff,reg0x%x=%X\n", REG_SPS0_CTRL, + rtl_read_byte(rtlpriv, REG_SPS0_CTRL))); + /* r. Note: for PCIe interface, PON will not turn */ + /* off m-bias and BandGap in PCIe suspend mode. */ + + /* 0x17[7] 1b': power off in process 0b' : power off over */ + if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { + spin_lock_irqsave(&globalmutex_power, flags); + u1b_tmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + u1b_tmp &= (~BIT(7)); + rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1b_tmp); + spin_unlock_irqrestore(&globalmutex_power, flags); + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<=======\n")); +} + +void rtl92de_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92de_set_media_status(hw, opmode); + + if (rtlpci->driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + /* Power sequence for each MAC. */ + /* a. stop tx DMA */ + /* b. close RF */ + /* c. clear rx buf */ + /* d. stop rx DMA */ + /* e. reset MAC */ + + /* a. stop tx DMA */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFE); + udelay(50); + + /* b. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */ + + /* c. ========RF OFF sequence========== */ + /* 0x88c[23:20] = 0xf. */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); + + /* APSD_CTRL 0x600[7:0] = 0x40 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + + /* Close antenna 0,0xc04,0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0); + + /* SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB state machine */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + + /* Mac0 can not do Global reset. Mac1 can do. */ + /* SYS_FUNC_EN 0x02[7:0] = 0xE0 reset BB state machine */ + if (rtlpriv->rtlhal.interfaceindex == 1) + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); + udelay(50); + + /* d. stop tx/rx dma before disable REG_CR (0x100) to fix */ + /* dma hang issue when disable/enable device. */ + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff); + udelay(50); + rtl_write_byte(rtlpriv, REG_CR, 0x0); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==> Do power off.......\n")); + if (rtl92d_phy_check_poweroff(hw)) + _rtl92de_poweroff_adapter(hw); + return; +} + +void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, ISR, *p_inta); + + /* + * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; + * rtl_write_dword(rtlpriv, ISR + 4, *p_intb); + */ +} + +void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; + /*rtl92de_disable_interrupt(hw); */ + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x20); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30); + else + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x20); + rtl_write_byte(rtlpriv, 0x606, 0x30); +} + +void rtl92de_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, + ("beacon_interval:%d\n", bcn_interval)); + /* rtl92de_disable_interrupt(hw); */ + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + /* rtl92de_enable_interrupt(hw); */ +} + +void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, + ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl92de_disable_interrupt(hw); + rtl92de_enable_interrupt(hw); +} + +static void _rtl92de_readpowervalue_fromprom(struct txpower_info *pwrinfo, + u8 *rom_content, bool autoLoadfail) +{ + u32 rfpath, eeaddr, group, offset1, offset2; + u8 i; + + memset(pwrinfo, 0, sizeof(struct txpower_info)); + if (autoLoadfail) { + for (group = 0; group < CHANNEL_GROUP_MAX; group++) { + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + if (group < CHANNEL_GROUP_MAX_2G) { + pwrinfo->cck_index[rfpath][group] = + EEPROM_DEFAULT_TXPOWERLEVEL_2G; + pwrinfo->ht40_1sindex[rfpath][group] = + EEPROM_DEFAULT_TXPOWERLEVEL_2G; + } else { + pwrinfo->ht40_1sindex[rfpath][group] = + EEPROM_DEFAULT_TXPOWERLEVEL_5G; + } + pwrinfo->ht40_2sindexdiff[rfpath][group] = + EEPROM_DEFAULT_HT40_2SDIFF; + pwrinfo->ht20indexdiff[rfpath][group] = + EEPROM_DEFAULT_HT20_DIFF; + pwrinfo->ofdmindexdiff[rfpath][group] = + EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + pwrinfo->ht40maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT40_PWRMAXOFFSET; + pwrinfo->ht20maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT20_PWRMAXOFFSET; + } + } + for (i = 0; i < 3; i++) { + pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI; + pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI; + } + return; + } + + /* Maybe autoload OK,buf the tx power index value is not filled. + * If we find it, we set it to default value. */ + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + for (group = 0; group < CHANNEL_GROUP_MAX_2G; group++) { + eeaddr = EEPROM_CCK_TX_PWR_INX_2G + (rfpath * 3) + + group; + pwrinfo->cck_index[rfpath][group] = + (rom_content[eeaddr] == 0xFF) ? + (eeaddr > 0x7B ? + EEPROM_DEFAULT_TXPOWERLEVEL_5G : + EEPROM_DEFAULT_TXPOWERLEVEL_2G) : + rom_content[eeaddr]; + } + } + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + for (group = 0; group < CHANNEL_GROUP_MAX; group++) { + offset1 = group / 3; + offset2 = group % 3; + eeaddr = EEPROM_HT40_1S_TX_PWR_INX_2G + (rfpath * 3) + + offset2 + offset1 * 21; + pwrinfo->ht40_1sindex[rfpath][group] = + (rom_content[eeaddr] == 0xFF) ? (eeaddr > 0x7B ? + EEPROM_DEFAULT_TXPOWERLEVEL_5G : + EEPROM_DEFAULT_TXPOWERLEVEL_2G) : + rom_content[eeaddr]; + } + } + /* These just for 92D efuse offset. */ + for (group = 0; group < CHANNEL_GROUP_MAX; group++) { + for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { + int base1 = EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G; + + offset1 = group / 3; + offset2 = group % 3; + + if (rom_content[base1 + offset2 + offset1 * 21] != 0xFF) + pwrinfo->ht40_2sindexdiff[rfpath][group] = + (rom_content[base1 + + offset2 + offset1 * 21] >> (rfpath * 4)) + & 0xF; + else + pwrinfo->ht40_2sindexdiff[rfpath][group] = + EEPROM_DEFAULT_HT40_2SDIFF; + if (rom_content[EEPROM_HT20_TX_PWR_INX_DIFF_2G + offset2 + + offset1 * 21] != 0xFF) + pwrinfo->ht20indexdiff[rfpath][group] = + (rom_content[EEPROM_HT20_TX_PWR_INX_DIFF_2G + + offset2 + offset1 * 21] >> (rfpath * 4)) + & 0xF; + else + pwrinfo->ht20indexdiff[rfpath][group] = + EEPROM_DEFAULT_HT20_DIFF; + if (rom_content[EEPROM_OFDM_TX_PWR_INX_DIFF_2G + offset2 + + offset1 * 21] != 0xFF) + pwrinfo->ofdmindexdiff[rfpath][group] = + (rom_content[EEPROM_OFDM_TX_PWR_INX_DIFF_2G + + offset2 + offset1 * 21] >> (rfpath * 4)) + & 0xF; + else + pwrinfo->ofdmindexdiff[rfpath][group] = + EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + if (rom_content[EEPROM_HT40_MAX_PWR_OFFSET_2G + offset2 + + offset1 * 21] != 0xFF) + pwrinfo->ht40maxoffset[rfpath][group] = + (rom_content[EEPROM_HT40_MAX_PWR_OFFSET_2G + + offset2 + offset1 * 21] >> (rfpath * 4)) + & 0xF; + else + pwrinfo->ht40maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT40_PWRMAXOFFSET; + if (rom_content[EEPROM_HT20_MAX_PWR_OFFSET_2G + offset2 + + offset1 * 21] != 0xFF) + pwrinfo->ht20maxoffset[rfpath][group] = + (rom_content[EEPROM_HT20_MAX_PWR_OFFSET_2G + + offset2 + offset1 * 21] >> (rfpath * 4)) & + 0xF; + else + pwrinfo->ht20maxoffset[rfpath][group] = + EEPROM_DEFAULT_HT20_PWRMAXOFFSET; + } + } + if (rom_content[EEPROM_TSSI_A_5G] != 0xFF) { + /* 5GL */ + pwrinfo->tssi_a[0] = rom_content[EEPROM_TSSI_A_5G] & 0x3F; + pwrinfo->tssi_b[0] = rom_content[EEPROM_TSSI_B_5G] & 0x3F; + /* 5GM */ + pwrinfo->tssi_a[1] = rom_content[EEPROM_TSSI_AB_5G] & 0x3F; + pwrinfo->tssi_b[1] = + (rom_content[EEPROM_TSSI_AB_5G] & 0xC0) >> 6 | + (rom_content[EEPROM_TSSI_AB_5G + 1] & 0x0F) << 2; + /* 5GH */ + pwrinfo->tssi_a[2] = (rom_content[EEPROM_TSSI_AB_5G + 1] & + 0xF0) >> 4 | + (rom_content[EEPROM_TSSI_AB_5G + 2] & 0x03) << 4; + pwrinfo->tssi_b[2] = (rom_content[EEPROM_TSSI_AB_5G + 2] & + 0xFC) >> 2; + } else { + for (i = 0; i < 3; i++) { + pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI; + pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI; + } + } +} + +static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct txpower_info pwrinfo; + u8 tempval[2], i, pwr, diff; + u32 ch, rfPath, group; + + _rtl92de_readpowervalue_fromprom(&pwrinfo, hwinfo, autoload_fail); + if (!autoload_fail) { + /* bit0~2 */ + rtlefuse->eeprom_regulatory = (hwinfo[EEPROM_RF_OPT1] & 0x7); + rtlefuse->eeprom_thermalmeter = + hwinfo[EEPROM_THERMAL_METER] & 0x1f; + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_K]; + tempval[0] = hwinfo[EEPROM_IQK_DELTA] & 0x03; + tempval[1] = (hwinfo[EEPROM_LCK_DELTA] & 0x0C) >> 2; + rtlefuse->txpwr_fromeprom = true; + if (IS_92D_D_CUT(rtlpriv->rtlhal.version)) { + rtlefuse->internal_pa_5g[0] = + !((hwinfo[EEPROM_TSSI_A_5G] & + BIT(6)) >> 6); + rtlefuse->internal_pa_5g[1] = + !((hwinfo[EEPROM_TSSI_B_5G] & + BIT(6)) >> 6); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Is D cut,Internal PA0 %d Internal PA1 %d\n", + rtlefuse->internal_pa_5g[0], + rtlefuse->internal_pa_5g[1])) + } + rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; + rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; + } else { + rtlefuse->eeprom_regulatory = 0; + rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->crystalcap = EEPROM_DEFAULT_CRYSTALCAP; + tempval[0] = tempval[1] = 3; + } + + /* Use default value to fill parameters if + * efuse is not filled on some place. */ + + /* ThermalMeter from EEPROM */ + if (rtlefuse->eeprom_thermalmeter < 0x06 || + rtlefuse->eeprom_thermalmeter > 0x1c) + rtlefuse->eeprom_thermalmeter = 0x12; + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + + /* check XTAL_K */ + if (rtlefuse->crystalcap == 0xFF) + rtlefuse->crystalcap = 0; + if (rtlefuse->eeprom_regulatory > 3) + rtlefuse->eeprom_regulatory = 0; + + for (i = 0; i < 2; i++) { + switch (tempval[i]) { + case 0: + tempval[i] = 5; + break; + case 1: + tempval[i] = 4; + break; + case 2: + tempval[i] = 3; + break; + case 3: + default: + tempval[i] = 0; + break; + } + } + + rtlefuse->delta_iqk = tempval[0]; + if (tempval[1] > 0) + rtlefuse->delta_lck = tempval[1] - 1; + if (rtlefuse->eeprom_c9 == 0xFF) + rtlefuse->eeprom_c9 = 0x00; + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, + ("EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, + ("ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, + ("CrystalCap = 0x%x\n", rtlefuse->crystalcap)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, + ("Delta_IQK = 0x%x Delta_LCK = 0x%x\n", rtlefuse->delta_iqk, + rtlefuse->delta_lck)); + + for (rfPath = 0; rfPath < RF6052_MAX_PATH; rfPath++) { + for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { + group = rtl92d_get_chnlgroup_fromarray((u8) ch); + if (ch < CHANNEL_MAX_NUMBER_2G) + rtlefuse->txpwrlevel_cck[rfPath][ch] = + pwrinfo.cck_index[rfPath][group]; + rtlefuse->txpwrlevel_ht40_1s[rfPath][ch] = + pwrinfo.ht40_1sindex[rfPath][group]; + rtlefuse->txpwr_ht20diff[rfPath][ch] = + pwrinfo.ht20indexdiff[rfPath][group]; + rtlefuse->txpwr_legacyhtdiff[rfPath][ch] = + pwrinfo.ofdmindexdiff[rfPath][group]; + rtlefuse->pwrgroup_ht20[rfPath][ch] = + pwrinfo.ht20maxoffset[rfPath][group]; + rtlefuse->pwrgroup_ht40[rfPath][ch] = + pwrinfo.ht40maxoffset[rfPath][group]; + pwr = pwrinfo.ht40_1sindex[rfPath][group]; + diff = pwrinfo.ht40_2sindexdiff[rfPath][group]; + rtlefuse->txpwrlevel_ht40_2s[rfPath][ch] = + (pwr > diff) ? (pwr - diff) : 0; + } + } +} + +static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw, + u8 *content) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 macphy_crvalue = content[EEPROM_MAC_FUNCTION]; + + if (macphy_crvalue & BIT(3)) { + rtlhal->macphymode = SINGLEMAC_SINGLEPHY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("MacPhyMode SINGLEMAC_SINGLEPHY\n")); + } else { + rtlhal->macphymode = DUALMAC_DUALPHY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("MacPhyMode DUALMAC_DUALPHY\n")); + } +} + +static void _rtl92de_read_macphymode_and_bandtype(struct ieee80211_hw *hw, + u8 *content) +{ + _rtl92de_read_macphymode_from_prom(hw, content); + rtl92d_phy_config_macphymode(hw); + rtl92d_phy_config_macphymode_info(hw); +} + +static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + enum version_8192d chipver = rtlpriv->rtlhal.version; + u8 cutvalue[2]; + u16 chipvalue; + + rtlpriv->intf_ops->read_efuse_byte(hw, EEPROME_CHIP_VERSION_H, + &cutvalue[1]); + rtlpriv->intf_ops->read_efuse_byte(hw, EEPROME_CHIP_VERSION_L, + &cutvalue[0]); + chipvalue = (cutvalue[1] << 8) | cutvalue[0]; + switch (chipvalue) { + case 0xAA55: + chipver |= CHIP_92D_C_CUT; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("C-CUT!!!\n")); + break; + case 0x9966: + chipver |= CHIP_92D_D_CUT; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("D-CUT!!!\n")); + break; + default: + chipver |= CHIP_92D_D_CUT; + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unkown CUT!\n")); + break; + } + rtlpriv->rtlhal.version = chipver; +} + +static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u16 i, usvalue; + u8 hwinfo[HWSET_MAX_SIZE]; + u16 eeprom_id; + unsigned long flags; + + if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { + spin_lock_irqsave(&globalmutex_for_power_and_efuse, flags); + rtl_efuse_shadow_map_update(hw); + _rtl92de_efuse_update_chip_version(hw); + spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); + memcpy((void *)hwinfo, (void *)&rtlefuse->efuse_map + [EFUSE_INIT_MAP][0], + HWSET_MAX_SIZE); + } else if (rtlefuse->epromtype == EEPROM_93C46) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("RTL819X Not boot from eeprom, check it !!")); + } + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + hwinfo, HWSET_MAX_SIZE); + + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != RTL8190_EEPROM_ID) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + rtlefuse->autoload_failflag = true; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + rtlefuse->autoload_failflag = false; + } + if (rtlefuse->autoload_failflag == true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("RTL819X Not boot from eeprom, check it !!")); + return; + } + rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; + _rtl92de_read_macphymode_and_bandtype(hw, hwinfo); + + /* VID, DID SE 0xA-D */ + rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; + rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; + rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; + rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROMId = 0x%4x\n", eeprom_id)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + + /* Read Permanent MAC address */ + if (rtlhal->interfaceindex == 0) { + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_MAC0_92D + i]; + *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; + } + } else { + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_MAC1_92D + i]; + *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; + } + } + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, + rtlefuse->dev_addr); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr))); + _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo); + + /* Read Channel Plan */ + switch (rtlhal->bandset) { + case BAND_ON_2_4G: + rtlefuse->channel_plan = COUNTRY_CODE_TELEC; + break; + case BAND_ON_5G: + rtlefuse->channel_plan = COUNTRY_CODE_FCC; + break; + case BAND_ON_BOTH: + rtlefuse->channel_plan = COUNTRY_CODE_FCC; + break; + default: + rtlefuse->channel_plan = COUNTRY_CODE_FCC; + break; + } + rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; + rtlefuse->txpwr_fromeprom = true; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); +} + +void rtl92de_read_eeprom_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl92de_read_chip_version(hw); + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + rtlefuse->autoload_status = tmp_u1b; + if (tmp_u1b & BIT(4)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + rtlefuse->epromtype = EEPROM_93C46; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + + rtlefuse->autoload_failflag = false; + _rtl92de_read_adapter_info(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + } + return; +} + +static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw, + struct ieee80211_sta *sta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 ratr_value; + u8 ratr_index = 0; + u8 nmode = mac->ht_enable; + u8 mimo_ps = IEEE80211_SMPS_OFF; + u16 shortgi_rate; + u32 tmp_ratr_value; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = mac->mode; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_value = sta->supp_rates[1] << 4; + else + ratr_value = sta->supp_rates[0]; + ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | + sta->ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_A: + ratr_value &= 0x00000FF0; + break; + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + nmode = 1; + if (mimo_ps == IEEE80211_SMPS_STATIC) { + ratr_value &= 0x0007F005; + } else { + u32 ratr_mask; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) { + ratr_mask = 0x000ff005; + } else { + ratr_mask = 0x0f0ff005; + } + + ratr_value &= ratr_mask; + } + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + + break; + } + ratr_value &= 0x0FFFFFFF; + if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz))) { + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); +} + +static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap; + u8 ratr_index; + u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + ? 1 : 0; + u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + 1 : 0; + u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + 1 : 0; + enum wireless_mode wirelessmode = 0; + bool shortgi = false; + u32 value[2]; + u8 macid = 0; + u8 mimo_ps = IEEE80211_SMPS_OFF; + + sta_entry = (struct rtl_sta_info *) sta->drv_priv; + mimo_ps = sta_entry->mimo_ps; + wirelessmode = sta_entry->wireless_mode; + if (mac->opmode == NL80211_IFTYPE_STATION) + curtxbw_40mhz = mac->bw_40; + else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + + if (rtlhal->current_bandtype == BAND_ON_5G) + ratr_bitmap = sta->supp_rates[1] << 4; + else + ratr_bitmap = sta->supp_rates[0]; + ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | + sta->ht_cap.mcs.rx_mask[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_G; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + if (wirelessmode == WIRELESS_MODE_N_24G) + ratr_index = RATR_INX_WIRELESS_NGB; + else + ratr_index = RATR_INX_WIRELESS_NG; + if (mimo_ps == IEEE80211_SMPS_STATIC) { + if (rssi_level == 1) + ratr_bitmap &= 0x00070000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0007f000; + else + ratr_bitmap &= 0x0007f005; + } else { + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + } + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + + value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); + value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80; + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + ("ratr_bitmap :%x value0:%x value1:%x\n", + ratr_bitmap, value[0], value[1])); + rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value); + if (macid != 0) + sta_entry->ratr_index = ratr_index; +} + +void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl92de_update_hal_rate_mask(hw, sta, rssi_level); + else + rtl92de_update_hal_rate_table(hw, sta); +} + +void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x1010; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + enum rf_pwrstate e_rfpowerstate_toset; + u8 u1tmp; + bool actuallyset = false; + unsigned long flag; + + if (rtlpci->being_init_adapter) + return false; + if (ppsc->swrf_processing) + return false; + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, + REG_MAC_PINMUX_CFG) & ~(BIT(3))); + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; + if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("GPIOChangeRF - HW Radio ON, RF ON\n")); + e_rfpowerstate_toset = ERFON; + ppsc->hwradiooff = false; + actuallyset = true; + } else if ((ppsc->hwradiooff == false) + && (e_rfpowerstate_toset == ERFOFF)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + e_rfpowerstate_toset = ERFOFF; + ppsc->hwradiooff = true; + actuallyset = true; + } + if (actuallyset) { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } else { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + *valid = 1; + return !ppsc->hwradiooff; +} + +void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id; + bool is_pairwise = false; + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx; + u8 cam_offset = 0; + u8 clear_number = 5; + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " + "not process\n")); + enc_algo = CAM_TKIP; + break; + } + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = rtl_cam_get_free_entry(hw, + p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + RT_TRACE(rtlpriv, COMP_SEC, + DBG_EMERG, ("Can not " + "find free hw security" + " cam entry\n")); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + if (rtlpriv->sec.key_len[key_index] == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("delete one entry, entry_id is %d\n", + entry_id)); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1])); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("add one entry\n")); + if (is_pairwise) { + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, + "Pairwiase Key content :", + rtlpriv->sec.pairwise_key, + rtlpriv-> + sec.key_len[PAIRWISE_KEYIDX]); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set Pairwiase key\n")); + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv-> + sec.key_buf[key_index]); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set group key\n")); + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + } + } +} + +void rtl92de_suspend(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->rtlhal.macphyctl_reg = rtl_read_byte(rtlpriv, + REG_MAC_PHY_CTRL_NORMAL); +} + +void rtl92de_resume(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL, + rtlpriv->rtlhal.macphyctl_reg); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h new file mode 100644 index 00000000000..ad44ffa520e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92DE_HW_H__ +#define __RTL92DE_HW_H__ + +void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92de_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92de_interrupt_recognized(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb); +int rtl92de_hw_init(struct ieee80211_hw *hw); +void rtl92de_card_disable(struct ieee80211_hw *hw); +void rtl92de_enable_interrupt(struct ieee80211_hw *hw); +void rtl92de_disable_interrupt(struct ieee80211_hw *hw); +int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl92de_set_qos(struct ieee80211_hw *hw, int aci); +void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92de_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level); +void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + +extern void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, + u32 value, u8 direct); +extern u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, + u8 direct); +void rtl92de_suspend(struct ieee80211_hw *hw); +void rtl92de_resume(struct ieee80211_hw *hw); +void rtl92d_linked_set_reg(struct ieee80211_hw *hw); + +#endif -- cgit v1.2.3-70-g09d2 From f53d5a700694bd8eef081468fd936e0b174b4c94 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:10:10 -0500 Subject: rtlwifi: rtl8192de: Merge led routines Merge routines led.c and led.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/led.c | 159 +++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/led.h | 38 +++++++ 2 files changed, 197 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/led.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/led.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c new file mode 100644 index 00000000000..c965c73cf18 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -0,0 +1,159 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +static void _rtl92ce_init_led(struct ieee80211_hw *hw, + struct rtl_led *pled, enum rtl_led_pin ledpin) +{ + pled->hw = hw; + pled->ledpin = ledpin; + pled->ledon = false; +} + +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + if ((rtlpriv->efuse.eeprom_did == 0x8176) || + (rtlpriv->efuse.eeprom_did == 0x8193)) + /* BIT7 of REG_LEDCFG2 should be set to + * make sure we could emit the led2. */ + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | + BIT(7) | BIT(5) | BIT(6)); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | + BIT(7) | BIT(5)); + break; + case LED_PIN_LED1: + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); + + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->ledon = true; +} + +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + u8 ledcfg; + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (pcipriv->ledctl.led_opendrain == true) + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(1) | BIT(5) | BIT(6))); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->ledon = false; +} + +void rtl92de_init_sw_leds(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); + _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); +} + +static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl92ce_sw_led_on(hw, pLed0); + break; + case LED_CTL_POWER_OFF: + rtl92ce_sw_led_off(hw, pLed0); + break; + default: + break; + } +} + +void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", ledaction)); + + _rtl92ce_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/rtlwifi/rtl8192de/led.h new file mode 100644 index 00000000000..f6d33a6f0f8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CE_LED_H__ +#define __RTL92CE_LED_H__ + +void rtl92de_init_sw_leds(struct ieee80211_hw *hw); +void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif -- cgit v1.2.3-70-g09d2 From 7274a8c229805d5ab1228a2d7d8ed304fcfa2bc6 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:10:25 -0500 Subject: rtlwifi: rtl8192de: Merge phy routines Merge routines phy.c and phy.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 3837 ++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/phy.h | 178 ++ 2 files changed, 4015 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/phy.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/phy.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c new file mode 100644 index 00000000000..4d4c8ebc77a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -0,0 +1,3837 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" +#include "sw.h" +#include "hw.h" + +#define MAX_RF_IMR_INDEX 12 +#define MAX_RF_IMR_INDEX_NORMAL 13 +#define RF_REG_NUM_FOR_C_CUT_5G 6 +#define RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA 7 +#define RF_REG_NUM_FOR_C_CUT_2G 5 +#define RF_CHNL_NUM_5G 19 +#define RF_CHNL_NUM_5G_40M 17 +#define TARGET_CHNL_NUM_5G 221 +#define TARGET_CHNL_NUM_2G 14 +#define CV_CURVE_CNT 64 + +static u32 rf_reg_for_5g_swchnl_normal[MAX_RF_IMR_INDEX_NORMAL] = { + 0, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0 +}; + +static u8 rf_reg_for_c_cut_5g[RF_REG_NUM_FOR_C_CUT_5G] = { + RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G4, RF_SYN_G5, RF_SYN_G6 +}; + +static u8 rf_reg_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = { + RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G7, RF_SYN_G8 +}; + +static u8 rf_for_c_cut_5g_internal_pa[RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = { + 0x0B, 0x48, 0x49, 0x4B, 0x03, 0x04, 0x0E +}; + +static u32 rf_reg_mask_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = { + BIT(19) | BIT(18) | BIT(17) | BIT(14) | BIT(1), + BIT(10) | BIT(9), + BIT(18) | BIT(17) | BIT(16) | BIT(1), + BIT(2) | BIT(1), + BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11) +}; + +static u8 rf_chnl_5g[RF_CHNL_NUM_5G] = { + 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, + 112, 116, 120, 124, 128, 132, 136, 140 +}; + +static u8 rf_chnl_5g_40m[RF_CHNL_NUM_5G_40M] = { + 38, 42, 46, 50, 54, 58, 62, 102, 106, 110, 114, + 118, 122, 126, 130, 134, 138 +}; +static u32 rf_reg_pram_c_5g[5][RF_REG_NUM_FOR_C_CUT_5G] = { + {0xE43BE, 0xFC638, 0x77C0A, 0xDE471, 0xd7110, 0x8EB04}, + {0xE43BE, 0xFC078, 0xF7C1A, 0xE0C71, 0xD7550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C0A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF079, 0xF7C1A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C1A, 0xDE471, 0xd7550, 0xAEB04} +}; + +static u32 rf_reg_param_for_c_cut_2g[3][RF_REG_NUM_FOR_C_CUT_2G] = { + {0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840}, + {0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840}, + {0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41} +}; + +static u32 rf_syn_g4_for_c_cut_2g = 0xD1C31 & 0x7FF; + +static u32 rf_pram_c_5g_int_pa[3][RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = { + {0x01a00, 0x40443, 0x00eb5, 0x89bec, 0x94a12, 0x94a12, 0x94a12}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a52, 0x94a52, 0x94a52}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a12, 0x94a12, 0x94a12} +}; + +/* [mode][patha+b][reg] */ +static u32 rf_imr_param_normal[1][3][MAX_RF_IMR_INDEX_NORMAL] = { + { + /* channel 1-14. */ + { + 0x70000, 0x00ff0, 0x4400f, 0x00ff0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x64888, 0xe266c, 0x00090, 0x22fff + }, + /* path 36-64 */ + { + 0x70000, 0x22880, 0x4470f, 0x55880, 0x00070, 0x88000, + 0x0, 0x88080, 0x70000, 0x64a82, 0xe466c, 0x00090, + 0x32c9a + }, + /* 100 -165 */ + { + 0x70000, 0x44880, 0x4477f, 0x77880, 0x00070, 0x88000, + 0x0, 0x880b0, 0x0, 0x64b82, 0xe466c, 0x00090, 0x32c9a + } + } +}; + +static u32 curveindex_5g[TARGET_CHNL_NUM_5G] = {0}; + +static u32 curveindex_2g[TARGET_CHNL_NUM_2G] = {0}; + +static u32 targetchnl_5g[TARGET_CHNL_NUM_5G] = { + 25141, 25116, 25091, 25066, 25041, + 25016, 24991, 24966, 24941, 24917, + 24892, 24867, 24843, 24818, 24794, + 24770, 24765, 24721, 24697, 24672, + 24648, 24624, 24600, 24576, 24552, + 24528, 24504, 24480, 24457, 24433, + 24409, 24385, 24362, 24338, 24315, + 24291, 24268, 24245, 24221, 24198, + 24175, 24151, 24128, 24105, 24082, + 24059, 24036, 24013, 23990, 23967, + 23945, 23922, 23899, 23876, 23854, + 23831, 23809, 23786, 23764, 23741, + 23719, 23697, 23674, 23652, 23630, + 23608, 23586, 23564, 23541, 23519, + 23498, 23476, 23454, 23432, 23410, + 23388, 23367, 23345, 23323, 23302, + 23280, 23259, 23237, 23216, 23194, + 23173, 23152, 23130, 23109, 23088, + 23067, 23046, 23025, 23003, 22982, + 22962, 22941, 22920, 22899, 22878, + 22857, 22837, 22816, 22795, 22775, + 22754, 22733, 22713, 22692, 22672, + 22652, 22631, 22611, 22591, 22570, + 22550, 22530, 22510, 22490, 22469, + 22449, 22429, 22409, 22390, 22370, + 22350, 22336, 22310, 22290, 22271, + 22251, 22231, 22212, 22192, 22173, + 22153, 22134, 22114, 22095, 22075, + 22056, 22037, 22017, 21998, 21979, + 21960, 21941, 21921, 21902, 21883, + 21864, 21845, 21826, 21807, 21789, + 21770, 21751, 21732, 21713, 21695, + 21676, 21657, 21639, 21620, 21602, + 21583, 21565, 21546, 21528, 21509, + 21491, 21473, 21454, 21436, 21418, + 21400, 21381, 21363, 21345, 21327, + 21309, 21291, 21273, 21255, 21237, + 21219, 21201, 21183, 21166, 21148, + 21130, 21112, 21095, 21077, 21059, + 21042, 21024, 21007, 20989, 20972, + 25679, 25653, 25627, 25601, 25575, + 25549, 25523, 25497, 25471, 25446, + 25420, 25394, 25369, 25343, 25318, + 25292, 25267, 25242, 25216, 25191, + 25166 +}; + +/* channel 1~14 */ +static u32 targetchnl_2g[TARGET_CHNL_NUM_2G] = { + 26084, 26030, 25976, 25923, 25869, 25816, 25764, + 25711, 25658, 25606, 25554, 25502, 25451, 25328 +}; + +static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) { + if (((bitmask >> i) & 0x1) == 1) + break; + } + + return i; +} + +u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u32 returnvalue, originalvalue, bitshift; + u8 dbi_direct; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x)\n", regaddr, bitmask)); + if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) { + /* mac1 use phy0 read radio_b. */ + /* mac0 use phy1 read radio_b. */ + if (rtlhal->during_mac1init_radioa) + dbi_direct = BIT(3); + else if (rtlhal->during_mac0init_radiob) + dbi_direct = BIT(3) | BIT(2); + originalvalue = rtl92de_read_dword_dbi(hw, (u16)regaddr, + dbi_direct); + } else { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + } + bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " + "Addr[0x%x]=0x%x\n", bitmask, regaddr, originalvalue)); + return returnvalue; +} + +void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 dbi_direct = 0; + u32 originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, data)); + if (rtlhal->during_mac1init_radioa) + dbi_direct = BIT(3); + else if (rtlhal->during_mac0init_radiob) + /* mac0 use phy1 write radio_b. */ + dbi_direct = BIT(3) | BIT(2); + if (bitmask != BMASKDWORD) { + if (rtlhal->during_mac1init_radioa || + rtlhal->during_mac0init_radiob) + originalvalue = rtl92de_read_dword_dbi(hw, + (u16) regaddr, + dbi_direct); + else + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) + rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct); + else + rtl_write_dword(rtlpriv, regaddr, data); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, data)); +} + +static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + newoffset = offset; + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD, + tmplong & (~BLSSIREADEDGE)); + udelay(10); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD, tmplong2); + udelay(50); + udelay(50); + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD, + tmplong | BLSSIREADEDGE); + udelay(10); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, + BLSSIREADBACKDATA); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x] = 0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue)); + return retvalue; +} + +static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 offset, u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + newoffset = offset; + /* T65 RF */ + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr)); +} + +u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask)); + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); + bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " + "bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value)); + return readback_value; +} + +void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 original_value, bitshift; + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath)); + if (bitmask == 0) + return; + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != BRFREGOFFSETMASK) { + original_value = _rtl92d_phy_rf_serial_read(hw, + rfpath, regaddr); + bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data); + } + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath)); +} + +bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + arraylength = MAC_2T_ARRAYLENGTH; + ptrarray = rtl8192de_mac_2tarray; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Img:Rtl819XMAC_Array\n")); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { + /* improve 2-stream TX EVM */ + /* rtl_write_byte(rtlpriv, 0x14,0x71); */ + /* AMPDU aggregation number 9 */ + /* rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */ + rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x0B); + } else { + /* 92D need to test to decide the num. */ + rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x07); + } + return true; +} + +static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + /* RF Interface Sowrtware Control */ + /* 16 LSBs if read 32-bit from 0x870 */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + /* 16 LSBs if read 32-bit from 0x874 */ + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + /* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */ + + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + /* RF Interface Readback Value */ + /* 16 LSBs if read 32-bit from 0x8E0 */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + /* 16 LSBs if read 32-bit from 0x8E4 */ + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + /* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */ + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + /* RF Interface Output (and Enable) */ + /* 16 LSBs if read 32-bit from 0x860 */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + /* 16 LSBs if read 32-bit from 0x864 */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + /* RF Interface (Output and) Enable */ + /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + /* Addr of LSSI. Wirte RF register by driver */ + /* LSSI Parameter */ + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + /* RF parameter */ + /* BB Band Select */ + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; + + /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + /* Tx gain stage */ + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + /* Tranceiver A~D HSSI Parameter-1 */ + /* wire control parameter1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + /* wire control parameter1 */ + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + /* Tranceiver A~D HSSI Parameter-2 */ + /* wire control parameter2 */ + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + /* wire control parameter2 */ + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + /* RF switch Control */ + /* TR/Ant switch control */ + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + + /* AGC control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + /* AGC control 2 */ + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + /* RX AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; + + /*RX AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + /* Tx AFE control 1 */ + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTxIQIMBALANCE; + + /* Tx AFE control 2 */ + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATxAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTxAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTxAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTxAFE; + + /* Tranceiver LSSI Readback SI mode */ + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; + + /* Tranceiver LSSI Readback PI mode */ + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVERA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVERB_HSPI_READBACK; +} + +static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table = NULL; + u32 *agctab_5garray_table; + u16 phy_reg_arraylen, agctab_arraylen = 0, agctab_5garraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + /* Normal chip,Mac0 use AGC_TAB.txt for 2G and 5G band. */ + if (rtlhal->interfaceindex == 0) { + agctab_arraylen = AGCTAB_ARRAYLENGTH; + agctab_array_table = rtl8192de_agctab_array; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + (" ===> phy:MAC0, Rtl819XAGCTAB_Array\n")); + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + agctab_arraylen = AGCTAB_2G_ARRAYLENGTH; + agctab_array_table = rtl8192de_agctab_2garray; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + (" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n")); + } else { + agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH; + agctab_5garray_table = rtl8192de_agctab_5garray; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + (" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n")); + + } + } + phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH; + phy_regarray_table = rtl8192de_phy_reg_2tarray; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + (" ===> phy:Rtl819XPHY_REG_Array_PG\n")); + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + if (phy_regarray_table[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table[i] == 0xfb) + udelay(50); + else if (phy_regarray_table[i] == 0xfa) + udelay(5); + else if (phy_regarray_table[i] == 0xf9) + udelay(1); + rtl_set_bbreg(hw, phy_regarray_table[i], BMASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The phy_regarray_table[0] is %x" + " Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1])); + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + if (rtlhal->interfaceindex == 0) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], + BMASKDWORD, + agctab_array_table[i + 1]); + /* Add 1us delay between BB/RF register + * setting. */ + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The Rtl819XAGCTAB_Array_" + "Table[0] is %ul " + "Rtl819XPHY_REGArray[1] is %ul\n", + agctab_array_table[i], + agctab_array_table[i + 1])); + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Normal Chip, MAC0, load " + "Rtl819XAGCTAB_Array\n")); + } else { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], + BMASKDWORD, + agctab_array_table[i + 1]); + /* Add 1us delay between BB/RF register + * setting. */ + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The Rtl819XAGCTAB_Array_" + "Table[0] is %ul Rtl819XPHY_" + "REGArray[1] is %ul\n", + agctab_array_table[i], + agctab_array_table[i + 1])); + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Load Rtl819XAGCTAB_2GArray\n")); + } else { + for (i = 0; i < agctab_5garraylen; i = i + 2) { + rtl_set_bbreg(hw, + agctab_5garray_table[i], + BMASKDWORD, + agctab_5garray_table[i + 1]); + /* Add 1us delay between BB/RF registeri + * setting. */ + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The Rtl819XAGCTAB_5GArray_" + "Table[0] is %ul Rtl819XPHY_" + "REGArray[1] is %ul\n", + agctab_5garray_table[i], + agctab_5garray_table[i + 1])); + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Load Rtl819XAGCTAB_5GArray\n")); + } + } + } + return true; +} + +static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (regaddr == RTXAGC_A_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][0])); + } + if (regaddr == RTXAGC_A_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][1])); + } + if (regaddr == RTXAGC_A_CCK1_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][6])); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][7])); + } + if (regaddr == RTXAGC_A_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][2])); + } + if (regaddr == RTXAGC_A_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][3])); + } + if (regaddr == RTXAGC_A_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][4])); + } + if (regaddr == RTXAGC_A_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][5])); + } + if (regaddr == RTXAGC_B_RATE18_06) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][8])); + } + if (regaddr == RTXAGC_B_RATE54_24) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][9])); + } + if (regaddr == RTXAGC_B_CCK1_55_MCS32) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][14])); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][15])); + } + if (regaddr == RTXAGC_B_MCS03_MCS00) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][10])); + } + if (regaddr == RTXAGC_B_MCS07_MCS04) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][11])); + } + if (regaddr == RTXAGC_B_MCS11_MCS08) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][12])); + } + if (regaddr == RTXAGC_B_MCS15_MCS12) { + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = + data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][13])); + rtlphy->pwrgroup_cnt++; + } +} + +static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + phy_regarray_pg_len = PHY_REG_ARRAY_PG_LENGTH; + phy_regarray_table_pg = rtl8192de_phy_reg_array_pg; + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + if (phy_regarray_table_pg[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table_pg[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table_pg[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table_pg[i] == 0xfb) + udelay(50); + else if (phy_regarray_table_pg[i] == 0xfa) + udelay(5); + else if (phy_regarray_table_pg[i] == 0xf9) + udelay(1); + _rtl92d_store_pwrindex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("configtype != BaseBand_Config_PHY_REG\n")); + } + return true; +} + +static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus = true; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + return false; + } + + /* if (rtlphy->rf_type == RF_1T2R) { + * _rtl92c_phy_bb_config_1t(hw); + * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + *} */ + + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = _rtl92d_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + return false; + } + rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + return false; + } + rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, 0x200)); + + return true; +} + +bool rtl92d_phy_bb_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 regval; + u32 regvaldw; + u8 value; + + _rtl92d_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, + regval | BIT(13) | BIT(0) | BIT(1)); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + /* 0x1f bit7 bit6 represent for mac0/mac1 driver ready */ + value = rtl_read_byte(rtlpriv, REG_RF_CTRL); + rtl_write_byte(rtlpriv, REG_RF_CTRL, value | RF_EN | RF_RSTB | + RF_SDMRSTB); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA | + FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB); + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + if (!(IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))) { + regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); + rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); + } + + return _rtl92d_phy_bb_config(hw); +} + +bool rtl92d_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl92d_phy_rf6052_config(hw); +} + +bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum rf_content content, + enum radio_path rfpath) +{ + int i, j; + u32 *radioa_array_table; + u32 *radiob_array_table; + u16 radioa_arraylen, radiob_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + radioa_arraylen = RADIOA_2T_ARRAYLENGTH; + radioa_array_table = rtl8192de_radioa_2tarray; + radiob_arraylen = RADIOB_2T_ARRAYLENGTH; + radiob_array_table = rtl8192de_radiob_2tarray; + if (rtlpriv->efuse.internal_pa_5g[0]) { + radioa_arraylen = RADIOA_2T_INT_PA_ARRAYLENGTH; + radioa_array_table = rtl8192de_radioa_2t_int_paarray; + } + if (rtlpriv->efuse.internal_pa_5g[1]) { + radiob_arraylen = RADIOB_2T_INT_PA_ARRAYLENGTH; + radiob_array_table = rtl8192de_radiob_2t_int_paarray; + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("PHY_ConfigRFWithHeaderFile() " + "Radio_A:Rtl819XRadioA_1TArray\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("PHY_ConfigRFWithHeaderFile() " + "Radio_B:Rtl819XRadioB_1TArray\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + + /* this only happens when DMDP, mac0 start on 2.4G, + * mac1 start on 5G, mac 0 has to set phy0&phy1 + * pathA or mac1 has to set phy0&phy1 pathA */ + if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + (" ===> althougth Path A, we load radiob.txt\n")); + radioa_arraylen = radiob_arraylen; + radioa_array_table = radiob_array_table; + } + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + if (radioa_array_table[i] == 0xfe) { + mdelay(50); + } else if (radioa_array_table[i] == 0xfd) { + /* delay_ms(5); */ + for (j = 0; j < 100; j++) + udelay(MAX_STALL_TIME); + } else if (radioa_array_table[i] == 0xfc) { + /* delay_ms(1); */ + for (j = 0; j < 20; j++) + udelay(MAX_STALL_TIME); + + } else if (radioa_array_table[i] == 0xfb) { + udelay(50); + } else if (radioa_array_table[i] == 0xfa) { + udelay(5); + } else if (radioa_array_table[i] == 0xf9) { + udelay(1); + } else { + rtl_set_rfreg(hw, rfpath, radioa_array_table[i], + BRFREGOFFSETMASK, + radioa_array_table[i + 1]); + /* Add 1us delay between BB/RF register set. */ + udelay(1); + } + } + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + if (radiob_array_table[i] == 0xfe) { + /* Delay specific ms. Only RF configuration + * requires delay. */ + mdelay(50); + } else if (radiob_array_table[i] == 0xfd) { + /* delay_ms(5); */ + for (j = 0; j < 100; j++) + udelay(MAX_STALL_TIME); + } else if (radiob_array_table[i] == 0xfc) { + /* delay_ms(1); */ + for (j = 0; j < 20; j++) + udelay(MAX_STALL_TIME); + } else if (radiob_array_table[i] == 0xfb) { + udelay(50); + } else if (radiob_array_table[i] == 0xfa) { + udelay(5); + } else if (radiob_array_table[i] == 0xf9) { + udelay(1); + } else { + rtl_set_rfreg(hw, rfpath, radiob_array_table[i], + BRFREGOFFSETMASK, + radiob_array_table[i + 1]); + /* Add 1us delay between BB/RF register set. */ + udelay(1); + } + } + break; + case RF90_PATH_C: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + case RF90_PATH_D: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + return true; +} + +void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->default_initialgain[0] = + (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, BMASKBYTE0); + rtlphy->default_initialgain[1] = + (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, BMASKBYTE0); + rtlphy->default_initialgain[2] = + (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, BMASKBYTE0); + rtlphy->default_initialgain[3] = + (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default initial gain (c50=0x%x, " + "c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3])); + rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, + BMASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, + BMASKDWORD); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync)); +} + +static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + + /* 1. CCK */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* RF-A */ + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + /* RF-B */ + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + } else { + cckpowerlevel[RF90_PATH_A] = 0; + cckpowerlevel[RF90_PATH_B] = 0; + } + /* 2. OFDM for 1S or 2S */ + if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) { + /* Read HT 40 OFDM TX power */ + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } else if (rtlphy->rf_type == RF_2T2R) { + /* Read HT 40 OFDM TX power */ + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; + } +} + +static void _rtl92d_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +} + +static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl) +{ + u8 channel_5g[59] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 118, 120, 122, 124, 126, 128, + 130, 132, 134, 136, 138, 140, 149, 151, + 153, 155, 157, 159, 161, 163, 165 + }; + u8 place = chnl; + + if (chnl > 14) { + for (place = 14; place < sizeof(channel_5g); place++) { + if (channel_5g[place] == chnl) { + place++; + break; + } + } + } + return place; +} + +void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (rtlefuse->txpwr_fromeprom == false) + return; + channel = _rtl92c_phy_get_rightchnlplace(channel); + _rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) + _rtl92d_ccxpower_index_check(hw, channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) + rtl92d_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); +} + +void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + rtlhal->current_bandtypebackup = + rtlhal->current_bandtype; + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Unknown Scan Backup operation.\n")); + break; + } + } +} + +void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + unsigned long flag = 0; + u8 reg_prsr_rsc; + u8 reg_bw_opmode; + + if (rtlphy->set_bwmode_inprogress) + return; + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("FALSE driver sleep or unload\n")); + return; + } + rtlphy->set_bwmode_inprogress = true; + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz")); + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + + reg_prsr_rsc = (reg_prsr_rsc & 0x90) | + (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + /* SET BIT10 BIT11 for receive cck */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | + BIT(11), 3); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + /* Set Control channel to upper or lower. + * These settings are required only for 40MHz */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCKSIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + /* SET BIT10 BIT11 for receive cck */ + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | + BIT(11), 0); + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + + } + rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + +static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x00); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0); +} + +static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 i, value8; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + rtlhal->bandset = band; + rtlhal->current_bandtype = band; + if (IS_92D_SINGLEPHY(rtlhal->version)) + rtlhal->bandset = BAND_ON_BOTH; + /* stop RX/Tx */ + _rtl92d_phy_stop_trx_before_changeband(hw); + /* reconfig BB/RF according to wireless mode */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* BB & RF Config */ + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>2.4G\n")); + if (rtlhal->interfaceindex == 1) + _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + } else { + /* 5G band */ + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>5G\n")); + if (rtlhal->interfaceindex == 1) + _rtl92d_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + } + rtl92d_update_bbrf_configuration(hw); + if (rtlhal->current_bandtype == BAND_ON_2_4G) + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + + /* 20M BW. */ + /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); */ + rtlhal->reloadtxpowerindex = true; + /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1)); + value8 |= BIT(1); + rtl_write_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1), value8); + } else { + value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1)); + value8 &= (~BIT(1)); + rtl_write_byte(rtlpriv, (rtlhal->interfaceindex == + 0 ? REG_MAC0 : REG_MAC1), value8); + } + for (i = 0; i < 20; i++) + udelay(MAX_STALL_TIME); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n")); +} + +static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, + u8 channel, u8 rfpath) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 imr_num = MAX_RF_IMR_INDEX; + u32 rfmask = BRFREGOFFSETMASK; + u8 group, i; + unsigned long flag = 0; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>path %d\n", rfpath)); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); + /* fc area 0xd2c */ + if (channel > 99) + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) | + BIT(14), 2); + else + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) | + BIT(14), 1); + /* leave 0 for channel1-14. */ + group = channel <= 64 ? 1 : 2; + imr_num = MAX_RF_IMR_INDEX_NORMAL; + for (i = 0; i < imr_num; i++) + rtl_set_rfreg(hw, (enum radio_path)rfpath, + rf_reg_for_5g_swchnl_normal[i], rfmask, + rf_imr_param_normal[0][group][i]); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 1); + } else { + /* G band. */ + RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, + ("Load RF IMR parameters for G band. IMR already " + "setting %d\n", + rtlpriv->rtlhal.load_imrandiqk_setting_for2g)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) { + RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, + ("Load RF IMR parameters " + "for G band. %d\n", rfpath)); + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, + 0x00f00000, 0xf); + imr_num = MAX_RF_IMR_INDEX_NORMAL; + for (i = 0; i < imr_num; i++) { + rtl_set_rfreg(hw, (enum radio_path)rfpath, + rf_reg_for_5g_swchnl_normal[i], + BRFREGOFFSETMASK, + rf_imr_param_normal[0][0][i]); + } + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, + 0x00f00000, 0); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN | BCCKEN, 3); + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + } + } + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); +} + +static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, + u8 rfpath, u32 *pu4_regval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + /*----Store original RFENV control type----*/ + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + *pu4_regval = rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + *pu4_regval = + rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16); + break; + } + /*----Set RF_ENV enable----*/ + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + /*----Set RF_ENV output high----*/ + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + /* Set bit number of Address and Data for RF register */ + /* Set 1 to 4 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREADDRESSLENGTH, 0x0); + udelay(1); + /*Set 0 to 12 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); +} + +static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, + u32 *pu4_regval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("=====>\n")); + /*----Restore RFENV control type----*/ ; + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, *pu4_regval); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16, + *pu4_regval); + break; + } + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<=====\n")); +} + +static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 path = rtlhal->current_bandtype == + BAND_ON_5G ? RF90_PATH_A : RF90_PATH_B; + u8 index = 0, i = 0, rfpath = RF90_PATH_A; + bool need_pwr_down = false, internal_pa = false; + u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>\n")); + /* config path A for 5G */ + if (rtlhal->current_bandtype == BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + u4tmp = curveindex_5g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, " + "0x28 = 0x%x !!\n", u4tmp)); + for (i = 0; i < RF_CHNL_NUM_5G; i++) { + if (channel == rf_chnl_5g[i] && channel <= 140) + index = 0; + } + for (i = 0; i < RF_CHNL_NUM_5G_40M; i++) { + if (channel == rf_chnl_5g_40m[i] && channel <= 140) + index = 1; + } + if (channel == 149 || channel == 155 || channel == 161) + index = 2; + else if (channel == 151 || channel == 153 || channel == 163 + || channel == 165) + index = 3; + else if (channel == 157 || channel == 159) + index = 4; + + if (rtlhal->macphymode == DUALMAC_DUALPHY + && rtlhal->interfaceindex == 1) { + need_pwr_down = rtl92d_phy_enable_anotherphy(hw, false); + rtlhal->during_mac1init_radioa = true; + /* asume no this case */ + if (need_pwr_down) + _rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + for (i = 0; i < RF_REG_NUM_FOR_C_CUT_5G; i++) { + if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) { + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + BRFREGOFFSETMASK, 0xE439D); + } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) { + u4tmp2 = (rf_reg_pram_c_5g[index][i] & + 0x7FF) | (u4tmp << 11); + if (channel == 36) + u4tmp2 &= ~(BIT(7) | BIT(6)); + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + BRFREGOFFSETMASK, u4tmp2); + } else { + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + BRFREGOFFSETMASK, + rf_reg_pram_c_5g[index][i]); + } + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("offset 0x%x value 0x%x " + "path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_5g[i], + rf_reg_pram_c_5g[index][i], path, + index, rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], BRFREGOFFSETMASK))); + } + if (need_pwr_down) + _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + if (rtlhal->during_mac1init_radioa) + rtl92d_phy_powerdown_anotherphy(hw, false); + if (channel < 149) + value = 0x07; + else if (channel >= 149) + value = 0x02; + if (channel >= 36 && channel <= 64) + index = 0; + else if (channel >= 100 && channel <= 140) + index = 1; + else + index = 2; + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlhal->macphymode == DUALMAC_DUALPHY && + rtlhal->interfaceindex == 1) /* MAC 1 5G */ + internal_pa = rtlpriv->efuse.internal_pa_5g[1]; + else + internal_pa = + rtlpriv->efuse.internal_pa_5g[rfpath]; + if (internal_pa) { + for (i = 0; + i < RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA; + i++) { + rtl_set_rfreg(hw, rfpath, + rf_for_c_cut_5g_internal_pa[i], + BRFREGOFFSETMASK, + rf_pram_c_5g_int_pa[index][i]); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, + ("offset 0x%x value 0x%x " + "path %d index %d\n", + rf_for_c_cut_5g_internal_pa[i], + rf_pram_c_5g_int_pa[index][i], + rfpath, index)); + } + } else { + rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, + mask, value); + } + } + } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + u4tmp = curveindex_2g[channel - 1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, " + "0x28 = 0x%x !!\n", u4tmp)); + if (channel == 1 || channel == 2 || channel == 4 || channel == 9 + || channel == 10 || channel == 11 || channel == 12) + index = 0; + else if (channel == 3 || channel == 13 || channel == 14) + index = 1; + else if (channel >= 5 && channel <= 8) + index = 2; + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + path = RF90_PATH_A; + if (rtlhal->interfaceindex == 0) { + need_pwr_down = + rtl92d_phy_enable_anotherphy(hw, true); + rtlhal->during_mac0init_radiob = true; + + if (need_pwr_down) + _rtl92d_phy_enable_rf_env(hw, path, + &u4regvalue); + } + } + for (i = 0; i < RF_REG_NUM_FOR_C_CUT_2G; i++) { + if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7) + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + BRFREGOFFSETMASK, + (rf_reg_param_for_c_cut_2g[index][i] | + BIT(17))); + else + rtl_set_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + BRFREGOFFSETMASK, + rf_reg_param_for_c_cut_2g + [index][i]); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("offset 0x%x value 0x%x mak 0x%x path %d " + "index %d readback 0x%x\n", + rf_reg_for_c_cut_2g[i], + rf_reg_param_for_c_cut_2g[index][i], + rf_reg_mask_for_c_cut_2g[i], path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + BRFREGOFFSETMASK))); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rf_syn_g4_for_c_cut_2g | (u4tmp << 11))); + + rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, + BRFREGOFFSETMASK, + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); + if (need_pwr_down) + _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); + if (rtlhal->during_mac0init_radiob) + rtl92d_phy_powerdown_anotherphy(hw, true); + } + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); +} + +u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl) +{ + u8 channel_all[59] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 118, 120, 122, 124, 126, 128, 130, + 132, 134, 136, 138, 140, 149, 151, 153, 155, + 157, 159, 161, 163, 165 + }; + u8 place = chnl; + + if (chnl > 14) { + for (place = 14; place < sizeof(channel_all); place++) { + if (channel_all[place] == chnl) + return place - 13; + } + } + + return 0; +} + +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 /* ms */ +#define MAX_TOLERANCE_92D 3 + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 regeac, rege94, rege9c, regea4; + u8 result = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + /* path-A IQK setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + if (rtlhal->interfaceindex == 0) { + rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f); + } else { + rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c22); + } + rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x28160206); + /* path-B IQK setting */ + if (configpathb) { + rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206); + } + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); + /* One shot, path A LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Delay %d ms for One shot, path A LOK & IQK.\n", + IQK_DELAY_TIME)); + udelay(IQK_DELAY_TIME * 1000); + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) && + (((rege9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + /* if Tx is OK, check whether Rx is OK */ + if (!(regeac & BIT(27)) && (((regea4 & 0x03FF0000) >> 16) != 0x132) && + (((regeac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n")); + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, + bool configpathb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 regeac, rege94, rege9c, regea4; + u8 result = 0; + u8 i; + u8 retrycount = 2; + u32 TxOKBit = BIT(28), RxOKBit = BIT(27); + + if (rtlhal->interfaceindex == 1) { /* PHY1 */ + TxOKBit = BIT(31); + RxOKBit = BIT(30); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + /* path-A IQK setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307); + rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68160960); + /* path-B IQK setting */ + if (configpathb) { + rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82110000); + rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000); + } + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); + /* path-A PA on */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, 0x66e60e30); + for (i = 0; i < retrycount; i++) { + /* One shot, path A LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("One shot, path A LOK & IQK!\n")); + rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Delay %d ms for One shot, path A LOK & IQK.\n", + IQK_DELAY_TIME)); + udelay(IQK_DELAY_TIME * 1000 * 10); + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + if (!(regeac & TxOKBit) && + (((rege94 & 0x03FF0000) >> 16) != 0x142)) { + result |= 0x01; + } else { /* if Tx not OK, ignore Rx */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path A Tx IQK fail!!\n")); + continue; + } + + /* if Tx is OK, check whether Rx is OK */ + if (!(regeac & RxOKBit) && + (((regea4 & 0x03FF0000) >> 16) != 0x132)) { + result |= 0x02; + break; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path A Rx IQK fail!!\n")); + } + } + /* path A PA off */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, + rtlphy->iqk_bb_backup[0]); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, + rtlphy->iqk_bb_backup[1]); + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 regeac, regeb4, regebc, regec4, regecc; + u8 result = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + /* One shot, path B LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000); + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Delay %d ms for One shot, path B LOK & IQK.\n", + IQK_DELAY_TIME)); + udelay(IQK_DELAY_TIME * 1000); + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) && + (((regebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + if (!(regeac & BIT(30)) && (((regec4 & 0x03FF0000) >> 16) != 0x132) && + (((regecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n")); + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 regeac, regeb4, regebc, regec4, regecc; + u8 result = 0; + u8 i; + u8 retrycount = 2; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + /* path-A IQK setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); + rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000); + rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68110000); + + /* path-B IQK setting */ + rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f); + rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140307); + rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960); + + /* LO calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); + + /* path-B PA on */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x0f600700); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, 0x061f0d30); + + for (i = 0; i < retrycount; i++) { + /* One shot, path B LOK & IQK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("One shot, path A LOK & IQK!\n")); + rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000); + rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); + + /* delay x ms */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Delay %d ms for One shot, path B LOK & IQK.\n", 10)); + udelay(IQK_DELAY_TIME * 1000 * 10); + + /* Check failed */ + regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + if (!(regeac & BIT(31)) && + (((regeb4 & 0x03FF0000) >> 16) != 0x142)) + result |= 0x01; + else + continue; + if (!(regeac & BIT(30)) && + (((regec4 & 0x03FF0000) >> 16) != 0x132)) { + result |= 0x02; + break; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path B Rx IQK fail!!\n")); + } + } + + /* path B PA off */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, + rtlphy->iqk_bb_backup[0]); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, + rtlphy->iqk_bb_backup[2]); + return result; +} + +static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, + u32 *adda_reg, u32 *adda_backup, + u32 regnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save ADDA parameters.\n")); + for (i = 0; i < regnum; i++) + adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD); +} + +static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save MAC parameters.\n")); + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} + +static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *adda_reg, u32 *adda_backup, + u32 regnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Reload ADDA power saving parameters !\n")); + for (i = 0; i < regnum; i++) + rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]); +} + +static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Reload MAC parameters !\n")); + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); + rtl_write_byte(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw, + u32 *adda_reg, bool patha_on, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 pathon; + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ADDA ON.\n")); + pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (patha_on) + pathon = rtlpriv->rtlhal.interfaceindex == 0 ? + 0x04db25a4 : 0x0b1b25a4; + for (i = 0; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, pathon); +} + +static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("MAC settings for Calibration.\n")); + rtl_write_byte(rtlpriv, macreg[0], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & + (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); +} + +static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A standby mode!\n")); + + rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0); + rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); +} + +static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 mode; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI"))); + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode); +} + +static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], + u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u8 patha_ok, pathb_ok; + static u32 adda_reg[IQK_ADDA_REG_NUM] = { + RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + static u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE, + RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE, + RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4, + ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1 + }; + const u32 retrycount = 2; + u32 bbvalue; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 2.4G :Start!!!\n")); + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", + (is2t ? "2T2R" : "1T1R"))); + + /* Save ADDA parameters, turn Path A ADDA on */ + _rtl92d_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, IQK_ADDA_REG_NUM); + _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, IQK_BB_REG_NUM); + } + _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) + rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, BIT(8)); + + /* Switch BB to PI mode to do IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, true); + + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22204000); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); + if (is2t) { + rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, + 0x00010000); + rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, BMASKDWORD, + 0x00010000); + } + /* MAC settings */ + _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + /* Page B init */ + rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); + /* IQ calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl92d_phy_patha_iqk(hw, is2t); + if (patha_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path A IQK Success!!\n")); + result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) { + /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path A IQK Only Tx Success!!\n")); + + result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & + 0x3FF0000) >> 16; + } + } + if (0x00 == patha_ok) + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK failed!!\n")); + if (is2t) { + _rtl92d_phy_patha_standby(hw); + /* Turn Path B ADDA on */ + _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl92d_phy_pathb_iqk(hw); + if (pathb_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path B IQK Success!!\n")); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, + BMASKDWORD) & 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, + BMASKDWORD) & 0x3FF0000) >> 16; + result[t][6] = (rtl_get_bbreg(hw, 0xec4, + BMASKDWORD) & 0x3FF0000) >> 16; + result[t][7] = (rtl_get_bbreg(hw, 0xecc, + BMASKDWORD) & 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path B Only Tx IQK Success!!\n")); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, + BMASKDWORD) & 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, + BMASKDWORD) & 0x3FF0000) >> 16; + } + } + if (0x00 == pathb_ok) + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path B IQK failed!!\n")); + } + + /* Back to BB mode, load original value */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("IQK:Back to BB mode, load original value!\n")); + + rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); + if (t != 0) { + /* Switch back BB to SI mode after finish IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, false); + /* Reload ADDA power saving parameters */ + _rtl92d_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, IQK_ADDA_REG_NUM); + /* Reload MAC parameters */ + _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + if (is2t) + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + /* load 0xe30 IQC default value */ + rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00); + rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); +} + +static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, + long result[][8], u8 t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 patha_ok, pathb_ok; + static u32 adda_reg[IQK_ADDA_REG_NUM] = { + RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + static u32 iqk_bb_reg[IQK_BB_REG_NUM] = { + RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE, + RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR, + RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE, + RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4, + ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1 + }; + u32 bbvalue; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + + /* Note: IQ calibration must be performed after loading + * PHY_REG.txt , and radio_a, radio_b.txt */ + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n")); + udelay(IQK_DELAY_TIME * 1000 * 20); + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", + (is2t ? "2T2R" : "1T1R"))); + /* Save ADDA parameters, turn Path A ADDA on */ + _rtl92d_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + if (is2t) + _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + } + _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t); + /* MAC settings */ + _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + if (t == 0) + rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, BIT(8)); + /* Switch BB to PI mode to do IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, true); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22208000); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f); + + /* Page B init */ + rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); + /* IQ calibration setting */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00); + rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); + patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t); + if (patha_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Success!!\n")); + result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) & + 0x3FF0000) >> 16; + } else if (patha_ok == 0x01) { /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path A IQK Only Tx Success!!\n")); + + result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & + 0x3FF0000) >> 16; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Fail!!\n")); + } + if (is2t) { + /* _rtl92d_phy_patha_standby(hw); */ + /* Turn Path B ADDA on */ + _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t); + pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw); + if (pathb_ok == 0x03) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path B IQK Success!!\n")); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = (rtl_get_bbreg(hw, 0xec4, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = (rtl_get_bbreg(hw, 0xecc, BMASKDWORD) & + 0x3FF0000) >> 16; + } else if (pathb_ok == 0x01) { /* Tx IQK OK */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path B Only Tx IQK Success!!\n")); + result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & + 0x3FF0000) >> 16; + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path B IQK failed!!\n")); + } + } + + /* Back to BB mode, load original value */ + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("IQK:Back to BB mode, load original value!\n")); + rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); + if (t != 0) { + if (is2t) + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM); + else + _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, + IQK_BB_REG_NUM - 1); + /* Reload MAC parameters */ + _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + /* Switch back BB to SI mode after finish IQ Calibration. */ + if (!rtlphy->rfpi_enable) + _rtl92d_phy_pimode_switch(hw, false); + /* Reload ADDA power saving parameters */ + _rtl92d_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, + IQK_ADDA_REG_NUM); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); +} + +static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 i, j, diff, sim_bitmap, bound; + u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ + bool bresult = true; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version); + + if (is2t) + bound = 8; + else + bound = 4; + sim_bitmap = 0; + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - + result[c2][i]) : (result[c2][i] - result[c1][i]); + if (diff > MAX_TOLERANCE_92D) { + if ((i == 2 || i == 6) && !sim_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + sim_bitmap = sim_bitmap | (1 << i); + } else { + sim_bitmap = sim_bitmap | (1 << i); + } + } + } + if (sim_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } + if (!(sim_bitmap & 0x0F)) { /* path A OK */ + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + } else if (!(sim_bitmap & 0x03)) { /* path A, Tx OK */ + for (i = 0; i < 2; i++) + result[3][i] = result[c1][i]; + } + if (!(sim_bitmap & 0xF0) && is2t) { /* path B OK */ + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + } else if (!(sim_bitmap & 0x30)) { /* path B, Tx OK */ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + return false; +} + +static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], + u8 final_candidate, bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 oldval_0, val_x, tx0_a, reg; + long val_y, tx0_c; + bool is2t = IS_92D_SINGLEPHY(rtlhal->version) || + rtlhal->macphymode == DUALMAC_DUALPHY; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("Path A IQ Calibration %s !\n", + (iqk_ok) ? "Success" : "Failed")); + if (final_candidate == 0xFF) { + return; + } else if (iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD) >> 22) & 0x3FF; /* OFDM0_D */ + val_x = result[final_candidate][0]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + tx0_a = (val_x * oldval_0) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx0_a = 0x%x," + " oldval_0 0x%x\n", val_x, tx0_a, oldval_0)); + rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), + ((val_x * oldval_0 >> 7) & 0x1)); + val_y = result[final_candidate][1]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + /* path B IQK result + 3 */ + if (rtlhal->interfaceindex == 1 && + rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + tx0_c = (val_y * oldval_0) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx0_c = 0x%lx\n", + val_y, tx0_c)); + rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + if (is2t) + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), + ((val_y * oldval_0 >> 7) & 0x1)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xC80 = 0x%x\n", + rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD))); + if (txonly) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("only Tx OK\n")); + return; + } + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} + +static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], u8 final_candidate, bool txonly) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 oldval_1, val_x, tx1_a, reg; + long val_y, tx1_c; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n", + (iqk_ok) ? "Success" : "Failed")); + if (final_candidate == 0xFF) { + return; + } else if (iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, + BMASKDWORD) >> 22) & 0x3FF; + val_x = result[final_candidate][4]; + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + tx1_a = (val_x * oldval_1) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx1_a = 0x%x\n", + val_x, tx1_a)); + rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), + ((val_x * oldval_1 >> 7) & 0x1)); + val_y = result[final_candidate][5]; + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + if (rtlhal->current_bandtype == BAND_ON_5G) + val_y += 3; + tx1_c = (val_y * oldval_1) >> 8; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx1_c = 0x%lx\n", + val_y, tx1_c)); + rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30), + ((val_y * oldval_1 >> 7) & 0x1)); + if (txonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); + } +} + +void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + long result[4][8]; + u8 i, final_candidate, indexforchannel; + bool patha_ok, pathb_ok; + long rege94, rege9c, regea4, regeac, regeb4; + long regebc, regec4, regecc, regtmp = 0; + bool is12simular, is13simular, is23simular; + unsigned long flag = 0; + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("IQK:Start!!!channel %d\n", rtlphy->current_channel)); + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + patha_ok = false; + pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("IQK !!!currentband %d\n", rtlhal->current_bandtype)); + rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); + for (i = 0; i < 3; i++) { + if (rtlhal->current_bandtype == BAND_ON_5G) { + _rtl92d_phy_iq_calibrate_5g_normal(hw, result, i); + } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (IS_92D_SINGLEPHY(rtlhal->version)) + _rtl92d_phy_iq_calibrate(hw, result, i, true); + else + _rtl92d_phy_iq_calibrate(hw, result, i, false); + } + if (i == 1) { + is12simular = _rtl92d_phy_simularity_compare(hw, result, + 0, 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = _rtl92d_phy_simularity_compare(hw, result, + 0, 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl92d_phy_simularity_compare(hw, result, + 1, 2); + if (is23simular) { + final_candidate = 1; + } else { + for (i = 0; i < 8; i++) + regtmp += result[3][i]; + + if (regtmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + rtl92d_release_cckandrw_pagea_ctl(hw, &flag); + for (i = 0; i < 4; i++) { + rege94 = result[i][0]; + rege9c = result[i][1]; + regea4 = result[i][2]; + regeac = result[i][3]; + regeb4 = result[i][4]; + regebc = result[i][5]; + regec4 = result[i][6]; + regecc = result[i][7]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " + "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, + regecc)); + } + if (final_candidate != 0xff) { + rtlphy->reg_e94 = rege94 = result[final_candidate][0]; + rtlphy->reg_e9c = rege9c = result[final_candidate][1]; + regea4 = result[final_candidate][2]; + regeac = result[final_candidate][3]; + rtlphy->reg_eb4 = regeb4 = result[final_candidate][4]; + rtlphy->reg_ebc = regebc = result[final_candidate][5]; + regec4 = result[final_candidate][6]; + regecc = result[final_candidate][7]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("IQK: final_candidate is %x\n", final_candidate)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " + "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, + regecc)); + patha_ok = pathb_ok = true; + } else { + rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */ + rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; /* Y default value */ + } + if ((rege94 != 0) /*&&(regea4 != 0) */) + _rtl92d_phy_patha_fill_iqk_matrix(hw, patha_ok, result, + final_candidate, (regea4 == 0)); + if (IS_92D_SINGLEPHY(rtlhal->version)) { + if ((regeb4 != 0) /*&&(regec4 != 0) */) + _rtl92d_phy_pathb_fill_iqk_matrix(hw, pathb_ok, result, + final_candidate, (regec4 == 0)); + } + if (final_candidate != 0xFF) { + indexforchannel = rtl92d_get_rightchnlplace_for_iqk( + rtlphy->current_channel); + + for (i = 0; i < IQK_MATRIX_REG_NUM; i++) + rtlphy->iqk_matrix_regsetting[indexforchannel]. + value[0][i] = result[final_candidate][i]; + rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done = + true; + + RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD, + ("\nIQK OK indexforchannel %d.\n", indexforchannel)); + } +} + +void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 indexforchannel; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("channel %d\n", channel)); + /*------Do IQK for normal chip and test chip 5G band------- */ + indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("indexforchannel %d done %d\n", indexforchannel, + rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done)); + if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done && + rtlphy->need_iqk) { + /* Re Do IQK. */ + RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD, + ("Do IQK Matrix reg for channel:%d....\n", channel)); + rtl92d_phy_iq_calibrate(hw); + } else { + /* Just load the value. */ + /* 2G band just load once. */ + if (((!rtlhal->load_imrandiqk_setting_for2g) && + indexforchannel == 0) || indexforchannel > 0) { + RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, + ("Just Read IQK Matrix reg for channel:%d" + "....\n", channel)); + if ((rtlphy->iqk_matrix_regsetting[indexforchannel]. + value[0] != NULL) + /*&&(regea4 != 0) */) + _rtl92d_phy_patha_fill_iqk_matrix(hw, true, + rtlphy->iqk_matrix_regsetting[ + indexforchannel].value, 0, + (rtlphy->iqk_matrix_regsetting[ + indexforchannel].value[0][2] == 0)); + if (IS_92D_SINGLEPHY(rtlhal->version)) { + if ((rtlphy->iqk_matrix_regsetting[ + indexforchannel].value[0][4] != 0) + /*&&(regec4 != 0) */) + _rtl92d_phy_pathb_fill_iqk_matrix(hw, + true, + rtlphy->iqk_matrix_regsetting[ + indexforchannel].value, 0, + (rtlphy->iqk_matrix_regsetting[ + indexforchannel].value[0][6] + == 0)); + } + } + } + rtlphy->need_iqk = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); +} + +static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2) +{ + u32 ret; + + if (val1 >= val2) + ret = val1 - val2; + else + ret = val2 - val1; + return ret; +} + +static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel) +{ + + int i; + u8 channel_5g[45] = { + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, + 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, + 161, 163, 165 + }; + + for (i = 0; i < sizeof(channel_5g); i++) + if (channel == channel_5g[i]) + return true; + return false; +} + +static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw, + u32 *targetchnl, u32 * curvecount_val, + bool is5g, u32 *curveindex) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 smallest_abs_val = 0xffffffff, u4tmp; + u8 i, j; + u8 chnl_num = is5g ? TARGET_CHNL_NUM_5G : TARGET_CHNL_NUM_2G; + + for (i = 0; i < chnl_num; i++) { + if (is5g && !_rtl92d_is_legal_5g_channel(hw, i + 1)) + continue; + curveindex[i] = 0; + for (j = 0; j < (CV_CURVE_CNT * 2); j++) { + u4tmp = _rtl92d_phy_get_abs(targetchnl[i], + curvecount_val[j]); + + if (u4tmp < smallest_abs_val) { + curveindex[i] = j; + smallest_abs_val = u4tmp; + } + } + smallest_abs_val = 0xffffffff; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("curveindex[%d] = %x\n", i, + curveindex[i])); + } +} + +static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 erfpath = rtlpriv->rtlhal.current_bandtype == + BAND_ON_5G ? RF90_PATH_A : + IS_92D_SINGLEPHY(rtlpriv->rtlhal.version) ? + RF90_PATH_B : RF90_PATH_A; + u32 u4tmp = 0, u4regvalue = 0; + bool bneed_powerdown_radio = false; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("path %d\n", erfpath)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n", + rtlpriv->rtlhal.current_bandtype)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel)); + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ + u4tmp = curveindex_5g[channel-1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp)); + if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && + rtlpriv->rtlhal.interfaceindex == 1) { + bneed_powerdown_radio = + rtl92d_phy_enable_anotherphy(hw, false); + rtlpriv->rtlhal.during_mac1init_radioa = true; + /* asume no this case */ + if (bneed_powerdown_radio) + _rtl92d_phy_enable_rf_env(hw, erfpath, + &u4regvalue); + } + rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); + if (bneed_powerdown_radio) + _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); + if (rtlpriv->rtlhal.during_mac1init_radioa) + rtl92d_phy_powerdown_anotherphy(hw, false); + } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { + u4tmp = curveindex_2g[channel-1]; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp)); + if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && + rtlpriv->rtlhal.interfaceindex == 0) { + bneed_powerdown_radio = + rtl92d_phy_enable_anotherphy(hw, true); + rtlpriv->rtlhal.during_mac0init_radiob = true; + if (bneed_powerdown_radio) + _rtl92d_phy_enable_rf_env(hw, erfpath, + &u4regvalue); + } + rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", + rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800))); + if (bneed_powerdown_radio) + _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); + if (rtlpriv->rtlhal.during_mac0init_radiob) + rtl92d_phy_powerdown_anotherphy(hw, true); + } + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); +} + +static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 tmpreg, index, rf_mode[2]; + u8 path = is2t ? 2 : 1; + u8 i; + u32 u4tmp, offset; + u32 curvecount_val[CV_CURVE_CNT * 2] = {0}; + u16 timeout = 800, timecount = 0; + + /* Check continuous TX and Packet TX */ + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + /* if Deal with contisuous TX case, disable all continuous TX */ + /* if Deal with Packet TX case, block all queues */ + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x0F); + for (index = 0; index < path; index++) { + /* 1. Read original RF mode */ + offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1; + rf_mode[index] = rtl_read_byte(rtlpriv, offset); + /* 2. Set RF mode = standby mode */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_AC, + BRFREGOFFSETMASK, 0x010000); + if (rtlpci->init_ready) { + /* switch CV-curve control by LC-calibration */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, + BIT(17), 0x0); + /* 4. Set LC calibration begin */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, + 0x08000, 0x01); + } + u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6, + BRFREGOFFSETMASK); + while ((!(u4tmp & BIT(11))) && timecount <= timeout) { + mdelay(50); + timecount += 50; + u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, + RF_SYN_G6, BRFREGOFFSETMASK); + } + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_LCK finish delay for %d ms=2\n", timecount)); + u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK); + if (index == 0 && rtlhal->interfaceindex == 0) { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("path-A / 5G LCK\n")); + } else { + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("path-B / 2.4G LCK\n")); + } + memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2); + /* Set LC calibration off */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, + 0x08000, 0x0); + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("set RF 0x18[15] = 0\n")); + /* save Curve-counting number */ + for (i = 0; i < CV_CURVE_CNT; i++) { + u32 readval = 0, readval2 = 0; + rtl_set_rfreg(hw, (enum radio_path)index, 0x3F, + 0x7f, i); + + rtl_set_rfreg(hw, (enum radio_path)index, 0x4D, + BRFREGOFFSETMASK, 0x0); + readval = rtl_get_rfreg(hw, (enum radio_path)index, + 0x4F, BRFREGOFFSETMASK); + curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5; + /* reg 0x4f [4:0] */ + /* reg 0x50 [19:10] */ + readval2 = rtl_get_rfreg(hw, (enum radio_path)index, + 0x50, 0xffc00); + curvecount_val[2 * i] = (((readval & 0x1F) << 10) | + readval2); + } + if (index == 0 && rtlhal->interfaceindex == 0) + _rtl92d_phy_calc_curvindex(hw, targetchnl_5g, + curvecount_val, + true, curveindex_5g); + else + _rtl92d_phy_calc_curvindex(hw, targetchnl_2g, + curvecount_val, + false, curveindex_2g); + /* switch CV-curve control mode */ + rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, + BIT(17), 0x1); + } + + /* Restore original situation */ + for (index = 0; index < path; index++) { + offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1; + rtl_write_byte(rtlpriv, offset, 0x50); + rtl_write_byte(rtlpriv, offset, rf_mode[index]); + } + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + else /*Deal with Packet TX case */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x00); + _rtl92d_phy_reload_lck_setting(hw, rtlpriv->phy.current_channel); +} + +static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa PHY_LCK ver=2\n")); + _rtl92d_phy_lc_calibrate_sw(hw, is2t); +} + +void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 timeout = 2000, timecount = 0; + + while (rtlpriv->mac80211.act_scanning && timecount < timeout) { + udelay(50); + timecount += 50; + } + + rtlphy->lck_inprogress = true; + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount)); + if (IS_92D_SINGLEPHY(rtlhal->version)) { + _rtl92d_phy_lc_calibrate(hw, true); + } else { + /* For 1T1R */ + _rtl92d_phy_lc_calibrate(hw, false); + } + rtlphy->lck_inprogress = false; + RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LCK:Finish!!!\n")); +} + +void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) +{ + return; +} + +static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + return false; + } + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 i; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("settings regs %d default regs %d\n", + (int)(sizeof(rtlphy->iqk_matrix_regsetting) / + sizeof(struct iqk_matrix_regs)), + IQK_MATRIX_REG_NUM)); + /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */ + for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { + rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100; + rtlphy->iqk_matrix_regsetting[i].value[0][2] = 0x100; + rtlphy->iqk_matrix_regsetting[i].value[0][4] = 0x100; + rtlphy->iqk_matrix_regsetting[i].value[0][6] = 0x100; + rtlphy->iqk_matrix_regsetting[i].value[0][1] = 0x0; + rtlphy->iqk_matrix_regsetting[i].value[0][3] = 0x0; + rtlphy->iqk_matrix_regsetting[i].value[0][5] = 0x0; + rtlphy->iqk_matrix_regsetting[i].value[0][7] = 0x0; + rtlphy->iqk_matrix_regsetting[i].iqk_done = false; + } +} + +static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + postcommoncmdcnt = 0; + _rtl92d_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + rfdependcmdcnt = 0; + _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 0); + _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, + 0, 0, 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + } + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92d_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16)currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8)currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xffffff00) | currentcmd->para2); + if (rtlpriv->rtlhal.current_bandtype == + BAND_ON_5G) { + if (currentcmd->para2 > 99) + rtlphy->rfreg_chnlval[rfpath] = + rtlphy->rfreg_chnlval + [rfpath] | (BIT(18)); + else + rtlphy->rfreg_chnlval[rfpath] = + rtlphy->rfreg_chnlval + [rfpath] & (~BIT(18)); + rtlphy->rfreg_chnlval[rfpath] |= + (BIT(16) | BIT(8)); + } else { + rtlphy->rfreg_chnlval[rfpath] &= + ~(BIT(8) | BIT(16) | BIT(18)); + } + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + BRFREGOFFSETMASK, + rtlphy->rfreg_chnlval[rfpath]); + _rtl92d_phy_reload_imr_setting(hw, channel, + rfpath); + } + _rtl92d_phy_switch_rf_setting(hw, channel); + /* do IQK when all parameters are ready */ + rtl92d_phy_reload_iqk_setting(hw, channel); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + break; + } while (true); + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 delay; + u32 timeout = 1000, timecount = 0; + u8 channel = rtlphy->current_channel; + u32 ret_value; + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + ("sw_chnl_inprogress false driver sleep or unload\n")); + return 0; + } + while (rtlphy->lck_inprogress && timecount < timeout) { + mdelay(50); + timecount += 50; + } + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && + rtlhal->bandset == BAND_ON_BOTH) { + ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + BMASKDWORD); + if (rtlphy->current_channel > 14 && !(ret_value & BIT(0))) + rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G); + else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0))) + rtl92d_phy_switch_wirelessband(hw, BAND_ON_2_4G); + } + switch (rtlhal->current_bandtype) { + case BAND_ON_5G: + /* Get first channel error when change between + * 5G and 2.4G band. */ + if (channel <= 14) + return 0; + RT_ASSERT((channel > 14), ("5G but channel<=14")); + break; + case BAND_ON_2_4G: + /* Get first channel error when change between + * 5G and 2.4G band. */ + if (channel > 14) + return 0; + RT_ASSERT((channel <= 14), ("2G but channel>14")); + break; + default: + RT_ASSERT(false, + ("Invalid WirelessMode(%#x)!!\n", + rtlpriv->mac80211.mode)); + break; + } + rtlphy->sw_chnl_inprogress = true; + if (channel == 0) + channel = 1; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("switch to channel%d\n", rtlphy->current_channel)); + + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl92d_phy_sw_chnl_step_by_step(hw, + rtlphy->current_channel, + &rtlphy->sw_chnl_stage, &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else { + rtlphy->sw_chnl_inprogress = false; + } + break; + } while (true); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + rtlphy->sw_chnl_inprogress = false; + return 1; +} + +static void rtl92d_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress)); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; + rtl92d_dm_write_dig(hw); + rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; + dm_digtable.cur_igvalue = 0x17; + rtl92d_dm_write_dig(hw); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + rtlphy->set_io_inprogress = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("<---(%#x)\n", rtlphy->current_io_type)); +} + +bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool postprocessing = false; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress)); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Resume DM after scan.\n")); + postprocessing = true; + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Pause DM before scan.\n")); + postprocessing = true; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl92d_phy_set_io(hw); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + return true; +} + +static void _rtl92d_phy_set_rfon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* a. SYS_CLKR 0x08[11] = 1 restore MAC clock */ + /* b. SPS_CTRL 0x11[7:0] = 0x2b */ + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + /* c. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + /* RF_ON_EXCEP(d~g): */ + /* d. APSD_CTRL 0x600[7:0] = 0x00 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + /* e. SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function again */ + /* f. SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function*/ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + /* g. txpause 0x522[7:0] = 0x00 enable mac tx queue */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 u4btmp; + u8 delay = 5; + + /* a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */ + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + /* b. RF path 0 offset 0x00 = 0x00 disable RF */ + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); + /* c. APSD_CTRL 0x600[7:0] = 0x40 */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + /* d. APSD_CTRL 0x600[7:0] = 0x00 + * APSD_CTRL 0x600[7:0] = 0x00 + * RF path 0 offset 0x00 = 0x00 + * APSD_CTRL 0x600[7:0] = 0x40 + * */ + u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK); + while (u4btmp != 0 && delay > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK); + delay--; + } + if (delay == 0) { + /* Jump out the LPS turn off sequence to RF_ON_EXCEP */ + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Fail !!! Switch RF timeout.\n")); + return; + } + /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + /* f. SPS_CTRL 0x11[7:0] = 0x22 */ + if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); + /* g. SYS_CLKR 0x08[11] = 0 gated MAC clock */ +} + +bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + + bool bresult = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + if (rfpwr_state == ppsc->rfpwr_state) + return false; + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 InitializeCount = 0; + do { + InitializeCount++; + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic enable\n")); + rtstatus = rtl_ps_enable_nic(hw); + } while ((rtstatus != true) && + (InitializeCount < 10)); + + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + ("awake, sleeped:%d ms state_" + "inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap)); + ppsc->last_awake_jiffies = jiffies; + _rtl92d_phy_set_rfon(hw); + } + + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + break; + case ERFOFF: + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic disable\n")); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + else + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + break; + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + break; + + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0 || + queue_id == BEACON_QUEUE) { + queue_id++; + continue; + } else if (rtlpci->pdev->current_state != PCI_D0) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("eRf Off/Sleep: %d times TcbBusyQueu" + "e[%d] !=0 but lower power state!\n", + (i + 1), queue_id)); + break; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("eRf Off/Sleep: %d times TcbBusyQueu" + "e[%d] =%d " + "before doze!\n", (i + 1), queue_id, + skb_queue_len(&ring->queue))); + udelay(10); + i++; + } + + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("\nERFOFF: %d times TcbBusyQueue[%d] " + "= %d !\n", + MAX_DOZE_WAITING_TIMES_9x, queue_id, + skb_queue_len(&ring->queue))); + break; + } + } + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + ("Set rfsleep awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies))); + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("sleep awaked:%d ms " + "state_inap:%x\n", jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), rtlpriv->psc.state_inap)); + ppsc->last_sleep_jiffies = jiffies; + _rtl92d_phy_set_rfsleep(hw); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 offset = REG_MAC_PHY_CTRL_NORMAL; + + switch (rtlhal->macphymode) { + case DUALMAC_DUALPHY: + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("MacPhyMode: DUALMAC_DUALPHY\n")); + rtl_write_byte(rtlpriv, offset, 0xF3); + break; + case SINGLEMAC_SINGLEPHY: + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("MacPhyMode: SINGLEMAC_SINGLEPHY\n")); + rtl_write_byte(rtlpriv, offset, 0xF4); + break; + case DUALMAC_SINGLEPHY: + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("MacPhyMode: DUALMAC_SINGLEPHY\n")); + rtl_write_byte(rtlpriv, offset, 0xF1); + break; + } +} + +void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (rtlhal->macphymode) { + case DUALMAC_SINGLEPHY: + rtlphy->rf_type = RF_2T2R; + rtlhal->version |= CHIP_92D_SINGLEPHY; + rtlhal->bandset = BAND_ON_BOTH; + rtlhal->current_bandtype = BAND_ON_2_4G; + break; + + case SINGLEMAC_SINGLEPHY: + rtlphy->rf_type = RF_2T2R; + rtlhal->version |= CHIP_92D_SINGLEPHY; + rtlhal->bandset = BAND_ON_BOTH; + rtlhal->current_bandtype = BAND_ON_2_4G; + break; + + case DUALMAC_DUALPHY: + rtlphy->rf_type = RF_1T1R; + rtlhal->version &= (~CHIP_92D_SINGLEPHY); + /* Now we let MAC0 run on 5G band. */ + if (rtlhal->interfaceindex == 0) { + rtlhal->bandset = BAND_ON_5G; + rtlhal->current_bandtype = BAND_ON_5G; + } else { + rtlhal->bandset = BAND_ON_2_4G; + rtlhal->current_bandtype = BAND_ON_2_4G; + } + break; + default: + break; + } +} + +u8 rtl92d_get_chnlgroup_fromarray(u8 chnl) +{ + u8 group; + u8 channel_info[59] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, + 58, 60, 62, 64, 100, 102, 104, 106, 108, + 110, 112, 114, 116, 118, 120, 122, 124, + 126, 128, 130, 132, 134, 136, 138, 140, + 149, 151, 153, 155, 157, 159, 161, 163, + 165 + }; + + if (channel_info[chnl] <= 3) + group = 0; + else if (channel_info[chnl] <= 9) + group = 1; + else if (channel_info[chnl] <= 14) + group = 2; + else if (channel_info[chnl] <= 44) + group = 3; + else if (channel_info[chnl] <= 54) + group = 4; + else if (channel_info[chnl] <= 64) + group = 5; + else if (channel_info[chnl] <= 112) + group = 6; + else if (channel_info[chnl] <= 126) + group = 7; + else if (channel_info[chnl] <= 140) + group = 8; + else if (channel_info[chnl] <= 153) + group = 9; + else if (channel_info[chnl] <= 159) + group = 10; + else + group = 11; + return group; +} + +void rtl92d_phy_set_poweron(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + unsigned long flags; + u8 value8; + u16 i; + u32 mac_reg = (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1); + + /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + value8 = rtl_read_byte(rtlpriv, mac_reg); + value8 |= BIT(1); + rtl_write_byte(rtlpriv, mac_reg, value8); + } else { + value8 = rtl_read_byte(rtlpriv, mac_reg); + value8 &= (~BIT(1)); + rtl_write_byte(rtlpriv, mac_reg, value8); + } + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) { + value8 = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON); + } else { + spin_lock_irqsave(&globalmutex_power, flags); + if (rtlhal->interfaceindex == 0) { + value8 = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON); + } else { + value8 = rtl_read_byte(rtlpriv, REG_MAC1); + rtl_write_byte(rtlpriv, REG_MAC1, value8 | MAC1_ON); + } + value8 = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + spin_unlock_irqrestore(&globalmutex_power, flags); + for (i = 0; i < 200; i++) { + if ((value8 & BIT(7)) == 0) { + break; + } else { + udelay(500); + spin_lock_irqsave(&globalmutex_power, flags); + value8 = rtl_read_byte(rtlpriv, + REG_POWER_OFF_IN_PROCESS); + spin_unlock_irqrestore(&globalmutex_power, + flags); + } + } + if (i == 200) + RT_ASSERT(false, ("Another mac power off over time\n")); + } +} + +void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (rtlpriv->rtlhal.macphymode) { + case DUALMAC_DUALPHY: + rtl_write_byte(rtlpriv, REG_DMC, 0x0); + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08); + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff); + break; + case DUALMAC_SINGLEPHY: + rtl_write_byte(rtlpriv, REG_DMC, 0xf8); + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08); + rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff); + break; + case SINGLEMAC_SINGLEPHY: + rtl_write_byte(rtlpriv, REG_DMC, 0x0); + rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x10); + rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF); + break; + default: + break; + } +} + +void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rfpath, i; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* r_select_5G for path_A/B,0x878 */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x0); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x0); + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x0); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x0); + } + /* rssi_table_select:index 0 for 2.4G.1~3 for 5G,0xc78 */ + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x0); + /* fc_area 0xd2c */ + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x0); + /* 5G LAN ON */ + rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa); + /* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */ + rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, + 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, + 0x40000100); + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) | + (rtlefuse->eeprom_c9 & BIT(1)) | + ((rtlefuse->eeprom_cc & BIT(1)) << 4)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) | + ((rtlefuse->eeprom_c9 & BIT(0)) << 1) | + ((rtlefuse->eeprom_cc & BIT(0)) << 5)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(26) | BIT(22) | BIT(21) | BIT(10) | + BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) | + (rtlefuse->eeprom_c9 & BIT(1)) | + ((rtlefuse->eeprom_cc & BIT(1)) << 4) | + ((rtlefuse->eeprom_c9 & BIT(7)) << 9) | + ((rtlefuse->eeprom_c9 & BIT(5)) << 12) | + ((rtlefuse->eeprom_cc & BIT(3)) << 18)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) | + ((rtlefuse->eeprom_c9 & BIT(0)) << 1) | + ((rtlefuse->eeprom_cc & BIT(0)) << 5)); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(10) | BIT(6) | BIT(5), + ((rtlefuse->eeprom_c9 & BIT(6)) >> 6) | + ((rtlefuse->eeprom_c9 & BIT(4)) >> 3) | + ((rtlefuse->eeprom_cc & BIT(2)) << 3)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + BIT(31) | BIT(15), 0); + } + /* 1.5V_LDO */ + } else { + /* r_select_5G for path_A/B */ + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x1); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x1); + if (rtlhal->macphymode != DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x1); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x1); + } + /* rssi_table_select:index 0 for 2.4G.1~3 for 5G */ + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x1); + /* fc_area */ + rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x1); + /* 5G LAN ON */ + rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0); + /* TX BB gain shift,Just for testchip,0xc80,0xc88 */ + if (rtlefuse->internal_pa_5g[0]) + rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, + 0x2d4000b5); + else + rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, + 0x20000080); + if (rtlefuse->internal_pa_5g[1]) + rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, + 0x2d4000b5); + else + rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, + 0x20000080); + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(10) | BIT(6) | BIT(5), + (rtlefuse->eeprom_cc & BIT(5))); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), + (rtlefuse->eeprom_cc & BIT(4)) >> 4); + } else { + rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, + BIT(26) | BIT(22) | BIT(21) | BIT(10) | + BIT(6) | BIT(5), + (rtlefuse->eeprom_cc & BIT(5)) | + ((rtlefuse->eeprom_cc & BIT(7)) << 14)); + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4)); + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), + ((rtlefuse->eeprom_cc & BIT(6)) >> 6)); + rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, + BIT(31) | BIT(15), + ((rtlefuse->eeprom_cc & BIT(4)) >> 4) | + ((rtlefuse->eeprom_cc & BIT(6)) << 10)); + } + } + /* update IQK related settings */ + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, BMASKDWORD, 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, BMASKDWORD, 0x40000100); + rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) | + BIT(26) | BIT(24), 0x00); + rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, 0x00); + rtl_set_bbreg(hw, 0xca0, 0xF0000000, 0x00); + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, 0x00); + + /* Update RF */ + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */ + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | BIT(16) | + BIT(18), 0); + /* RF0x0b[16:14] =3b'111 */ + rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, + 0x1c000, 0x07); + } else { + /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */ + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | + BIT(16) | BIT(18), + (BIT(16) | BIT(8)) >> 8); + } + } + /* Update for all band. */ + /* DMDP */ + if (rtlphy->rf_type == RF_1T1R) { + /* Use antenna 0,0xc04,0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x11); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1); + + /* enable ad/da clock1 for dual-phy reg0x888 */ + if (rtlhal->interfaceindex == 0) { + rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | + BIT(13), 0x3); + } else { + rtl92d_phy_enable_anotherphy(hw, false); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("MAC1 use DBI to update 0x888")); + /* 0x888 */ + rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN, + rtl92de_read_dword_dbi(hw, + RFPGA0_ADDALLOCKEN, + BIT(3)) | BIT(12) | BIT(13), + BIT(3)); + rtl92d_phy_powerdown_anotherphy(hw, false); + } + } else { + /* Single PHY */ + /* Use antenna 0 & 1,0xc04,0xd04 */ + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x33); + rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3); + /* disable ad/da clock1,0x888 */ + rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0); + } + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath, + RF_CHNLBW, BRFREGOFFSETMASK); + rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C, + BRFREGOFFSETMASK); + } + for (i = 0; i < 2; i++) + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[i])); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==\n")); + +} + +bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 u1btmp; + unsigned long flags; + + if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON)); + return true; + } + spin_lock_irqsave(&globalmutex_power, flags); + if (rtlhal->interfaceindex == 0) { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON)); + u1btmp = rtl_read_byte(rtlpriv, REG_MAC1); + u1btmp &= MAC1_ON; + } else { + u1btmp = rtl_read_byte(rtlpriv, REG_MAC1); + rtl_write_byte(rtlpriv, REG_MAC1, u1btmp & (~MAC1_ON)); + u1btmp = rtl_read_byte(rtlpriv, REG_MAC0); + u1btmp &= MAC0_ON; + } + if (u1btmp) { + spin_unlock_irqrestore(&globalmutex_power, flags); + return false; + } + u1btmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); + u1btmp |= BIT(7); + rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1btmp); + spin_unlock_irqrestore(&globalmutex_power, flags); + return true; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h new file mode 100644 index 00000000000..a52c824b41e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h @@ -0,0 +1,178 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92D_PHY_H__ +#define __RTL92D_PHY_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define IQK_ADDA_REG_NUM 16 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNA_DIVERSITY_VALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 10 +#define IQK_BB_REG_NUM_test 6 +#define IQK_MAC_REG_NUM 4 +#define RX_INDEX_MAPPING_NUM 15 + +#define IQK_DELAY_TIME 1 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum rf_content { + radioa_txt = 0, + radiob_txt = 1, + radioc_txt = 2, + radiod_txt = 3 +}; + +static inline void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.interfaceindex == 1) + spin_lock_irqsave(&rtlpriv->locks.cck_and_rw_pagea_lock, *flag); +} + +static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.interfaceindex == 1) + spin_unlock_irqrestore(&rtlpriv->locks.cck_and_rw_pagea_lock, + *flag); +} + +extern u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +extern void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +extern u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +extern bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); +extern bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); +extern bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +extern void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +extern void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +extern void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +extern u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw); +bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum rf_content content, + enum radio_path rfpath); +bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +extern bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + +void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw); +void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw); +u8 rtl92d_get_chnlgroup_fromarray(u8 chnl); +void rtl92d_phy_set_poweron(struct ieee80211_hw *hw); +void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw); +bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw); +void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw); +void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw); +void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw); +void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag); +void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw, + unsigned long *flag); +u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl); +void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel); +void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw); + +#endif -- cgit v1.2.3-70-g09d2 From 3de1ef7304aeecbf666c02baacb173e08fa5cb43 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:10:40 -0500 Subject: rtlwifi: rtl8192de: Merge register definitions Merge routines reg.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/reg.h | 1313 ++++++++++++++++++++++++++ 1 file changed, 1313 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/reg.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h new file mode 100644 index 00000000000..131acc306fc --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h @@ -0,0 +1,1313 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92D_REG_H__ +#define __RTL92D_REG_H__ + +/* ----------------------------------------------------- */ +/* 0x0000h ~ 0x00FFh System Configuration */ +/* ----------------------------------------------------- */ +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_POWER_OFF_IN_PROCESS 0x0017 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +/* for 92d, DMDP,SMSP,DMSP contrl */ +#define REG_MAC_PHY_CTRL 0x002c +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 + +#define REG_MCUFWDL 0x0080 + +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_MAC_PHY_CTRL_NORMAL 0x00f8 + +#define REG_MAC0 0x0081 +#define REG_MAC1 0x0053 +#define FW_MAC0_READY 0x18 +#define FW_MAC1_READY 0x1A +#define MAC0_ON BIT(7) +#define MAC1_ON BIT(0) +#define MAC0_READY BIT(0) +#define MAC1_READY BIT(0) + +/* ----------------------------------------------------- */ +/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ +/* ----------------------------------------------------- */ +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_C2HEVT_CLEAR 0x01BF +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + + +/* ----------------------------------------------------- */ +/* 0x0200h ~ 0x027Fh TXDMA Configuration */ +/* ----------------------------------------------------- */ +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +/* ----------------------------------------------------- */ +/* 0x0280h ~ 0x02FFh RXDMA Configuration */ +/* ----------------------------------------------------- */ +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + +/* ----------------------------------------------------- */ +/* 0x0300h ~ 0x03FFh PCIe */ +/* ----------------------------------------------------- */ +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 +#define REG_BCNQ_DESA 0x0308 +#define REG_HQ_DESA 0x0310 +#define REG_MGQ_DESA 0x0318 +#define REG_VOQ_DESA 0x0320 +#define REG_VIQ_DESA 0x0328 +#define REG_BEQ_DESA 0x0330 +#define REG_BKQ_DESA 0x0338 +#define REG_RX_DESA 0x0340 +#define REG_DBI 0x0348 +#define REG_DBI_WDATA 0x0348 +#define REG_DBI_RDATA 0x034C +#define REG_DBI_CTRL 0x0350 +#define REG_DBI_FLAG 0x0352 +#define REG_MDIO 0x0354 +#define REG_DBG_SEL 0x0360 +#define REG_PCIE_HRPWM 0x0361 +#define REG_PCIE_HCPWM 0x0363 +#define REG_UART_CTRL 0x0364 +#define REG_UART_TX_DESA 0x0370 +#define REG_UART_RX_DESA 0x0378 + +/* ----------------------------------------------------- */ +/* 0x0400h ~ 0x047Fh Protocol Configuration */ +/* ----------------------------------------------------- */ +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 + + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_MULTI_BCNQ_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_LIFE_TIME 0x04C0 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_RTS_MAX_AGGR_NUM 0x04CB +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_EARLY_MODE_CONTROL 0x4D0 +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + +/* ----------------------------------------------------- */ +/* 0x0500h ~ 0x05FFh EDCA Configuration */ +/* ----------------------------------------------------- */ +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_USTIME_TSF 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_INIT_TSFTR 0x0564 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +/* Dual MAC Co-Existence Register */ +#define REG_DMC 0x05F0 + +/* ----------------------------------------------------- */ +/* 0x0600h ~ 0x07FFh WMAC Configuration */ +/* ----------------------------------------------------- */ +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + + +/* WMA, BA, CCX */ +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + + +/* Security */ +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +/* Power */ +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + + +/* ----------------------------------------------------- */ +/* Redifine 8192C register definition for compatibility */ +/* ----------------------------------------------------- */ +#define CR9346 REG_9346CR +#define MSR (REG_CR + 2) +#define ISR REG_HISR +#define TSFR REG_TSFTR + +#define MACIDR0 REG_MACID +#define MACIDR4 (REG_MACID + 4) + +#define PBP REG_PBP + +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + +/* ----------------------------------------------------- */ +/* 8192C (MSR) Media Status Register(Offset 0x4C, 8 bits)*/ +/* ----------------------------------------------------- */ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */ +/* ----------------------------------------------------- */ +/* 8192C Response Rate Set Register(offset 0x181, 24bits)*/ +/* ----------------------------------------------------- */ +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 +#define BRSR_ACKSHORTPMB BIT23 + +/* ----------------------------------------------------- */ +/* 8192C Rate Definition */ +/* ----------------------------------------------------- */ +/* CCK */ +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +/* OFDM */ +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +/* MCS 1 Spatial Stream */ +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +/* MCS 2 Spatial Stream */ +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +/* CCK */ +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +/* OFDM */ +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +/* MCS 1 Spatial Stream */ +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +/* MCS 2 Spatial Stream */ +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +/* ALL CCK Rate */ +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | \ + RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | \ + RATR_18M | RATR_24M | \ + RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ + RATR_MCS14 | RATR_MCS15) + +/* ----------------------------------------------------- */ +/* 8192C BW_OPMODE bits (Offset 0x203, 8bit) */ +/* ----------------------------------------------------- */ +#define BW_OPMODE_20MHZ BIT(2) +#define BW_OPMODE_5G BIT(1) +#define BW_OPMODE_11J BIT(0) + + +/* ----------------------------------------------------- */ +/* 8192C CAM Config Setting (offset 0x250, 1 byte) */ +/* ----------------------------------------------------- */ +#define CAM_VALID BIT(15) +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT(5) + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 +#define CAM_SMS4 0x6 + + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +/* 10. Power Save Control Registers (Offset: 0x0260 - 0x02DF) */ +#define WOW_PMEN BIT0 /* Power management Enable. */ +#define WOW_WOMEN BIT1 /* WoW function on or off. */ +#define WOW_MAGIC BIT2 /* Magic packet */ +#define WOW_UWF BIT3 /* Unicast Wakeup frame. */ + +/* 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F) */ +/* ----------------------------------------------------- */ +/* 8190 IMR/ISR bits (offset 0xfd, 8bits) */ +/* ----------------------------------------------------- */ +#define IMR8190_DISABLED 0x0 +#define IMR_BCNDMAINT6 BIT(31) +#define IMR_BCNDMAINT5 BIT(30) +#define IMR_BCNDMAINT4 BIT(29) +#define IMR_BCNDMAINT3 BIT(28) +#define IMR_BCNDMAINT2 BIT(27) +#define IMR_BCNDMAINT1 BIT(26) +#define IMR_BCNDOK8 BIT(25) +#define IMR_BCNDOK7 BIT(24) +#define IMR_BCNDOK6 BIT(23) +#define IMR_BCNDOK5 BIT(22) +#define IMR_BCNDOK4 BIT(21) +#define IMR_BCNDOK3 BIT(20) +#define IMR_BCNDOK2 BIT(19) +#define IMR_BCNDOK1 BIT(18) +#define IMR_TIMEOUT2 BIT(17) +#define IMR_TIMEOUT1 BIT(16) +#define IMR_TXFOVW BIT(15) +#define IMR_PSTIMEOUT BIT(14) +#define IMR_BcnInt BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_ATIMEND BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_TBDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_TBDER BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) + +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_C2HCMD BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_OCPINT BIT(1) +#define IMR_WLANOFF BIT(0) + +/* ----------------------------------------------------- */ +/* 8192C EFUSE */ +/* ----------------------------------------------------- */ +#define HWSET_MAX_SIZE 256 +#define EFUSE_MAX_SECTION 32 +#define EFUSE_REAL_CONTENT_LEN 512 + +/* ----------------------------------------------------- */ +/* 8192C EEPROM/EFUSE share register definition. */ +/* ----------------------------------------------------- */ +#define EEPROM_DEFAULT_TSSI 0x0 +#define EEPROM_DEFAULT_CRYSTALCAP 0x0 +#define EEPROM_DEFAULT_THERMALMETER 0x12 + +#define EEPROM_DEFAULT_TXPOWERLEVEL_2G 0x2C +#define EEPROM_DEFAULT_TXPOWERLEVEL_5G 0x22 + +#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 +/* HT20<->40 default Tx Power Index Difference */ +#define EEPROM_DEFAULT_HT20_DIFF 2 +/* OFDM Tx Power index diff */ +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x4 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + + +#define RTL8192_EEPROM_ID 0x8129 +#define EEPROM_WAPI_SUPPORT 0x78 + + +#define RTL8190_EEPROM_ID 0x8129 /* 0-1 */ +#define EEPROM_HPON 0x02 /* LDO settings.2-5 */ +#define EEPROM_CLK 0x06 /* Clock settings.6-7 */ +#define EEPROM_MAC_FUNCTION 0x08 /* SE Test mode.8 */ + +#define EEPROM_VID 0x28 /* SE Vendor ID.A-B */ +#define EEPROM_DID 0x2A /* SE Device ID. C-D */ +#define EEPROM_SVID 0x2C /* SE Vendor ID.E-F */ +#define EEPROM_SMID 0x2E /* SE PCI Subsystem ID. 10-11 */ + +#define EEPROM_MAC_ADDR 0x16 /* SEMAC Address. 12-17 */ +#define EEPROM_MAC_ADDR_MAC0_92D 0x55 +#define EEPROM_MAC_ADDR_MAC1_92D 0x5B + +/* 2.4G band Tx power index setting */ +#define EEPROM_CCK_TX_PWR_INX_2G 0x61 +#define EEPROM_HT40_1S_TX_PWR_INX_2G 0x67 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G 0x6D +#define EEPROM_HT20_TX_PWR_INX_DIFF_2G 0x70 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_2G 0x73 +#define EEPROM_HT40_MAX_PWR_OFFSET_2G 0x76 +#define EEPROM_HT20_MAX_PWR_OFFSET_2G 0x79 + +/*5GL channel 32-64 */ +#define EEPROM_HT40_1S_TX_PWR_INX_5GL 0x7C +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GL 0x82 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GL 0x85 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GL 0x88 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GL 0x8B +#define EEPROM_HT20_MAX_PWR_OFFSET_5GL 0x8E + +/* 5GM channel 100-140 */ +#define EEPROM_HT40_1S_TX_PWR_INX_5GM 0x91 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GM 0x97 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GM 0x9A +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GM 0x9D +#define EEPROM_HT40_MAX_PWR_OFFSET_5GM 0xA0 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GM 0xA3 + +/* 5GH channel 149-165 */ +#define EEPROM_HT40_1S_TX_PWR_INX_5GH 0xA6 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GH 0xAC +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GH 0xAF +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GH 0xB2 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GH 0xB5 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GH 0xB8 + +/* Map of supported channels. */ +#define EEPROM_CHANNEL_PLAN 0xBB +#define EEPROM_IQK_DELTA 0xBC +#define EEPROM_LCK_DELTA 0xBC +#define EEPROM_XTAL_K 0xBD /* [7:5] */ +#define EEPROM_TSSI_A_5G 0xBE +#define EEPROM_TSSI_B_5G 0xBF +#define EEPROM_TSSI_AB_5G 0xC0 +#define EEPROM_THERMAL_METER 0xC3 /* [4:0] */ +#define EEPROM_RF_OPT1 0xC4 +#define EEPROM_RF_OPT2 0xC5 +#define EEPROM_RF_OPT3 0xC6 +#define EEPROM_RF_OPT4 0xC7 +#define EEPROM_RF_OPT5 0xC8 +#define EEPROM_RF_OPT6 0xC9 +#define EEPROM_VERSION 0xCA +#define EEPROM_CUSTOMER_ID 0xCB +#define EEPROM_RF_OPT7 0xCC + +#define EEPROM_DEF_PART_NO 0x3FD /* Byte */ +#define EEPROME_CHIP_VERSION_L 0x3FF +#define EEPROME_CHIP_VERSION_H 0x3FE + +/* + * Current IOREG MAP + * 0x0000h ~ 0x00FFh System Configuration (256 Bytes) + * 0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) + * 0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) + * 0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) + * 0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) + * 0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) + * 0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) + * 0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) + * 0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) + */ + +/* ----------------------------------------------------- */ +/* 8192C (RCR) (Offset 0x608, 32 bits) */ +/* ----------------------------------------------------- */ +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +/* ----------------------------------------------------- */ +/* 8192C Regsiter Bit and Content definition */ +/* ----------------------------------------------------- */ +/* ----------------------------------------------------- */ +/* 0x0000h ~ 0x00FFh System Configuration */ +/* ----------------------------------------------------- */ + +/* SPS0_CTRL */ +#define SW18_FPWM BIT(3) + + +/* SYS_ISO_CTRL */ +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + + +/* SYS_FUNC_EN */ +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +/* APS_FSMCO */ +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +/* SYS_CLKR */ +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + + +/* 9346CR */ +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +/* AFE_MISC */ +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +/* RSV_CTRL */ +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +/* RF_CTRL */ +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + + + +/* LDOA15_CTRL */ +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + + + +/* LDOV12D_CTRL */ +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + +/* AFE_XTAL_CTRL */ +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + + +/* AFE_PLL_CTRL */ +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + + +/* EFUSE_CTRL */ +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +/* EFUSE_TEST */ +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +/* MCUFWDL */ +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define MAC1_WINTINI_RDY BIT(11) +#define CPRST BIT(23) + +/* REG_SYS_CFG */ +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +/* LLT_INIT */ +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + + +/* ----------------------------------------------------- */ +/* 0x0400h ~ 0x047Fh Protocol Configuration */ +/* ----------------------------------------------------- */ +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + + +/* ----------------------------------------------------- */ +/* 0x0500h ~ 0x05FFh EDCA Configuration */ +/* ----------------------------------------------------- */ +/* EDCA setting */ +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +/* ACMHWCTRL */ +#define ACMHW_HWEN BIT(0) +#define ACMHW_BEQEN BIT(1) +#define ACMHW_VIQEN BIT(2) +#define ACMHW_VOQEN BIT(3) + +/* ----------------------------------------------------- */ +/* 0x0600h ~ 0x07FFh WMAC Configuration */ +/* ----------------------------------------------------- */ + +/* TCR */ +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +/* SECCFG */ +#define SCR_TXUSEDK BIT(0) +#define SCR_RXUSEDK BIT(1) +#define SCR_TXENCENABLE BIT(2) +#define SCR_RXENCENABLE BIT(3) +#define SCR_SKBYA2 BIT(4) +#define SCR_NOSKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +/* General definitions */ +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_DUAL_MAC 127 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +/* Min Spacing related settings. */ +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + + +/* BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */ +/* 1. PMAC duplicate register due to connection: */ +/* RF_Mode, TRxRN, NumOf L-STF */ +/* 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */ +/* 3. RF register 0x00-2E */ +/* 4. Bit Mask for BB/RF register */ +/* 5. Other defintion for BB/RF R/W */ + +/* 3. Page8(0x800) */ +#define RFPGA0_RFMOD 0x800 + +#define RFPGA0_TXINFO 0x804 +#define RFPGA0_PSDFUNCTION 0x808 + +#define RFPGA0_TXGAINSTAGE 0x80c + +#define RFPGA0_RFTIMING1 0x810 +#define RFPGA0_RFTIMING2 0x814 + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 + +#define RFPGA0_RFWAkEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RFPARAMETER 0x878 +#define RFPGA0_XCD_RFPARAMETER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ADDALLOCKEN 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +#define RFPGA0_XD_LSSIREADBACK 0x8ac + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVERA_HSPI_READBACK 0x8b8 +#define TRANSCEIVERB_HSPI_READBACK 0x8bc +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +/* 4. Page9(0x900) */ +#define RFPGA1_RFMOD 0x900 + +#define RFPGA1_TXBLOCK 0x904 +#define RFPGA1_DEBUGSELECT 0x908 +#define RFPGA1_TXINFO 0x90c + +/* 5. PageA(0xA00) */ +#define RCCK0_SYSTEM 0xa00 + +#define RCCK0_AFESSTTING 0xa04 +#define RCCK0_CCA 0xa08 + +#define RCCK0_RXAGC1 0xa0c +#define RCCK0_RXAGC2 0xa10 + +#define RCCK0_RXHP 0xa14 + +#define RCCK0_DSPPARAMETER1 0xa18 +#define RCCK0_DSPPARAMETER2 0xa1c + +#define RCCK0_TXFILTER1 0xa20 +#define RCCK0_TXFILTER2 0xa24 +#define RCCK0_DEBUGPORT 0xa28 +#define RCCK0_FALSEALARMREPORT 0xa2c +#define RCCK0_TRSSIREPORT 0xa50 +#define RCCK0_RXREPORT 0xa54 +#define RCCK0_FACOUNTERLOWER 0xa5c +#define RCCK0_FACOUNTERUPPER 0xa58 + +/* 6. PageC(0xC00) */ +#define ROFDM0_LSTF 0xc00 + +#define ROFDM0_TRXPATHENABLE 0xc04 +#define ROFDM0_TRMUXPAR 0xc08 +#define ROFDM0_TRSWISOLATION 0xc0c + +#define ROFDM0_XARXAFE 0xc10 +#define ROFDM0_XARXIQIMBALANCE 0xc14 +#define ROFDM0_XBRXAFE 0xc18 +#define ROFDM0_XBRXIQIMBALANCE 0xc1c +#define ROFDM0_XCRXAFE 0xc20 +#define ROFDM0_XCRXIQIMBALANCE 0xc24 +#define ROFDM0_XDRXAFE 0xc28 +#define ROFDM0_XDRXIQIMBALANCE 0xc2c + +#define ROFDM0_RXDETECTOR1 0xc30 +#define ROFDM0_RXDETECTOR2 0xc34 +#define ROFDM0_RXDETECTOR3 0xc38 +#define ROFDM0_RXDETECTOR4 0xc3c + +#define ROFDM0_RXDSP 0xc40 +#define ROFDM0_CFOANDDAGC 0xc44 +#define ROFDM0_CCADROPTHRESHOLD 0xc48 +#define ROFDM0_ECCATHRESHOLD 0xc4c + +#define ROFDM0_XAAGCCORE1 0xc50 +#define ROFDM0_XAAGCCORE2 0xc54 +#define ROFDM0_XBAGCCORE1 0xc58 +#define ROFDM0_XBAGCCORE2 0xc5c +#define ROFDM0_XCAGCCORE1 0xc60 +#define ROFDM0_XCAGCCORE2 0xc64 +#define ROFDM0_XDAGCCORE1 0xc68 +#define ROFDM0_XDAGCCORE2 0xc6c + +#define ROFDM0_AGCPARAMETER1 0xc70 +#define ROFDM0_AGCPARAMETER2 0xc74 +#define ROFDM0_AGCRSSITABLE 0xc78 +#define ROFDM0_HTSTFAGC 0xc7c + +#define ROFDM0_XATxIQIMBALANCE 0xc80 +#define ROFDM0_XATxAFE 0xc84 +#define ROFDM0_XBTxIQIMBALANCE 0xc88 +#define ROFDM0_XBTxAFE 0xc8c +#define ROFDM0_XCTxIQIMBALANCE 0xc90 +#define ROFDM0_XCTxAFE 0xc94 +#define ROFDM0_XDTxIQIMBALANCE 0xc98 +#define ROFDM0_XDTxAFE 0xc9c + +#define ROFDM0_RXHPPARAMETER 0xce0 +#define ROFDM0_TXPSEUDONOISEWGT 0xce4 +#define ROFDM0_FRAMESYNC 0xcf0 +#define ROFDM0_DFSREPORT 0xcf4 +#define ROFDM0_TXCOEFF1 0xca4 +#define ROFDM0_TXCOEFF2 0xca8 +#define ROFDM0_TXCOEFF3 0xcac +#define ROFDM0_TXCOEFF4 0xcb0 +#define ROFDM0_TXCOEFF5 0xcb4 +#define ROFDM0_TXCOEFF6 0xcb8 + +/* 7. PageD(0xD00) */ +#define ROFDM1_LSTF 0xd00 +#define ROFDM1_TRXPATHENABLE 0xd04 + +#define ROFDM1_CFO 0xd08 +#define ROFDM1_CSI1 0xd10 +#define ROFDM1_SBD 0xd14 +#define ROFDM1_CSI2 0xd18 +#define ROFDM1_CFOTRACKING 0xd2c +#define ROFDM1_TRXMESAURE1 0xd34 +#define ROFDM1_INTFDET 0xd3c +#define ROFDM1_PSEUDONOISESTATEAB 0xd50 +#define ROFDM1_PSEUDONOISESTATECD 0xd54 +#define ROFDM1_RXPSEUDONOISEWGT 0xd58 + +#define ROFDM_PHYCOUNTER1 0xda0 +#define ROFDM_PHYCOUNTER2 0xda4 +#define ROFDM_PHYCOUNTER3 0xda8 + +#define ROFDM_SHORTCFOAB 0xdac +#define ROFDM_SHORTCFOCD 0xdb0 +#define ROFDM_LONGCFOAB 0xdb4 +#define ROFDM_LONGCFOCD 0xdb8 +#define ROFDM_TAILCFOAB 0xdbc +#define ROFDM_TAILCFOCD 0xdc0 +#define ROFDM_PWMEASURE1 0xdc4 +#define ROFDM_PWMEASURE2 0xdc8 +#define ROFDM_BWREPORT 0xdcc +#define ROFDM_AGCREPORT 0xdd0 +#define ROFDM_RXSNR 0xdd4 +#define ROFDM_RXEVMCSI 0xdd8 +#define ROFDM_SIGReport 0xddc + +/* 8. PageE(0xE00) */ +#define RTXAGC_A_RATE18_06 0xe00 +#define RTXAGC_A_RATE54_24 0xe04 +#define RTXAGC_A_CCK1_MCS32 0xe08 +#define RTXAGC_A_MCS03_MCS00 0xe10 +#define RTXAGC_A_MCS07_MCS04 0xe14 +#define RTXAGC_A_MCS11_MCS08 0xe18 +#define RTXAGC_A_MCS15_MCS12 0xe1c + +#define RTXAGC_B_RATE18_06 0x830 +#define RTXAGC_B_RATE54_24 0x834 +#define RTXAGC_B_CCK1_55_MCS32 0x838 +#define RTXAGC_B_MCS03_MCS00 0x83c +#define RTXAGC_B_MCS07_MCS04 0x848 +#define RTXAGC_B_MCS11_MCS08 0x84c +#define RTXAGC_B_MCS15_MCS12 0x868 +#define RTXAGC_B_CCK11_A_CCK2_11 0x86c + +/* RL6052 Register definition */ +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define rRfChannel 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 + +#define RF_T_METER 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 + +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +/* Bit Mask */ + +/* 2. Page8(0x800) */ +#define BRFMOD 0x1 +#define BCCKTXSC 0x30 +#define BCCKEN 0x1000000 +#define BOFDMEN 0x2000000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDRESSLENGTH 0x400 + +#define BRFSI_RFENV 0x10 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 +#define BLSSIREADBACKDATA 0xfffff +/* 4. PageA(0xA00) */ +#define BCCKSIDEBAND 0x10 + +/* Other Definition */ +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BDWORD 0xf + +#define BMASKBYTE0 0xff +#define BMASKBYTE1 0xff00 +#define BMASKBYTE2 0xff0000 +#define BMASKBYTE3 0xff000000 +#define BMASKHWORD 0xffff0000 +#define BMASKLWORD 0x0000ffff +#define BMASKDWORD 0xffffffff +#define BMASK12BITS 0xfff +#define BMASKH4BITS 0xf0000000 +#define BMASKOFDM_D 0xffc00000 +#define BMASKCCK 0x3f3f3f3f + +#define BRFREGOFFSETMASK 0xfffff + +#endif -- cgit v1.2.3-70-g09d2 From f219eff1e51aa598107c9deda0fa0f061371eded Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:10:55 -0500 Subject: rtlwifi: rtl8192de: Merge rf routines Merge routines rf.c and rf.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 628 ++++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/rf.h | 44 ++ 2 files changed, 672 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/rf.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/rf.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c new file mode 100644 index 00000000000..c326372220f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -0,0 +1,628 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "hw.h" + +void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 rfpath; + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = ((rtlphy->rfreg_chnlval + [rfpath] & 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | + BIT(11), 0x01); + + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, + ("20M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath])); + } + + break; + case HT_CHANNEL_WIDTH_20_40: + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & 0xfffff3ff)); + rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11), + 0x00); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, + ("40M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath])); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", bandwidth)); + break; + } +} + +void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = {0, 0}, tmpval; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + if (mac->act_scanning == true) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + } + } else { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8); + tx_agc[RF90_PATH_A] += tmpval; + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *) (&(tx_agc[idx1])); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK1_MCS32)); + tmpval = tx_agc[RF90_PATH_A] >> 8; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK1_55_MCS32)); +} + +static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 powerbase0, powerbase1; + u8 legacy_pwrdiff, ht20_pwrdiff; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerbase0 = powerlevel[i] + legacy_pwrdiff; + powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | + (powerbase0 << 8) | powerbase0; + *(ofdmbase + i) = powerbase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + } + + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerbase1 = powerlevel[i]; + powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) | + (powerbase1 << 8) | powerbase1; + *(mcsbase + i) = powerbase1; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + } +} + +static u8 _rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex) +{ + u8 group; + u8 channel_info[59] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, + 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, + 161, 163, 165 + }; + + if (channel_info[chnlindex] <= 3) /* Chanel 1-3 */ + group = 0; + else if (channel_info[chnlindex] <= 9) /* Channel 4-9 */ + group = 1; + else if (channel_info[chnlindex] <= 14) /* Channel 10-14 */ + group = 2; + else if (channel_info[chnlindex] <= 64) + group = 6; + else if (channel_info[chnlindex] <= 140) + group = 7; + else + group = 8; + return group; +} + +static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerbase0, + u32 *powerbase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4]; + u32 writeval = 0, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " + "performance, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval)); + break; + case 1: + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + if (rtlphy->pwrgroup_cnt >= MAX_PG_GROUP) { + chnlgroup = _rtl92d_phy_get_chnlgroup_bypg( + channel - 1); + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20) + chnlgroup++; + else + chnlgroup += 4; + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : + powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Realtek regulatory, " + "20MHz, writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), + writeval)); + } + break; + case 2: + writeval = ((index < 2) ? powerbase0[rf] : + powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, " + "writeval(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval)); + break; + case 3: + chnlgroup = 0; + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 40MHz rf(%c) = " + "0x%x\n", ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40[rf] + [channel - 1])); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 20MHz rf(%c) = " + "0x%x\n", ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20[rf] + [channel - 1])); + } + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] & + (0x7f << (i * 8))) >> (i * 8)); + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwr_diff_limit[i] > + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht40 + [rf][channel - 1]; + } else { + if (pwr_diff_limit[i] > + rtlefuse->pwrgroup_ht20[rf][ + channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]; + } + } + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | + (pwr_diff_limit[0]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit)); + writeval = customer_limit + ((index < 2) ? + powerbase0[rf] : powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer, writeval rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval)); + break; + default: + chnlgroup = 0; + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] + ((index < 2) ? + powerbase0[rf] : powerbase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("RTK better performance, writeval " + "rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeval)); + break; + } + *(p_outwriteval + rf) = writeval; + } +} + +static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pvalue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + static u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + static u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeval; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeval = pvalue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8) ((writeval & (0x7f << + (i * 8))) >> (i * 8)); + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Set 0x%x = %08x\n", regoffset, writeval)); + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + writeval = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + for (i = 0; i < 3; i++) { + if (i != 2) + writeval = (writeval > 8) ? + (writeval - 8) : 0; + else + writeval = (writeval > 6) ? + (writeval - 6) : 0; + rtl_write_byte(rtlpriv, (u32) (regoffset + i), + (u8) writeval); + } + } + } +} + +void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeval[2], powerbase0[2], powerbase1[2]; + u8 index; + + _rtl92d_phy_get_power_base(hw, ppowerlevel, channel, + &powerbase0[0], &powerbase1[0]); + for (index = 0; index < 6; index++) { + _rtl92d_get_txpower_writeval_by_regulatory(hw, + channel, index, &powerbase0[0], + &powerbase1[0], &writeval[0]); + _rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]); + } +} + +bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 u1btmp; + u8 direct = bmac0 == true ? BIT(3) | BIT(2) : BIT(3); + u8 mac_reg = bmac0 == true ? REG_MAC1 : REG_MAC0; + u8 mac_on_bit = bmac0 == true ? MAC1_ON : MAC0_ON; + bool bresult = true; /* true: need to enable BB/RF power */ + + rtlhal->during_mac0init_radiob = false; + rtlhal->during_mac1init_radioa = false; + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n")); + /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */ + u1btmp = rtl_read_byte(rtlpriv, mac_reg); + if (!(u1btmp & mac_on_bit)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n")); + /* Enable BB and RF power */ + rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL, + rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) | + BIT(29) | BIT(16) | BIT(17), direct); + } else { + /* We think if MAC1 is ON,then radio_a.txt + * and radio_b.txt has been load. */ + bresult = false; + } + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n")); + return bresult; + +} + +void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u8 u1btmp; + u8 direct = bmac0 == true ? BIT(3) | BIT(2) : BIT(3); + u8 mac_reg = bmac0 == true ? REG_MAC1 : REG_MAC0; + u8 mac_on_bit = bmac0 == true ? MAC1_ON : MAC0_ON; + + rtlhal->during_mac0init_radiob = false; + rtlhal->during_mac1init_radioa = false; + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + /* check MAC0 enable or not again now, if + * enabled, not power down radio A. */ + u1btmp = rtl_read_byte(rtlpriv, mac_reg); + if (!(u1btmp & mac_on_bit)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n")); + /* power down RF radio A according to YuNan's advice. */ + rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER, + 0x00000000, direct); + } + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); +} + +bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool rtstatus = true; + struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + u32 u4_regvalue = 0; + u8 rfpath; + struct bb_reg_def *pphyreg; + bool mac1_initradioa_first = false, mac0_initradiob_first = false; + bool need_pwrdown_radioa = false, need_pwrdown_radiob = false; + bool true_bpath = false; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + /* Single phy mode: use radio_a radio_b config path_A path_B */ + /* seperately by MAC0, and MAC1 needn't configure RF; */ + /* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */ + /* MAC1 use radio_b config 2nd PHY path_A. */ + /* DMDP,MAC0 on G band,MAC1 on A band. */ + if (rtlhal->macphymode == DUALMAC_DUALPHY) { + if (rtlhal->current_bandtype == BAND_ON_2_4G && + rtlhal->interfaceindex == 0) { + /* MAC0 needs PHY1 load radio_b.txt. + * Driver use DBI to write. */ + if (rtl92d_phy_enable_anotherphy(hw, true)) { + rtlphy->num_total_rfpath = 2; + mac0_initradiob_first = true; + } else { + /* We think if MAC1 is ON,then radio_a.txt and + * radio_b.txt has been load. */ + return rtstatus; + } + } else if (rtlhal->current_bandtype == BAND_ON_5G && + rtlhal->interfaceindex == 1) { + /* MAC1 needs PHY0 load radio_a.txt. + * Driver use DBI to write. */ + if (rtl92d_phy_enable_anotherphy(hw, false)) { + rtlphy->num_total_rfpath = 2; + mac1_initradioa_first = true; + } else { + /* We think if MAC0 is ON,then radio_a.txt and + * radio_b.txt has been load. */ + return rtstatus; + } + } else if (rtlhal->interfaceindex == 1) { + /* MAC0 enabled, only init radia B. */ + true_bpath = true; + } + } + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + /* Mac1 use PHY0 write */ + if (mac1_initradioa_first) { + if (rfpath == RF90_PATH_A) { + rtlhal->during_mac1init_radioa = true; + need_pwrdown_radioa = true; + } else if (rfpath == RF90_PATH_B) { + rtlhal->during_mac1init_radioa = false; + mac1_initradioa_first = false; + rfpath = RF90_PATH_A; + true_bpath = true; + rtlphy->num_total_rfpath = 1; + } + } else if (mac0_initradiob_first) { + /* Mac0 use PHY1 write */ + if (rfpath == RF90_PATH_A) + rtlhal->during_mac0init_radiob = false; + if (rfpath == RF90_PATH_B) { + rtlhal->during_mac0init_radiob = true; + mac0_initradiob_first = false; + need_pwrdown_radiob = true; + rfpath = RF90_PATH_A; + true_bpath = true; + rtlphy->num_total_rfpath = 1; + } + } + pphyreg = &rtlphy->phyreg_def[rfpath]; + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + /* Set bit number of Address and Data for RF register */ + /* Set 1 to 4 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDRESSLENGTH, 0x0); + udelay(1); + /* Set 0 to 12 bits for 8255 */ + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + switch (rfpath) { + case RF90_PATH_A: + if (true_bpath == true) + rtstatus = rtl92d_phy_config_rf_with_headerfile( + hw, radiob_txt, + (enum radio_path)rfpath); + else + rtstatus = rtl92d_phy_config_rf_with_headerfile( + hw, radioa_txt, + (enum radio_path)rfpath); + break; + case RF90_PATH_B: + rtstatus = + rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt, + (enum radio_path) rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, + u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16, + u4_regvalue); + break; + } + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio[%d] Fail!!", rfpath)); + goto phy_rf_cfg_fail; + } + + } + + /* check MAC0 enable or not again, if enabled, + * not power down radio A. */ + /* check MAC1 enable or not again, if enabled, + * not power down radio B. */ + if (need_pwrdown_radioa) + rtl92d_phy_powerdown_anotherphy(hw, false); + else if (need_pwrdown_radiob) + rtl92d_phy_powerdown_anotherphy(hw, true); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + return rtstatus; + +phy_rf_cfg_fail: + return rtstatus; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h new file mode 100644 index 00000000000..74b9cfc39a8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92D_RF_H__ +#define __RTL92D_RF_H__ + +extern void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +extern bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); +extern bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); +extern void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, + bool bmac0); + +#endif -- cgit v1.2.3-70-g09d2 From a7dbd3b50d09c0006babb2ba0bbdba4b0ede5c73 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:11:10 -0500 Subject: rtlwifi: rtl8192de: Merge main (sw) routines Merge routines sw.c and sw.h for RTL8192SE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 423 ++++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/sw.h | 37 +++ 2 files changed, 460 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/sw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/sw.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c new file mode 100644 index 00000000000..08837744f6f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -0,0 +1,423 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "hw.h" +#include "sw.h" +#include "trx.h" +#include "led.h" + +static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /*close ASPM for AMD defaultly */ + rtlpci->const_amdpci_aspm = 0; + + /* + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set defult to RTL8192CE:3 RTL8192E:2 + * */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8192CE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = 1; +} + +static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) +{ + int err; + u8 tid; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + const struct firmware *firmware; + static int header_print; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = 0; + rtlpriv->dm.thermalvalue = 0; + rtlpriv->dm.useramask = 1; + + /* dual mac */ + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) + rtlpriv->phy.current_channel = 36; + else + rtlpriv->phy.current_channel = 1; + + if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { + rtlpriv->rtlhal.disable_amsdu_8k = true; + /* No long RX - reduce fragmentation */ + rtlpci->rxbuffersize = 4096; + } + + rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); + + rtlpci->receive_config = ( + RCR_APPFCS + | RCR_AMF + | RCR_ADF + | RCR_APP_MIC + | RCR_APP_ICV + | RCR_AICV + | RCR_ACRC32 + | RCR_AB + | RCR_AM + | RCR_APM + | RCR_APP_PHYST_RXFF + | RCR_HTC_LOC_CTRL + ); + + rtlpci->irq_mask[0] = (u32) ( + IMR_ROK + | IMR_VODOK + | IMR_VIDOK + | IMR_BEDOK + | IMR_BKDOK + | IMR_MGNTDOK + | IMR_HIGHDOK + | IMR_BDOK + | IMR_RDU + | IMR_RXFOVW + ); + + rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpriv->psc.reg_fwctrl_lps = 3; + rtlpriv->psc.reg_max_lps_awakeintvl = 5; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 */ + rtl92d_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); + if (!rtlpriv->rtlhal.pfirmware) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't alloc buffer for fw.\n")); + return 1; + } + + if (!header_print) { + printk(KERN_INFO "rtl8192de: Driver for Realtek RTL8192DE" + " WLAN interface"); + printk(KERN_INFO "rtl8192de: Loading firmware file %s\n", + rtlpriv->cfg->fw_name); + header_print++; + } + /* request fw */ + err = request_firmware(&firmware, rtlpriv->cfg->fw_name, + rtlpriv->io.dev); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to request firmware!\n")); + return 1; + } + if (firmware->size > 0x8000) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Firmware is too big!\n")); + release_firmware(firmware); + return 1; + } + memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); + rtlpriv->rtlhal.fwsize = firmware->size; + release_firmware(firmware); + + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = true; + for (tid = 0; tid < 8; tid++) + skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + return 0; +} + +static void rtl92d_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tid; + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } + for (tid = 0; tid < 8; tid++) + skb_queue_purge(&rtlpriv->mac80211.skb_waitq[tid]); +} + +static struct rtl_hal_ops rtl8192de_hal_ops = { + .init_sw_vars = rtl92d_init_sw_vars, + .deinit_sw_vars = rtl92d_deinit_sw_vars, + .read_eeprom_info = rtl92de_read_eeprom_info, + .interrupt_recognized = rtl92de_interrupt_recognized, + .hw_init = rtl92de_hw_init, + .hw_disable = rtl92de_card_disable, + .hw_suspend = rtl92de_suspend, + .hw_resume = rtl92de_resume, + .enable_interrupt = rtl92de_enable_interrupt, + .disable_interrupt = rtl92de_disable_interrupt, + .set_network_type = rtl92de_set_network_type, + .set_chk_bssid = rtl92de_set_check_bssid, + .set_qos = rtl92de_set_qos, + .set_bcn_reg = rtl92de_set_beacon_related_registers, + .set_bcn_intv = rtl92de_set_beacon_interval, + .update_interrupt_mask = rtl92de_update_interrupt_mask, + .get_hw_reg = rtl92de_get_hw_reg, + .set_hw_reg = rtl92de_set_hw_reg, + .update_rate_tbl = rtl92de_update_hal_rate_tbl, + .fill_tx_desc = rtl92de_tx_fill_desc, + .fill_tx_cmddesc = rtl92de_tx_fill_cmddesc, + .query_rx_desc = rtl92de_rx_query_desc, + .set_channel_access = rtl92de_update_channel_access_setting, + .radio_onoff_checking = rtl92de_gpio_radio_on_off_checking, + .set_bw_mode = rtl92d_phy_set_bw_mode, + .switch_channel = rtl92d_phy_sw_chnl, + .dm_watchdog = rtl92d_dm_watchdog, + .scan_operation_backup = rtl92d_phy_scan_operation_backup, + .set_rf_power_state = rtl92d_phy_set_rf_power_state, + .led_control = rtl92de_led_control, + .set_desc = rtl92de_set_desc, + .get_desc = rtl92de_get_desc, + .tx_polling = rtl92de_tx_polling, + .enable_hw_sec = rtl92de_enable_hw_security_config, + .set_key = rtl92de_set_key, + .init_sw_leds = rtl92de_init_sw_leds, + .get_bbreg = rtl92d_phy_query_bb_reg, + .set_bbreg = rtl92d_phy_set_bb_reg, + .get_rfreg = rtl92d_phy_query_rf_reg, + .set_rfreg = rtl92d_phy_set_rf_reg, + .linked_set_reg = rtl92d_linked_set_reg, +}; + +static struct rtl_mod_params rtl92de_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = true, + .fwctrl_lps = false, +}; + +static struct rtl_hal_cfg rtl92de_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8192de", + .fw_name = "rtlwifi/rtl8192defw.bin", + .ops = &rtl8192de_hal_ops, + .mod_params = &rtl92de_mod_params, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = RCR_AM, + .maps[MAC_RCR_AB] = RCR_AB, + .maps[MAC_RCR_ACRC32] = RCR_ACRC32, + .maps[MAC_RCR_ACF] = RCR_ACF, + .maps[MAC_RCR_AAP] = RCR_AAP, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, /* just for 92se */ + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = 0, /* just for 92se */ + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BcnInt] = IMR_BcnInt, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BcnInt | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC92D_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92D_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92D_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92D_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92D_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92D_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92D_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92D_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92D_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92D_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92D_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92D_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC92D_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92D_RATEMCS15, +}; + +static struct pci_device_id rtl92de_pci_ids[] __devinitdata = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)}, + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl92de_pci_ids); + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin"); + +module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444); +module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444); +MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); +MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); +MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1" + " is open)\n"); + +static struct pci_driver rtl92de_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl92de_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + +#ifdef CONFIG_PM + .suspend = rtl_pci_suspend, + .resume = rtl_pci_resume, +#endif + +}; + +/* add global spin lock to solve the problem that + * Dul mac register operation on the same time */ +spinlock_t globalmutex_power; +spinlock_t globalmutex_for_fwdownload; +spinlock_t globalmutex_for_power_and_efuse; + +static int __init rtl92de_module_init(void) +{ + int ret = 0; + + spin_lock_init(&globalmutex_power); + spin_lock_init(&globalmutex_for_fwdownload); + spin_lock_init(&globalmutex_for_power_and_efuse); + + ret = pci_register_driver(&rtl92de_driver); + if (ret) + RT_ASSERT(false, (": No device found\n")); + return ret; +} + +static void __exit rtl92de_module_exit(void) +{ + pci_unregister_driver(&rtl92de_driver); +} + +module_init(rtl92de_module_init); +module_exit(rtl92de_module_exit); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h new file mode 100644 index 00000000000..c95e47de134 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92DE_SW_H__ +#define __RTL92DE_SW_H__ + +extern spinlock_t globalmutex_power; +extern spinlock_t globalmutex_for_fwdownload; +extern spinlock_t globalmutex_for_power_and_efuse; + +#endif -- cgit v1.2.3-70-g09d2 From e501016884dc2112b3742045834302c8adfe3944 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:11:25 -0500 Subject: rtlwifi: rtl8192de: Merge table routines Merge routines table.c and table.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/table.c | 1690 ++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/table.h | 57 + 2 files changed, 1747 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/table.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/table.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/rtlwifi/rtl8192de/table.c new file mode 100644 index 00000000000..bad7f9449ec --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.c @@ -0,0 +1,1690 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + * Created on 2010/12/23, 6:38 + *****************************************************************************/ + +#include + +#include "table.h" + +u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH] = { + 0x024, 0x0011800d, + 0x028, 0x00ffdb83, + 0x014, 0x088ba955, + 0x010, 0x49022b03, + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x80706388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x27272727, + 0x86c, 0x272b2b2b, + 0x870, 0x07000700, + 0x874, 0x22188000, + 0x878, 0x08080808, + 0x87c, 0x00007ff8, + 0x880, 0xc0083070, + 0x884, 0x00000cd5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x40071d40, + 0xc04, 0x03a05633, + 0xc08, 0x001000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a979718, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x69543420, + 0xc54, 0x43bc009e, + 0xc58, 0x69543420, + 0xc5c, 0x433c00a8, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x058610db, + 0xc78, 0x0000001f, + 0xc7c, 0x40b95612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20e00000, + 0xc90, 0x00121820, + 0xc94, 0x00000007, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b11e20, + 0xcdc, 0xe8767533, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608404, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c126da4, + 0xe78, 0x0c126da4, + 0xe7c, 0x0c126da4, + 0xe80, 0x0c126da4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c126da4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf1c, 0x00000064, + 0xf4c, 0x00000004, + 0xf00, 0x00000300, +}; + +u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH] = { + 0xe00, 0xffffffff, 0x07090c0c, + 0xe04, 0xffffffff, 0x01020405, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0b0c0c0e, + 0xe14, 0xffffffff, 0x01030506, + 0xe18, 0xffffffff, 0x0b0c0d0e, + 0xe1c, 0xffffffff, 0x01030509, + 0x830, 0xffffffff, 0x07090c0c, + 0x834, 0xffffffff, 0x01020405, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0b0c0c0e, + 0x848, 0xffffffff, 0x01030506, + 0x84c, 0xffffffff, 0x0b0c0d0e, + 0x868, 0xffffffff, 0x01030509, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x08080808, + 0xe14, 0xffffffff, 0x00040408, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x08080808, + 0x848, 0xffffffff, 0x00040408, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00017524, + 0x019, 0x00000000, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000de471, + 0x029, 0x000d7110, + 0x02a, 0x0008cb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000f9c43, + 0x049, 0x00002e0c, + 0x04a, 0x000546eb, + 0x04b, 0x0008966c, + 0x04c, 0x0000dde9, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00037524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00057568, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00097524, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x0006aaaa, + 0x02e, 0x000b4d01, + 0x02d, 0x00080000, + 0x02e, 0x00004d02, + 0x02d, 0x00095555, + 0x02e, 0x00054d03, + 0x02d, 0x000aaaaa, + 0x02e, 0x000b4d04, + 0x02d, 0x000c0000, + 0x02e, 0x00004d05, + 0x02d, 0x000d5555, + 0x02e, 0x00054d06, + 0x02d, 0x000eaaaa, + 0x02e, 0x000b4d07, + 0x02d, 0x00000000, + 0x02e, 0x00005108, + 0x02d, 0x00015555, + 0x02e, 0x00055109, + 0x02d, 0x0002aaaa, + 0x02e, 0x000b510a, + 0x02d, 0x00040000, + 0x02e, 0x0000510b, + 0x02d, 0x00055555, + 0x02e, 0x0005510c, +}; + +u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00007401, + 0x019, 0x00000060, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000d1c31, + 0x029, 0x000d7110, + 0x02a, 0x000aeb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000f9c43, + 0x049, 0x00002e0c, + 0x04a, 0x000546eb, + 0x04b, 0x0008966c, + 0x04c, 0x0000dde9, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00037524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x018, 0x00057524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bc, + 0x013, 0x000247b0, + 0x013, 0x000203b4, + 0x013, 0x0001c3a8, + 0x013, 0x000181b4, + 0x013, 0x000141a8, + 0x013, 0x000100b0, + 0x013, 0x0000c0a4, + 0x013, 0x0000b02c, + 0x013, 0x00004020, + 0x013, 0x00000014, + 0x015, 0x0000f4c3, + 0x015, 0x0004f4c3, + 0x015, 0x0008f4c3, + 0x016, 0x000e085f, + 0x016, 0x000a085f, + 0x016, 0x0006085f, + 0x016, 0x0002085f, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00087401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x00066666, + 0x02e, 0x00064001, + 0x02d, 0x00091111, + 0x02e, 0x00014002, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4003, + 0x02d, 0x000e6666, + 0x02e, 0x00064004, + 0x02d, 0x00088888, + 0x02e, 0x00084005, + 0x02d, 0x0009dddd, + 0x02e, 0x000d4006, + 0x02d, 0x000b3333, + 0x02e, 0x00034007, + 0x02d, 0x00048888, + 0x02e, 0x00084408, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4409, + 0x02d, 0x000e6666, + 0x02e, 0x0006440a, + 0x02d, 0x00011111, + 0x02e, 0x0001480b, + 0x02d, 0x0003bbbb, + 0x02e, 0x000b480c, + 0x02d, 0x00066666, + 0x02e, 0x0006480d, + 0x02d, 0x000ccccc, + 0x02e, 0x000c480e, +}; + +u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00017524, + 0x019, 0x00000000, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000de471, + 0x029, 0x000d7110, + 0x02a, 0x0008eb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000c0443, + 0x049, 0x00000730, + 0x04a, 0x00050f0f, + 0x04b, 0x000896ee, + 0x04c, 0x0000ddee, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00037564, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00057595, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00097524, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x0006aaaa, + 0x02e, 0x000b4d01, + 0x02d, 0x00080000, + 0x02e, 0x00004d02, + 0x02d, 0x00095555, + 0x02e, 0x00054d03, + 0x02d, 0x000aaaaa, + 0x02e, 0x000b4d04, + 0x02d, 0x000c0000, + 0x02e, 0x00004d05, + 0x02d, 0x000d5555, + 0x02e, 0x00054d06, + 0x02d, 0x000eaaaa, + 0x02e, 0x000b4d07, + 0x02d, 0x00000000, + 0x02e, 0x00005108, + 0x02d, 0x00015555, + 0x02e, 0x00055109, + 0x02d, 0x0002aaaa, + 0x02e, 0x000b510a, + 0x02d, 0x00040000, + 0x02e, 0x0000510b, + 0x02d, 0x00055555, + 0x02e, 0x0005510c, +}; + +u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH] = { + 0x000, 0x00030000, + 0x001, 0x00030000, + 0x002, 0x00000000, + 0x003, 0x00018c63, + 0x004, 0x00018c63, + 0x008, 0x00084000, + 0x00b, 0x0001c000, + 0x00e, 0x00018c67, + 0x00f, 0x00000851, + 0x014, 0x00021440, + 0x018, 0x00007401, + 0x019, 0x00000060, + 0x01d, 0x000a1290, + 0x023, 0x00001558, + 0x01a, 0x00030a99, + 0x01b, 0x00040b00, + 0x01c, 0x000fc339, + 0x03a, 0x000a57eb, + 0x03b, 0x00020000, + 0x03c, 0x000ff454, + 0x020, 0x0000aa52, + 0x021, 0x00054000, + 0x040, 0x0000aa52, + 0x041, 0x00014000, + 0x025, 0x000803be, + 0x026, 0x000fc638, + 0x027, 0x00077c18, + 0x028, 0x000d1c31, + 0x029, 0x000d7110, + 0x02a, 0x000aeb04, + 0x02b, 0x0004128b, + 0x02c, 0x00001840, + 0x043, 0x0002444f, + 0x044, 0x0001adb0, + 0x045, 0x00056467, + 0x046, 0x0008992c, + 0x047, 0x0000452c, + 0x048, 0x000c0443, + 0x049, 0x00000730, + 0x04a, 0x00050f0f, + 0x04b, 0x000896ee, + 0x04c, 0x0000ddee, + 0x018, 0x00007401, + 0x000, 0x00070000, + 0x012, 0x000dc000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x000287b7, + 0x013, 0x000247ab, + 0x013, 0x0002079f, + 0x013, 0x0001c793, + 0x013, 0x0001839b, + 0x013, 0x00014392, + 0x013, 0x0001019a, + 0x013, 0x0000c191, + 0x013, 0x00008194, + 0x013, 0x000040a0, + 0x013, 0x00000018, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x016, 0x000e1330, + 0x016, 0x000a1330, + 0x016, 0x00061330, + 0x016, 0x00021330, + 0x018, 0x00017524, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00037564, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x018, 0x00057595, + 0x000, 0x00070000, + 0x012, 0x000cf000, + 0x012, 0x000bc000, + 0x012, 0x00078000, + 0x012, 0x00000000, + 0x013, 0x000287bf, + 0x013, 0x000247b3, + 0x013, 0x000207a7, + 0x013, 0x0001c79b, + 0x013, 0x0001839f, + 0x013, 0x00014393, + 0x013, 0x00010399, + 0x013, 0x0000c38d, + 0x013, 0x00008199, + 0x013, 0x0000418d, + 0x013, 0x00000099, + 0x015, 0x0000f495, + 0x015, 0x0004f495, + 0x015, 0x0008f495, + 0x016, 0x000e1874, + 0x016, 0x000a1874, + 0x016, 0x00061874, + 0x016, 0x00021874, + 0x030, 0x0004470f, + 0x031, 0x00044ff0, + 0x032, 0x00000070, + 0x033, 0x000dd480, + 0x034, 0x000ffac0, + 0x035, 0x000b80c0, + 0x036, 0x00077000, + 0x037, 0x00064ff2, + 0x038, 0x000e7661, + 0x039, 0x00000e90, + 0x000, 0x00030000, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00088009, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x01e, 0x00088001, + 0x01f, 0x00080000, + 0x0fe, 0x00000000, + 0x018, 0x00087401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x02b, 0x00041289, + 0x0fe, 0x00000000, + 0x02d, 0x00066666, + 0x02e, 0x00064001, + 0x02d, 0x00091111, + 0x02e, 0x00014002, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4003, + 0x02d, 0x000e6666, + 0x02e, 0x00064004, + 0x02d, 0x00088888, + 0x02e, 0x00084005, + 0x02d, 0x0009dddd, + 0x02e, 0x000d4006, + 0x02d, 0x000b3333, + 0x02e, 0x00034007, + 0x02d, 0x00048888, + 0x02e, 0x00084408, + 0x02d, 0x000bbbbb, + 0x02e, 0x000b4409, + 0x02d, 0x000e6666, + 0x02e, 0x0006440a, + 0x02d, 0x00011111, + 0x02e, 0x0001480b, + 0x02d, 0x0003bbbb, + 0x02e, 0x000b480c, + 0x02d, 0x00066666, + 0x02e, 0x0006480d, + 0x02d, 0x000ccccc, + 0x02e, 0x000c480e, +}; + +u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x00000050, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x462, 0x00000008, + 0x463, 0x00000003, + 0x4c8, 0x000000ff, + 0x4c9, 0x00000008, + 0x4cc, 0x000000ff, + 0x4cd, 0x000000ff, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000040, + 0x547, 0x00000000, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000a, + 0x63e, 0x0000000e, + 0x63f, 0x0000000e, + 0x66e, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7a070001, + 0xc78, 0x79080001, + 0xc78, 0x78090001, + 0xc78, 0x770a0001, + 0xc78, 0x760b0001, + 0xc78, 0x750c0001, + 0xc78, 0x740d0001, + 0xc78, 0x730e0001, + 0xc78, 0x720f0001, + 0xc78, 0x71100001, + 0xc78, 0x70110001, + 0xc78, 0x6f120001, + 0xc78, 0x6e130001, + 0xc78, 0x6d140001, + 0xc78, 0x6c150001, + 0xc78, 0x6b160001, + 0xc78, 0x6a170001, + 0xc78, 0x69180001, + 0xc78, 0x68190001, + 0xc78, 0x671a0001, + 0xc78, 0x661b0001, + 0xc78, 0x651c0001, + 0xc78, 0x641d0001, + 0xc78, 0x631e0001, + 0xc78, 0x621f0001, + 0xc78, 0x61200001, + 0xc78, 0x60210001, + 0xc78, 0x49220001, + 0xc78, 0x48230001, + 0xc78, 0x47240001, + 0xc78, 0x46250001, + 0xc78, 0x45260001, + 0xc78, 0x44270001, + 0xc78, 0x43280001, + 0xc78, 0x42290001, + 0xc78, 0x412a0001, + 0xc78, 0x402b0001, + 0xc78, 0x262c0001, + 0xc78, 0x252d0001, + 0xc78, 0x242e0001, + 0xc78, 0x232f0001, + 0xc78, 0x22300001, + 0xc78, 0x21310001, + 0xc78, 0x20320001, + 0xc78, 0x06330001, + 0xc78, 0x05340001, + 0xc78, 0x04350001, + 0xc78, 0x03360001, + 0xc78, 0x02370001, + 0xc78, 0x01380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7a420001, + 0xc78, 0x79430001, + 0xc78, 0x78440001, + 0xc78, 0x77450001, + 0xc78, 0x76460001, + 0xc78, 0x75470001, + 0xc78, 0x74480001, + 0xc78, 0x73490001, + 0xc78, 0x724a0001, + 0xc78, 0x714b0001, + 0xc78, 0x704c0001, + 0xc78, 0x6f4d0001, + 0xc78, 0x6e4e0001, + 0xc78, 0x6d4f0001, + 0xc78, 0x6c500001, + 0xc78, 0x6b510001, + 0xc78, 0x6a520001, + 0xc78, 0x69530001, + 0xc78, 0x68540001, + 0xc78, 0x67550001, + 0xc78, 0x66560001, + 0xc78, 0x65570001, + 0xc78, 0x64580001, + 0xc78, 0x63590001, + 0xc78, 0x625a0001, + 0xc78, 0x615b0001, + 0xc78, 0x605c0001, + 0xc78, 0x485d0001, + 0xc78, 0x475e0001, + 0xc78, 0x465f0001, + 0xc78, 0x45600001, + 0xc78, 0x44610001, + 0xc78, 0x43620001, + 0xc78, 0x42630001, + 0xc78, 0x41640001, + 0xc78, 0x40650001, + 0xc78, 0x27660001, + 0xc78, 0x26670001, + 0xc78, 0x25680001, + 0xc78, 0x24690001, + 0xc78, 0x236a0001, + 0xc78, 0x226b0001, + 0xc78, 0x216c0001, + 0xc78, 0x206d0001, + 0xc78, 0x206e0001, + 0xc78, 0x206f0001, + 0xc78, 0x20700001, + 0xc78, 0x20710001, + 0xc78, 0x20720001, + 0xc78, 0x20730001, + 0xc78, 0x20740001, + 0xc78, 0x20750001, + 0xc78, 0x20760001, + 0xc78, 0x20770001, + 0xc78, 0x20780001, + 0xc78, 0x20790001, + 0xc78, 0x207a0001, + 0xc78, 0x207b0001, + 0xc78, 0x207c0001, + 0xc78, 0x207d0001, + 0xc78, 0x207e0001, + 0xc78, 0x207f0001, + 0xc78, 0x38000002, + 0xc78, 0x38010002, + 0xc78, 0x38020002, + 0xc78, 0x38030002, + 0xc78, 0x38040002, + 0xc78, 0x38050002, + 0xc78, 0x38060002, + 0xc78, 0x38070002, + 0xc78, 0x38080002, + 0xc78, 0x3c090002, + 0xc78, 0x3e0a0002, + 0xc78, 0x400b0002, + 0xc78, 0x440c0002, + 0xc78, 0x480d0002, + 0xc78, 0x4c0e0002, + 0xc78, 0x500f0002, + 0xc78, 0x52100002, + 0xc78, 0x56110002, + 0xc78, 0x5a120002, + 0xc78, 0x5e130002, + 0xc78, 0x60140002, + 0xc78, 0x60150002, + 0xc78, 0x60160002, + 0xc78, 0x62170002, + 0xc78, 0x62180002, + 0xc78, 0x62190002, + 0xc78, 0x621a0002, + 0xc78, 0x621b0002, + 0xc78, 0x621c0002, + 0xc78, 0x621d0002, + 0xc78, 0x621e0002, + 0xc78, 0x621f0002, + 0xc78, 0x32000044, + 0xc78, 0x32010044, + 0xc78, 0x32020044, + 0xc78, 0x32030044, + 0xc78, 0x32040044, + 0xc78, 0x32050044, + 0xc78, 0x32060044, + 0xc78, 0x32070044, + 0xc78, 0x32080044, + 0xc78, 0x34090044, + 0xc78, 0x350a0044, + 0xc78, 0x360b0044, + 0xc78, 0x370c0044, + 0xc78, 0x380d0044, + 0xc78, 0x390e0044, + 0xc78, 0x3a0f0044, + 0xc78, 0x3e100044, + 0xc78, 0x42110044, + 0xc78, 0x44120044, + 0xc78, 0x46130044, + 0xc78, 0x4a140044, + 0xc78, 0x4e150044, + 0xc78, 0x50160044, + 0xc78, 0x55170044, + 0xc78, 0x5a180044, + 0xc78, 0x5e190044, + 0xc78, 0x641a0044, + 0xc78, 0x6e1b0044, + 0xc78, 0x6e1c0044, + 0xc78, 0x6e1d0044, + 0xc78, 0x6e1e0044, + 0xc78, 0x6e1f0044, + 0xc78, 0x6e1f0000, +}; + +u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7a020001, + 0xc78, 0x79030001, + 0xc78, 0x78040001, + 0xc78, 0x77050001, + 0xc78, 0x76060001, + 0xc78, 0x75070001, + 0xc78, 0x74080001, + 0xc78, 0x73090001, + 0xc78, 0x720a0001, + 0xc78, 0x710b0001, + 0xc78, 0x700c0001, + 0xc78, 0x6f0d0001, + 0xc78, 0x6e0e0001, + 0xc78, 0x6d0f0001, + 0xc78, 0x6c100001, + 0xc78, 0x6b110001, + 0xc78, 0x6a120001, + 0xc78, 0x69130001, + 0xc78, 0x68140001, + 0xc78, 0x67150001, + 0xc78, 0x66160001, + 0xc78, 0x65170001, + 0xc78, 0x64180001, + 0xc78, 0x63190001, + 0xc78, 0x621a0001, + 0xc78, 0x611b0001, + 0xc78, 0x601c0001, + 0xc78, 0x481d0001, + 0xc78, 0x471e0001, + 0xc78, 0x461f0001, + 0xc78, 0x45200001, + 0xc78, 0x44210001, + 0xc78, 0x43220001, + 0xc78, 0x42230001, + 0xc78, 0x41240001, + 0xc78, 0x40250001, + 0xc78, 0x27260001, + 0xc78, 0x26270001, + 0xc78, 0x25280001, + 0xc78, 0x24290001, + 0xc78, 0x232a0001, + 0xc78, 0x222b0001, + 0xc78, 0x212c0001, + 0xc78, 0x202d0001, + 0xc78, 0x202e0001, + 0xc78, 0x202f0001, + 0xc78, 0x20300001, + 0xc78, 0x20310001, + 0xc78, 0x20320001, + 0xc78, 0x20330001, + 0xc78, 0x20340001, + 0xc78, 0x20350001, + 0xc78, 0x20360001, + 0xc78, 0x20370001, + 0xc78, 0x20380001, + 0xc78, 0x20390001, + 0xc78, 0x203a0001, + 0xc78, 0x203b0001, + 0xc78, 0x203c0001, + 0xc78, 0x203d0001, + 0xc78, 0x203e0001, + 0xc78, 0x203f0001, + 0xc78, 0x32000044, + 0xc78, 0x32010044, + 0xc78, 0x32020044, + 0xc78, 0x32030044, + 0xc78, 0x32040044, + 0xc78, 0x32050044, + 0xc78, 0x32060044, + 0xc78, 0x32070044, + 0xc78, 0x32080044, + 0xc78, 0x34090044, + 0xc78, 0x350a0044, + 0xc78, 0x360b0044, + 0xc78, 0x370c0044, + 0xc78, 0x380d0044, + 0xc78, 0x390e0044, + 0xc78, 0x3a0f0044, + 0xc78, 0x3e100044, + 0xc78, 0x42110044, + 0xc78, 0x44120044, + 0xc78, 0x46130044, + 0xc78, 0x4a140044, + 0xc78, 0x4e150044, + 0xc78, 0x50160044, + 0xc78, 0x55170044, + 0xc78, 0x5a180044, + 0xc78, 0x5e190044, + 0xc78, 0x641a0044, + 0xc78, 0x6e1b0044, + 0xc78, 0x6e1c0044, + 0xc78, 0x6e1d0044, + 0xc78, 0x6e1e0044, + 0xc78, 0x6e1f0044, + 0xc78, 0x6e1f0000, +}; + +u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7a070001, + 0xc78, 0x79080001, + 0xc78, 0x78090001, + 0xc78, 0x770a0001, + 0xc78, 0x760b0001, + 0xc78, 0x750c0001, + 0xc78, 0x740d0001, + 0xc78, 0x730e0001, + 0xc78, 0x720f0001, + 0xc78, 0x71100001, + 0xc78, 0x70110001, + 0xc78, 0x6f120001, + 0xc78, 0x6e130001, + 0xc78, 0x6d140001, + 0xc78, 0x6c150001, + 0xc78, 0x6b160001, + 0xc78, 0x6a170001, + 0xc78, 0x69180001, + 0xc78, 0x68190001, + 0xc78, 0x671a0001, + 0xc78, 0x661b0001, + 0xc78, 0x651c0001, + 0xc78, 0x641d0001, + 0xc78, 0x631e0001, + 0xc78, 0x621f0001, + 0xc78, 0x61200001, + 0xc78, 0x60210001, + 0xc78, 0x49220001, + 0xc78, 0x48230001, + 0xc78, 0x47240001, + 0xc78, 0x46250001, + 0xc78, 0x45260001, + 0xc78, 0x44270001, + 0xc78, 0x43280001, + 0xc78, 0x42290001, + 0xc78, 0x412a0001, + 0xc78, 0x402b0001, + 0xc78, 0x262c0001, + 0xc78, 0x252d0001, + 0xc78, 0x242e0001, + 0xc78, 0x232f0001, + 0xc78, 0x22300001, + 0xc78, 0x21310001, + 0xc78, 0x20320001, + 0xc78, 0x06330001, + 0xc78, 0x05340001, + 0xc78, 0x04350001, + 0xc78, 0x03360001, + 0xc78, 0x02370001, + 0xc78, 0x01380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x38000002, + 0xc78, 0x38010002, + 0xc78, 0x38020002, + 0xc78, 0x38030002, + 0xc78, 0x38040002, + 0xc78, 0x38050002, + 0xc78, 0x38060002, + 0xc78, 0x38070002, + 0xc78, 0x38080002, + 0xc78, 0x3c090002, + 0xc78, 0x3e0a0002, + 0xc78, 0x400b0002, + 0xc78, 0x440c0002, + 0xc78, 0x480d0002, + 0xc78, 0x4c0e0002, + 0xc78, 0x500f0002, + 0xc78, 0x52100002, + 0xc78, 0x56110002, + 0xc78, 0x5a120002, + 0xc78, 0x5e130002, + 0xc78, 0x60140002, + 0xc78, 0x60150002, + 0xc78, 0x60160002, + 0xc78, 0x62170002, + 0xc78, 0x62180002, + 0xc78, 0x62190002, + 0xc78, 0x621a0002, + 0xc78, 0x621b0002, + 0xc78, 0x621c0002, + 0xc78, 0x621d0002, + 0xc78, 0x621e0002, + 0xc78, 0x621f0002, + 0xc78, 0x6e1f0000, +}; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/rtlwifi/rtl8192de/table.h new file mode 100644 index 00000000000..93f30ca62d8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + * Created on 2010/ 5/18, 1:41 + *****************************************************************************/ + +#ifndef __RTL92DE_TABLE__H_ +#define __RTL92DE_TABLE__H_ + +/*Created on 2011/ 1/14, 1:35*/ + +#define PHY_REG_2T_ARRAYLENGTH 380 +extern u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH]; +#define PHY_REG_ARRAY_PG_LENGTH 624 +extern u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH]; +#define RADIOA_2T_ARRAYLENGTH 378 +extern u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH]; +#define RADIOB_2T_ARRAYLENGTH 384 +extern u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH]; +#define RADIOA_2T_INT_PA_ARRAYLENGTH 378 +extern u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH]; +#define RADIOB_2T_INT_PA_ARRAYLENGTH 384 +extern u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH]; +#define MAC_2T_ARRAYLENGTH 160 +extern u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH]; +#define AGCTAB_ARRAYLENGTH 386 +extern u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH]; +#define AGCTAB_5G_ARRAYLENGTH 194 +extern u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH]; +#define AGCTAB_2G_ARRAYLENGTH 194 +extern u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH]; + +#endif -- cgit v1.2.3-70-g09d2 From 674f0523ec07a7c716f5ed8a2debe6632be750f8 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:11:40 -0500 Subject: rtlwifi: rtl8192de: Merge TX and RX routines Merge routines trx.c and trx.h for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 959 +++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192de/trx.h | 756 +++++++++++++++++++++ 2 files changed, 1715 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/trx.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/trx.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c new file mode 100644 index 00000000000..bf1462f69b5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -0,0 +1,959 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" + +static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + __le16 fc = rtl_get_fc(skb); + + if (unlikely(ieee80211_is_beacon(fc))) + return QSLT_BEACON; + if (ieee80211_is_mgmt(fc)) + return QSLT_MGNT; + + return skb->priority; +} + +static int _rtl92de_rate_mapping(bool isht, u8 desc_rate) +{ + int rate_idx; + + if (false == isht) { + switch (desc_rate) { + case DESC92D_RATE1M: + rate_idx = 0; + break; + case DESC92D_RATE2M: + rate_idx = 1; + break; + case DESC92D_RATE5_5M: + rate_idx = 2; + break; + case DESC92D_RATE11M: + rate_idx = 3; + break; + case DESC92D_RATE6M: + rate_idx = 4; + break; + case DESC92D_RATE9M: + rate_idx = 5; + break; + case DESC92D_RATE12M: + rate_idx = 6; + break; + case DESC92D_RATE18M: + rate_idx = 7; + break; + case DESC92D_RATE24M: + rate_idx = 8; + break; + case DESC92D_RATE36M: + rate_idx = 9; + break; + case DESC92D_RATE48M: + rate_idx = 10; + break; + case DESC92D_RATE54M: + rate_idx = 11; + break; + default: + rate_idx = 0; + break; + } + return rate_idx; + } else { + switch (desc_rate) { + case DESC92D_RATE1M: + rate_idx = 0; + break; + case DESC92D_RATE2M: + rate_idx = 1; + break; + case DESC92D_RATE5_5M: + rate_idx = 2; + break; + case DESC92D_RATE11M: + rate_idx = 3; + break; + case DESC92D_RATE6M: + rate_idx = 4; + break; + case DESC92D_RATE9M: + rate_idx = 5; + break; + case DESC92D_RATE12M: + rate_idx = 6; + break; + case DESC92D_RATE18M: + rate_idx = 7; + break; + case DESC92D_RATE24M: + rate_idx = 8; + break; + case DESC92D_RATE36M: + rate_idx = 9; + break; + case DESC92D_RATE48M: + rate_idx = 10; + break; + case DESC92D_RATE54M: + rate_idx = 11; + break; + default: + rate_idx = 11; + break; + } + return rate_idx; + } +} + +static u8 _rtl92d_query_rxpwrpercentage(char antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; +} + +static u8 _rtl92d_evm_db_to_percentage(char value) +{ + char ret_val = value; + + if (ret_val >= 0) + ret_val = 0; + if (ret_val <= -33) + ret_val = -33; + ret_val = 0 - ret_val; + ret_val *= 3; + if (ret_val == 99) + ret_val = 100; + return ret_val; +} + +static long _rtl92de_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +static long _rtl92de_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + return retsig; +} + +static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, + struct rx_desc_92d *pdesc, + struct rx_fwinfo_92d *p_drvinfo, + bool packet_match_bssid, + bool packet_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct phy_sts_cck_8192d *cck_buf; + s8 rx_pwr_all, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool is_cck_rate; + + is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; + pstats->packet_beacon = packet_beacon; + pstats->is_cck = is_cck_rate; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; + + if (is_cck_rate) { + u8 report, cck_highpwr; + cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo; + if (ppsc->rfpwr_state == ERFON) + cck_highpwr = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + BIT(9)); + else + cck_highpwr = false; + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all); + /* CCK gain is smaller than OFDM/MCS gain, */ + /* so we add gain diff by experiences, the val is 6 */ + pwdb_all += 6; + if (pwdb_all > 100) + pwdb_all = 100; + /* modify the offset to make the same gain index with OFDM. */ + if (pwdb_all > 34 && pwdb_all <= 42) + pwdb_all -= 2; + else if (pwdb_all > 26 && pwdb_all <= 34) + pwdb_all -= 6; + else if (pwdb_all > 14 && pwdb_all <= 26) + pwdb_all -= 8; + else if (pwdb_all > 4 && pwdb_all <= 14) + pwdb_all -= 4; + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + if (packet_match_bssid) { + u8 sq; + if (pstats->rx_pwdb_all > 40) { + sq = 100; + } else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + pstats->signalquality = sq; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = true; + rtlpriv->dm.rfpath_rxenable[1] = true; + for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) + - 110; + rssi = _rtl92d_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + if (packet_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8) rssi; + } + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106; + pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + if (pdesc->rxht && pdesc->rxmcs >= DESC92D_RATEMCS8 && + pdesc->rxmcs <= DESC92D_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + for (i = 0; i < max_spatial_stream; i++) { + evm = _rtl92d_evm_db_to_percentage(p_drvinfo->rxevm[i]); + if (packet_match_bssid) { + if (i == 0) + pstats->signalquality = + (u8)(evm & 0xff); + pstats->rx_mimo_signalquality[i] = + (u8)(evm & 0xff); + } + } + } + if (is_cck_rate) + pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw, + pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw, + total_rssi /= rf_rx_num)); +} + +static void rtl92d_loop_over_paths(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 rfpath; + + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstats->rx_mimo_signalstrength[rfpath]; + + } + if (pstats->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + } +} + +static void _rtl92de_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_rssi, tmpval; + + if (pstats->packet_toself || pstats->packet_beacon) { + rtlpriv->stats.rssi_calculate_cnt++; + if (rtlpriv->stats.ui_rssi.total_num++ >= + PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = + PHY_RSSI_SLID_WIN_MAX; + last_rssi = rtlpriv->stats.ui_rssi.elements[ + rtlpriv->stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; + rtlpriv->stats.ui_rssi.elements + [rtlpriv->stats.ui_rssi.index++] = + pstats->signalstrength; + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = _rtl92de_translate_todbm(hw, + (u8) tmpval); + pstats->rssi = rtlpriv->stats.signal_strength; + } + if (!pstats->is_cck && pstats->packet_toself) + rtl92d_loop_over_paths(hw, pstats); +} + +static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting = 0; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; + if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * + 5 + pstats->recvsignalpower + weighting) / 6; +} + +static void _rtl92de_process_pwdb(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb; + + if (mac->opmode == NL80211_IFTYPE_ADHOC || + mac->opmode == NL80211_IFTYPE_AP) + return; + else + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + + if (pstats->packet_toself || pstats->packet_beacon) { + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb + 1; + } else { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + _rtl92de_update_rxsignalstatistics(hw, pstats); + } +} + +static void rtl92d_loop_over_streams(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int stream; + + for (stream = 0; stream < 2; stream++) { + if (pstats->rx_mimo_signalquality[stream] != -1) { + if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { + rtlpriv->stats.rx_evm_percentage[stream] = + pstats->rx_mimo_signalquality[stream]; + } + rtlpriv->stats.rx_evm_percentage[stream] = + ((rtlpriv->stats.rx_evm_percentage[stream] + * (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalquality[stream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } +} + +static void _rtl92de_process_ui_link_quality(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm, tmpval; + + if (pstats->signalquality == 0) + return; + if (pstats->packet_toself || pstats->packet_beacon) { + if (rtlpriv->stats.ui_link_quality.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.ui_link_quality.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index]; + rtlpriv->stats.ui_link_quality.total_val -= last_evm; + } + rtlpriv->stats.ui_link_quality.total_val += + pstats->signalquality; + rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index++] = + pstats->signalquality; + if (rtlpriv->stats.ui_link_quality.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.ui_link_quality.index = 0; + tmpval = rtlpriv->stats.ui_link_quality.total_val / + rtlpriv->stats.ui_link_quality.total_num; + rtlpriv->stats.signal_quality = tmpval; + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + rtl92d_loop_over_streams(hw, pstats); + } +} + +static void _rtl92de_process_phyinfo(struct ieee80211_hw *hw, + u8 *buffer, + struct rtl_stats *pcurrent_stats) +{ + + if (!pcurrent_stats->packet_matchbssid && + !pcurrent_stats->packet_beacon) + return; + + _rtl92de_process_ui_rssi(hw, pcurrent_stats); + _rtl92de_process_pwdb(hw, pcurrent_stats); + _rtl92de_process_ui_link_quality(hw, pcurrent_stats); +} + +static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92d *pdesc, + struct rx_fwinfo_92d *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u16 type, cfc; + __le16 fc; + bool packet_matchbssid, packet_toself, packet_beacon; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + cfc = le16_to_cpu(fc); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && + (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && + (!pstats->crc) && (!pstats->icv)); + packet_toself = packet_matchbssid && + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + if (ieee80211_is_beacon(fc)) + packet_beacon = true; + _rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + _rtl92de_process_phyinfo(hw, tmp_buf, pstats); +} + +bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *p_desc, struct sk_buff *skb) +{ + struct rx_fwinfo_92d *p_drvinfo; + struct rx_desc_92d *pdesc = (struct rx_desc_92d *)p_desc; + u32 phystatus = GET_RX_DESC_PHYST(pdesc); + + stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); + stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); + stats->icv = (u16) GET_RX_DESC_ICV(pdesc); + stats->crc = (u16) GET_RX_DESC_CRC32(pdesc); + stats->hwerror = (stats->crc | stats->icv); + stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); + stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); + stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); + stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); + stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) + && (GET_RX_DESC_FAGGR(pdesc) == 1)); + stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); + stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); + rx_status->freq = hw->conf.channel->center_freq; + rx_status->band = hw->conf.channel->band; + if (GET_RX_DESC_CRC32(pdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (!GET_RX_DESC_SWDEC(pdesc)) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (GET_RX_DESC_BW(pdesc)) + rx_status->flag |= RX_FLAG_40MHZ; + if (GET_RX_DESC_RXHT(pdesc)) + rx_status->flag |= RX_FLAG_HT; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; + if (stats->decrypted) + rx_status->flag |= RX_FLAG_DECRYPTED; + rx_status->rate_idx = _rtl92de_rate_mapping((bool) + GET_RX_DESC_RXHT(pdesc), + (u8) + GET_RX_DESC_RXMCS(pdesc)); + rx_status->mactime = GET_RX_DESC_TSFL(pdesc); + if (phystatus == true) { + p_drvinfo = (struct rx_fwinfo_92d *)(skb->data + + stats->rx_bufshift); + _rtl92de_translate_rx_signal_stuff(hw, + skb, stats, pdesc, + p_drvinfo); + } + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->rssi + 10; + /*rx_status->noise = -stats->noise; */ + return true; +} + +static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + u8 *virtualaddress) +{ + memset(virtualaddress, 0, 8); + + SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num); + SET_EARLYMODE_LEN0(virtualaddress, ptcb_desc->empkt_len[0]); + SET_EARLYMODE_LEN1(virtualaddress, ptcb_desc->empkt_len[1]); + SET_EARLYMODE_LEN2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF); + SET_EARLYMODE_LEN2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4); + SET_EARLYMODE_LEN3(virtualaddress, ptcb_desc->empkt_len[3]); + SET_EARLYMODE_LEN4(virtualaddress, ptcb_desc->empkt_len[4]); +} + +void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + struct ieee80211_tx_info *info, struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct ieee80211_sta *sta = info->control.sta; + u8 *pdesc = (u8 *) pdesc_tx; + u16 seq_number; + __le16 fc = hdr->frame_control; + unsigned int buf_len = 0; + unsigned int skb_len = skb->len; + u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 bw_40 = 0; + + if (mac->opmode == NL80211_IFTYPE_STATION) { + bw_40 = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta) + bw_40 = sta->ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + buf_len = skb->len; + mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d)); + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + SET_TX_DESC_PKT_OFFSET(pdesc, 1); + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN + + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD, + ("Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num)); + _rtl92de_insert_emcontent(ptcb_desc, + (u8 *)(skb->data)); + } + } else { + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + } + /* 5G have no CCK rate */ + if (rtlhal->current_bandtype == BAND_ON_5G) + if (ptcb_desc->hw_rate < DESC92D_RATE6M) + ptcb_desc->hw_rate = DESC92D_RATE6M; + SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate); + if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) + SET_TX_DESC_DATA_SHORTGI(pdesc, 1); + + if (rtlhal->macphymode == DUALMAC_DUALPHY && + ptcb_desc->hw_rate == DESC92D_RATEMCS7) + SET_TX_DESC_DATA_SHORTGI(pdesc, 1); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + SET_TX_DESC_AGG_ENABLE(pdesc, 1); + SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); + } + SET_TX_DESC_SEQ(pdesc, seq_number); + SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? 1 : 0)); + SET_TX_DESC_HW_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable + || ptcb_desc->cts_enable) ? 1 : 0)); + SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); + SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); + /* 5G have no CCK rate */ + if (rtlhal->current_bandtype == BAND_ON_5G) + if (ptcb_desc->rts_rate < DESC92D_RATE6M) + ptcb_desc->rts_rate = DESC92D_RATE6M; + SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); + SET_TX_DESC_RTS_BW(pdesc, 0); + SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); + SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= + DESC92D_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0))); + if (bw_40) { + if (ptcb_desc->packet_bw) { + SET_TX_DESC_DATA_BW(pdesc, 1); + SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); + } else { + SET_TX_DESC_DATA_BW(pdesc, 0); + SET_TX_DESC_TX_SUB_CARRIER(pdesc, + mac->cur_40_prime_sc); + } + } else { + SET_TX_DESC_DATA_BW(pdesc, 0); + SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); + } + SET_TX_DESC_LINIP(pdesc, 0); + SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len); + if (sta) { + u8 ampdu_density = sta->ht_cap.ampdu_density; + SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf; + + keyconf = info->control.hw_key; + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE(pdesc, 0x0); + break; + + } + } + SET_TX_DESC_PKT_ID(pdesc, 0); + SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); + SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); + SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); + SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ? + 1 : 0); + SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + /* Set TxRate and RTSRate in TxDesc */ + /* This prevent Tx initial rate of new-coming packets */ + /* from being overwritten by retried packet rate.*/ + if (!ptcb_desc->use_driver_rate) { + SET_TX_DESC_RTS_RATE(pdesc, 0x08); + /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */ + } + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("Enable RDG function.\n")); + SET_TX_DESC_RDG_ENABLE(pdesc, 1); + SET_TX_DESC_HTC(pdesc, 1); + } + } + } + + SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); + SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); + SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len); + SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); + if (rtlpriv->dm.useramask) { + SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index); + SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); + } else { + SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index); + SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index); + } + if (ieee80211_is_data_qos(fc)) + SET_TX_DESC_QOS(pdesc, 1); + + if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { + SET_TX_DESC_HWSEQ_EN(pdesc, 1); + SET_TX_DESC_PKT_ID(pdesc, 8); + } + SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); +} + +void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, + u8 *pdesc, bool firstseg, + bool lastseg, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 fw_queue = QSLT_BEACON; + dma_addr_t mapping = pci_map_single(rtlpci->pdev, + skb->data, skb->len, PCI_DMA_TODEVICE); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + __le16 fc = hdr->frame_control; + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); + if (firstseg) + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + /* 5G have no CCK rate + * Caution: The macros below are multi-line expansions. + * The braces are needed no matter what checkpatch says + */ + if (rtlhal->current_bandtype == BAND_ON_5G) { + SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE6M); + } else { + SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE1M); + } + SET_TX_DESC_SEQ(pdesc, 0); + SET_TX_DESC_LINIP(pdesc, 0); + SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); + SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); + SET_TX_DESC_RATE_ID(pdesc, 7); + SET_TX_DESC_MACID(pdesc, 0); + SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + SET_TX_DESC_OFFSET(pdesc, 0x20); + SET_TX_DESC_USE_RATE(pdesc, 1); + + if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) { + SET_TX_DESC_HWSEQ_EN(pdesc, 1); + SET_TX_DESC_PKT_ID(pdesc, 8); + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE); + wmb(); + SET_TX_DESC_OWN(pdesc, 1); +} + +void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +{ + if (istx == true) { + switch (desc_name) { + case HW_DESC_OWN: + wmb(); + SET_TX_DESC_OWN(pdesc, 1); + break; + case HW_DESC_TX_NEXTDESC_ADDR: + SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); + break; + default: + RT_ASSERT(false, ("ERR txdesc :%d" + " not process\n", desc_name)); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXOWN: + wmb(); + SET_RX_DESC_OWN(pdesc, 1); + break; + case HW_DESC_RXBUFF_ADDR: + SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); + break; + case HW_DESC_RXPKT_LEN: + SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); + break; + case HW_DESC_RXERO: + SET_RX_DESC_EOR(pdesc, 1); + break; + default: + RT_ASSERT(false, ("ERR rxdesc :%d " + "not process\n", desc_name)); + break; + } + } +} + +u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) +{ + u32 ret = 0; + + if (istx == true) { + switch (desc_name) { + case HW_DESC_OWN: + ret = GET_TX_DESC_OWN(p_desc); + break; + case HW_DESC_TXBUFF_ADDR: + ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); + break; + default: + RT_ASSERT(false, ("ERR txdesc :%d " + "not process\n", desc_name)); + break; + } + } else { + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; + switch (desc_name) { + case HW_DESC_OWN: + ret = GET_RX_DESC_OWN(pdesc); + break; + case HW_DESC_RXPKT_LEN: + ret = GET_RX_DESC_PKT_LEN(pdesc); + break; + default: + RT_ASSERT(false, ("ERR rxdesc :%d " + "not process\n", desc_name)); + break; + } + } + return ret; +} + +void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (hw_queue == BEACON_QUEUE) + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); + else + rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, + BIT(0) << (hw_queue)); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h new file mode 100644 index 00000000000..992d6766e66 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h @@ -0,0 +1,756 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92DE_TRX_H__ +#define __RTL92DE_TRX_H__ + +#define TX_DESC_SIZE 64 +#define TX_DESC_AGGR_SUBFRAME_SIZE 32 + +#define RX_DESC_SIZE 32 +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 40 +#define USB_HWDESC_HEADER_LEN 32 +#define CRCLENGTH 4 + +/* Define a macro that takes a le32 word, converts it to host ordering, + * right shifts by a specified count, creates a mask of the specified + * bit count, and extracts that number of bits. + */ + +#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \ + ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ + BIT_LEN_MASK_32(__mask)) + +/* Define a macro that clears a bit field in an le32 word and + * sets the specified value into that bit field. The resulting + * value remains in le32 ordering; however, it is properly converted + * to host ordering for the clear and set operations before conversion + * back to le32. + */ + +#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \ + (*(__le32 *)(__pdesc) = \ + (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \ + (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \ + (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift))))); + +/* macros to read/write various fields in RX or TX descriptors */ + +#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val) +#define SET_TX_DESC_OFFSET(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val) +#define SET_TX_DESC_BMC(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 24, 1, __val) +#define SET_TX_DESC_HTC(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 25, 1, __val) +#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val) +#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val) +#define SET_TX_DESC_LINIP(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val) +#define SET_TX_DESC_NO_ACM(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val) +#define SET_TX_DESC_GF(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) +#define SET_TX_DESC_OWN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) + +#define GET_TX_DESC_PKT_SIZE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 0, 16) +#define GET_TX_DESC_OFFSET(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 16, 8) +#define GET_TX_DESC_BMC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 24, 1) +#define GET_TX_DESC_HTC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 25, 1) +#define GET_TX_DESC_LAST_SEG(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 26, 1) +#define GET_TX_DESC_FIRST_SEG(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 27, 1) +#define GET_TX_DESC_LINIP(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 28, 1) +#define GET_TX_DESC_NO_ACM(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 29, 1) +#define GET_TX_DESC_GF(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 30, 1) +#define GET_TX_DESC_OWN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 31, 1) + +#define SET_TX_DESC_MACID(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 0, 5, __val) +#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 5, 1, __val) +#define SET_TX_DESC_BK(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 6, 1, __val) +#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 7, 1, __val) +#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 8, 5, __val) +#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 13, 1, __val) +#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 14, 1, __val) +#define SET_TX_DESC_PIFS(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 15, 1, __val) +#define SET_TX_DESC_RATE_ID(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 16, 4, __val) +#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 20, 1, __val) +#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 21, 1, __val) +#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 22, 2, __val) +#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+4, 26, 8, __val) + +#define GET_TX_DESC_MACID(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 0, 5) +#define GET_TX_DESC_AGG_ENABLE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 5, 1) +#define GET_TX_DESC_AGG_BREAK(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 6, 1) +#define GET_TX_DESC_RDG_ENABLE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 7, 1) +#define GET_TX_DESC_QUEUE_SEL(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 8, 5) +#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 13, 1) +#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 14, 1) +#define GET_TX_DESC_PIFS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 15, 1) +#define GET_TX_DESC_RATE_ID(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 16, 4) +#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 20, 1) +#define GET_TX_DESC_EN_DESC_ID(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 21, 1) +#define GET_TX_DESC_SEC_TYPE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 22, 2) +#define GET_TX_DESC_PKT_OFFSET(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 24, 8) + +#define SET_TX_DESC_RTS_RC(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 0, 6, __val) +#define SET_TX_DESC_DATA_RC(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 6, 6, __val) +#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 14, 2, __val) +#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 17, 1, __val) +#define SET_TX_DESC_RAW(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 18, 1, __val) +#define SET_TX_DESC_CCX(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 19, 1, __val) +#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 20, 3, __val) +#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 24, 1, __val) +#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 25, 1, __val) +#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 26, 2, __val) +#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 28, 2, __val) +#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+8, 30, 2, __val) + +#define GET_TX_DESC_RTS_RC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 0, 6) +#define GET_TX_DESC_DATA_RC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 6, 6) +#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 14, 2) +#define GET_TX_DESC_MORE_FRAG(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 17, 1) +#define GET_TX_DESC_RAW(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 18, 1) +#define GET_TX_DESC_CCX(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 19, 1) +#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 20, 3) +#define GET_TX_DESC_ANTSEL_A(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 24, 1) +#define GET_TX_DESC_ANTSEL_B(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 25, 1) +#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 26, 2) +#define GET_TX_DESC_TX_ANTL(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 28, 2) +#define GET_TX_DESC_TX_ANT_HT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 30, 2) + +#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+12, 0, 8, __val) +#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+12, 8, 8, __val) +#define SET_TX_DESC_SEQ(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+12, 16, 12, __val) +#define SET_TX_DESC_PKT_ID(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+12, 28, 4, __val) + +#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 0, 8) +#define GET_TX_DESC_TAIL_PAGE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 8, 8) +#define GET_TX_DESC_SEQ(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 16, 12) +#define GET_TX_DESC_PKT_ID(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 28, 4) + +#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 0, 5, __val) +#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 5, 1, __val) +#define SET_TX_DESC_QOS(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 6, 1, __val) +#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 7, 1, __val) +#define SET_TX_DESC_USE_RATE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 8, 1, __val) +#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 9, 1, __val) +#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 10, 1, __val) +#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 11, 1, __val) +#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 12, 1, __val) +#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 13, 1, __val) +#define SET_TX_DESC_PORT_ID(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 14, 1, __val) +#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 18, 1, __val) +#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 19, 1, __val) +#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 20, 2, __val) +#define SET_TX_DESC_TX_STBC(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 22, 2, __val) +#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 24, 1, __val) +#define SET_TX_DESC_DATA_BW(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 25, 1, __val) +#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 26, 1, __val) +#define SET_TX_DESC_RTS_BW(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 27, 1, __val) +#define SET_TX_DESC_RTS_SC(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 28, 2, __val) +#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+16, 30, 2, __val) + +#define GET_TX_DESC_RTS_RATE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 0, 5) +#define GET_TX_DESC_AP_DCFE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 5, 1) +#define GET_TX_DESC_QOS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 6, 1) +#define GET_TX_DESC_HWSEQ_EN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 7, 1) +#define GET_TX_DESC_USE_RATE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 8, 1) +#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 9, 1) +#define GET_TX_DESC_DISABLE_FB(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 10, 1) +#define GET_TX_DESC_CTS2SELF(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 11, 1) +#define GET_TX_DESC_RTS_ENABLE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 12, 1) +#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 13, 1) +#define GET_TX_DESC_PORT_ID(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 14, 1) +#define GET_TX_DESC_WAIT_DCTS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 18, 1) +#define GET_TX_DESC_CTS2AP_EN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 19, 1) +#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 20, 2) +#define GET_TX_DESC_TX_STBC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 22, 2) +#define GET_TX_DESC_DATA_SHORT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 24, 1) +#define GET_TX_DESC_DATA_BW(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 25, 1) +#define GET_TX_DESC_RTS_SHORT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 26, 1) +#define GET_TX_DESC_RTS_BW(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 27, 1) +#define GET_TX_DESC_RTS_SC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 28, 2) +#define GET_TX_DESC_RTS_STBC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 30, 2) + +#define SET_TX_DESC_TX_RATE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val) +#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val) +#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 8, 5, __val) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 13, 4, __val) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 17, 1, __val) +#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 18, 6, __val) +#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 24, 8, __val) + +#define GET_TX_DESC_TX_RATE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 0, 6) +#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 6, 1) +#define GET_TX_DESC_CCX_TAG(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 7, 1) +#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 8, 5) +#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 13, 4) +#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 17, 1) +#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 18, 6) +#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 24, 8) + +#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 0, 5, __val) +#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 5, 5, __val) +#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 10, 1, __val) +#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 11, 5, __val) +#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 16, 4, __val) +#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 20, 4, __val) +#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 24, 4, __val) +#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 28, 4, __val) + +#define GET_TX_DESC_TXAGC_A(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 0, 5) +#define GET_TX_DESC_TXAGC_B(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 5, 5) +#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 10, 1) +#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 11, 5) +#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 16, 4) +#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 20, 4) +#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 24, 4) +#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 28, 4) + +#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+28, 0, 16, __val) +#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+28, 16, 4, __val) +#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+28, 20, 4, __val) +#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+28, 24, 4, __val) +#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+28, 28, 4, __val) + +#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+28, 0, 16) +#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+28, 16, 4) +#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+28, 20, 4) +#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+28, 24, 4) +#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+28, 28, 4) + +#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+32, 0, 32, __val) +#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+36, 0, 32, __val) + +#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+32, 0, 32) +#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+36, 0, 32) + +#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+40, 0, 32, __val) +#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+44, 0, 32, __val) + +#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+40, 0, 32) +#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+44, 0, 32) + +#define GET_RX_DESC_PKT_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 0, 14) +#define GET_RX_DESC_CRC32(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 14, 1) +#define GET_RX_DESC_ICV(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 15, 1) +#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 16, 4) +#define GET_RX_DESC_SECURITY(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 20, 3) +#define GET_RX_DESC_QOS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 23, 1) +#define GET_RX_DESC_SHIFT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 24, 2) +#define GET_RX_DESC_PHYST(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 26, 1) +#define GET_RX_DESC_SWDEC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 27, 1) +#define GET_RX_DESC_LS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 28, 1) +#define GET_RX_DESC_FS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 29, 1) +#define GET_RX_DESC_EOR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 30, 1) +#define GET_RX_DESC_OWN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc, 31, 1) + +#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val) +#define SET_RX_DESC_EOR(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) +#define SET_RX_DESC_OWN(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) + +#define GET_RX_DESC_MACID(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 0, 5) +#define GET_RX_DESC_TID(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 5, 4) +#define GET_RX_DESC_HWRSVD(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 9, 5) +#define GET_RX_DESC_PAGGR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 14, 1) +#define GET_RX_DESC_FAGGR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 15, 1) +#define GET_RX_DESC_A1_FIT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 16, 4) +#define GET_RX_DESC_A2_FIT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 20, 4) +#define GET_RX_DESC_PAM(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 24, 1) +#define GET_RX_DESC_PWR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 25, 1) +#define GET_RX_DESC_MD(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 26, 1) +#define GET_RX_DESC_MF(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 27, 1) +#define GET_RX_DESC_TYPE(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 28, 2) +#define GET_RX_DESC_MC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 30, 1) +#define GET_RX_DESC_BC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+4, 31, 1) +#define GET_RX_DESC_SEQ(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 0, 12) +#define GET_RX_DESC_FRAG(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 12, 4) +#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 16, 14) +#define GET_RX_DESC_NEXT_IND(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 30, 1) +#define GET_RX_DESC_RSVD(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+8, 31, 1) + +#define GET_RX_DESC_RXMCS(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 0, 6) +#define GET_RX_DESC_RXHT(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 6, 1) +#define GET_RX_DESC_SPLCP(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 8, 1) +#define GET_RX_DESC_BW(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 9, 1) +#define GET_RX_DESC_HTC(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 10, 1) +#define GET_RX_DESC_HWPC_ERR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 14, 1) +#define GET_RX_DESC_HWPC_IND(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 15, 1) +#define GET_RX_DESC_IV0(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+12, 16, 16) + +#define GET_RX_DESC_IV1(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+16, 0, 32) +#define GET_RX_DESC_TSFL(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+20, 0, 32) + +#define GET_RX_DESC_BUFF_ADDR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+24, 0, 32) +#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc+28, 0, 32) + +#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+24, 0, 32, __val) +#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+28, 0, 32, __val) + +#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ +do { \ + if (_size > TX_DESC_NEXT_DESC_OFFSET) \ + memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ + else \ + memset((void *)__pdesc, 0, _size); \ +} while (0); + +#define RX_HAL_IS_CCK_RATE(_pdesc)\ + (_pdesc->rxmcs == DESC92D_RATE1M || \ + _pdesc->rxmcs == DESC92D_RATE2M || \ + _pdesc->rxmcs == DESC92D_RATE5_5M || \ + _pdesc->rxmcs == DESC92D_RATE11M) + +/* For 92D early mode */ +#define SET_EARLYMODE_PKTNUM(__paddr, __value) \ + SET_BITS_OFFSET_LE(__paddr, 0, 3, __value) +#define SET_EARLYMODE_LEN0(__paddr, __value) \ + SET_BITS_OFFSET_LE(__paddr, 4, 12, __value) +#define SET_EARLYMODE_LEN1(__paddr, __value) \ + SET_BITS_OFFSET_LE(__paddr, 16, 12, __value) +#define SET_EARLYMODE_LEN2_1(__paddr, __value) \ + SET_BITS_OFFSET_LE(__paddr, 28, 4, __value) +#define SET_EARLYMODE_LEN2_2(__paddr, __value) \ + SET_BITS_OFFSET_LE(__paddr+4, 0, 8, __value) +#define SET_EARLYMODE_LEN3(__paddr, __value) \ + SET_BITS_OFFSET_LE(__paddr+4, 8, 12, __value) +#define SET_EARLYMODE_LEN4(__paddr, __value) \ + SET_BITS_OFFSET_LE(__paddr+4, 20, 12, __value) + +struct rx_fwinfo_92d { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + char rxevm[2]; + char rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct tx_desc_92d { + u32 pktsize:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 lastseg:1; + u32 firstseg:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + u32 macid:5; + u32 agg_en:1; + u32 bk:1; + u32 rdg_en:1; + u32 queuesel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rateid:4; + u32 nav_usehdr:1; + u32 en_descid:1; + u32 sectype:2; + u32 pktoffset:8; + + u32 rts_rc:6; + u32 data_rc:6; + u32 rsvd0:2; + u32 bar_retryht:2; + u32 rsvd1:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdudensity:3; + u32 rsvd2:1; + u32 ant_sela:1; + u32 ant_selb:1; + u32 txant_cck:2; + u32 txant_l:2; + u32 txant_ht:2; + + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 pktid:4; + + u32 rtsrate:5; + u32 apdcfe:1; + u32 qos:1; + u32 hwseq_enable:1; + u32 userrate:1; + u32 dis_rtsfb:1; + u32 dis_datafb:1; + u32 cts2self:1; + u32 rts_en:1; + u32 hwrts_en:1; + u32 portid:1; + u32 rsvd3:3; + u32 waitdcts:1; + u32 cts2ap_en:1; + u32 txsc:2; + u32 stbc:2; + u32 txshort:1; + u32 txbw:1; + u32 rtsshort:1; + u32 rtsbw:1; + u32 rtssc:2; + u32 rtsstbc:2; + + u32 txrate:6; + u32 shortgi:1; + u32 ccxt:1; + u32 txrate_fb_lmt:5; + u32 rtsrate_fb_lmt:4; + u32 retrylmt_en:1; + u32 txretrylmt:6; + u32 usb_txaggnum:8; + + u32 txagca:5; + u32 txagcb:5; + u32 usemaxlen:1; + u32 maxaggnum:5; + u32 mcsg1maxlen:4; + u32 mcsg2maxlen:4; + u32 mcsg3maxlen:4; + u32 mcs7sgimaxlen:4; + + u32 txbuffersize:16; + u32 mcsg4maxlen:4; + u32 mcsg5maxlen:4; + u32 mcsg6maxlen:4; + u32 mcsg15sgimaxlen:4; + + u32 txbuffaddr; + u32 txbufferaddr64; + u32 nextdescaddress; + u32 nextdescaddress64; + + u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_92d { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + + u32 macid:5; + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + + u32 rxmcs:6; + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + + u32 iv1; + + u32 tsfl; + + u32 bufferaddress; + u32 bufferaddress64; + +} __packed; + +void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, + u8 *pdesc, struct ieee80211_tx_info *info, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); +bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); +void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +u32 rtl92de_get_desc(u8 *pdesc, bool istx, u8 desc_name); +void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + bool b_firstseg, bool b_lastseg, + struct sk_buff *skb); + +#endif -- cgit v1.2.3-70-g09d2 From f34317db363636b50750d39e8a75873d4ee64cfa Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 10 Jun 2011 15:11:55 -0500 Subject: rtlwifi: Fix build problems introduced by merging rtl8192de These patches allow compilation of rtlwifi, rtl8192c_common, rtl8192ce, rtl8192cu and rtl8192se to compile after rtl8192de was added. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 2 ++ drivers/net/wireless/rtlwifi/wifi.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index 598cecc63f4..72a3d549754 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -1203,7 +1203,9 @@ #define EPROM_CMD_CONFIG 0x3 #define EPROM_CMD_LOAD 1 +#define HWSET_MAX_SIZE 128 #define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE +#define EFUSE_MAX_SECTION 16 #define WL_HWPDN_EN BIT(0) diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index c54cda5ce22..491e97fc034 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -303,9 +303,6 @@ enum hw_variables { HW_VAR_DATA_FILTER, }; -#define HWSET_MAX_SIZE 128 -#define EFUSE_MAX_SECTION 16 - enum _RT_MEDIA_STATUS { RT_MEDIA_DISCONNECT = 0, RT_MEDIA_CONNECT = 1 -- cgit v1.2.3-70-g09d2 From f9fc51365d0cf66d1f95f47618566f27177ecbbc Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 10 Jun 2011 15:12:10 -0500 Subject: rtlwifi: rtl8192de: Modify Kconfig and Makefile routines for new driver Set up Kconfig and Makefile for new driver for RTL8192DE. Signed-off-by: Chaoming_Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Kconfig | 15 +++++++++++++-- drivers/net/wireless/rtlwifi/Makefile | 1 + drivers/net/wireless/rtlwifi/rtl8192de/Makefile | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192de/Makefile (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 5aee8b22d74..45e14760c16 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -21,6 +21,17 @@ config RTL8192SE If you choose to build it as a module, it will be called rtl8192se +config RTL8192DE + tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter" + depends on MAC80211 && EXPERIMENTAL + select FW_LOADER + select RTLWIFI + ---help--- + This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192de + config RTL8192CU tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" depends on MAC80211 && USB && EXPERIMENTAL @@ -35,10 +46,10 @@ config RTL8192CU config RTLWIFI tristate - depends on RTL8192CE || RTL8192CU || RTL8192SE + depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE default m config RTL8192C_COMMON tristate - depends on RTL8192CE || RTL8192CU || RTL8192SE + depends on RTL8192CE || RTL8192CU default m diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index 7acce83c378..97935c565ba 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -23,5 +23,6 @@ obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ obj-$(CONFIG_RTL8192CE) += rtl8192ce/ obj-$(CONFIG_RTL8192CU) += rtl8192cu/ obj-$(CONFIG_RTL8192SE) += rtl8192se/ +obj-$(CONFIG_RTL8192DE) += rtl8192de/ ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/Makefile b/drivers/net/wireless/rtlwifi/rtl8192de/Makefile new file mode 100644 index 00000000000..e3213c8264b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/Makefile @@ -0,0 +1,14 @@ +rtl8192de-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8192DE) += rtl8192de.o + +ccflags-y += -D__CHECK_ENDIAN__ -- cgit v1.2.3-70-g09d2 From 04b7dcf979d71e870683c804802e44287a802760 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Jun 2011 10:06:59 +0200 Subject: wireless: unify QoS control field definitions Move all that mac80211 has into the generic ieee80211.h header file and use them. At the same time move them from mask+shift to just bits and rename them for consistent names. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/rx.c | 2 +- drivers/net/wireless/libertas_tf/main.c | 2 +- include/linux/ieee80211.h | 18 +++++++++++++----- net/mac80211/rx.c | 2 +- net/mac80211/wme.c | 3 +-- net/mac80211/wme.h | 5 ----- 6 files changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index ec21ea9fd8d..dc99030ea8b 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -472,7 +472,7 @@ static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len) u8 *qc = ieee80211_get_qos_ctl(hdr); reserved += NET_IP_ALIGN; - if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) + if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) reserved += NET_IP_ALIGN; } diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index d4005081f1d..2aa4de7cad2 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -585,7 +585,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) need_padding ^= ieee80211_has_a4(hdr->frame_control); need_padding ^= ieee80211_is_data_qos(hdr->frame_control) && (*ieee80211_get_qos_ctl(hdr) & - IEEE80211_QOS_CONTROL_A_MSDU_PRESENT); + IEEE80211_QOS_CTL_A_MSDU_PRESENT); if (need_padding) { memmove(skb->data + 2, skb->data, skb->len); diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index bf56b6f7827..a26108e4d92 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -117,8 +117,19 @@ #define IEEE80211_MAX_MESH_ID_LEN 32 #define IEEE80211_QOS_CTL_LEN 2 -#define IEEE80211_QOS_CTL_TID_MASK 0x000F -#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 +/* 1d tag mask */ +#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 +/* TID mask */ +#define IEEE80211_QOS_CTL_TID_MASK 0x000f +/* EOSP */ +#define IEEE80211_QOS_CTL_EOSP 0x0010 +/* ACK policy */ +#define IEEE80211_QOS_CTL_ACK_POLICY_NORMAL 0x0000 +#define IEEE80211_QOS_CTL_ACK_POLICY_NOACK 0x0020 +#define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL 0x0040 +#define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060 +/* A-MSDU 802.11n */ +#define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080 /* U-APSD queue for WMM IEs sent by AP */ #define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7) @@ -1423,9 +1434,6 @@ enum ieee80211_sa_query_action { }; -/* A-MSDU 802.11n */ -#define IEEE80211_QOS_CONTROL_A_MSDU_PRESENT 0x0080 - /* cipher suite selectors */ #define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00 #define WLAN_CIPHER_SUITE_WEP40 0x000FAC01 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7fa8c6be7bf..b5493ecd1e9 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -338,7 +338,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) u8 *qc = ieee80211_get_qos_ctl(hdr); /* frame has qos control */ tid = *qc & IEEE80211_QOS_CTL_TID_MASK; - if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) + if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) status->rx_flags |= IEEE80211_RX_AMSDU; } else { /* diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 28bc084dbfb..7a49532f14c 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -151,8 +151,7 @@ void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb) tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; if (unlikely(local->wifi_wme_noack_test)) - ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << - QOS_CONTROL_ACK_POLICY_SHIFT; + ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; /* qos header is 2 bytes, second reserved */ *p++ = ack_policy | tid; *p = 0; diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index 6053b1c9fee..faead6d0202 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h @@ -13,11 +13,6 @@ #include #include "ieee80211_i.h" -#define QOS_CONTROL_ACK_POLICY_NORMAL 0 -#define QOS_CONTROL_ACK_POLICY_NOACK 1 - -#define QOS_CONTROL_ACK_POLICY_SHIFT 5 - extern const int ieee802_1d_to_ac[8]; u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -- cgit v1.2.3-70-g09d2 From 8ee3108075c9e9e2701493a245a754b8b0db8e57 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Jun 2011 16:43:48 +0200 Subject: mac80211: restrict advertised HW scan rates Advertise only user-requested bitrates in a HW scan. Note that the hw_scan API doesn't currently have a way of asking for a specific probe request bitrate, so we might end up using a bitrate that we don't advertise as supported. I'll fix that later. Also add a hexdump printk to hwsim to verify this. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 2 ++ net/mac80211/scan.c | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7e1fa967127..031cd89b176 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1130,6 +1130,8 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, for (i = 0; i < req->n_channels; i++) printk(KERN_DEBUG "hwsim hw_scan freq %d\n", req->channels[i]->center_freq); + print_hex_dump(KERN_DEBUG, "scan IEs: ", DUMP_PREFIX_OFFSET, + 16, 1, req->ie, req->ie_len, 1); ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ); diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 1758b463c58..6403722da60 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -228,6 +228,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) { struct cfg80211_scan_request *req = local->scan_req; + struct ieee80211_sub_if_data *sdata = local->scan_sdata; enum ieee80211_band band; int i, ielen, n_chans; @@ -251,8 +252,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) local->hw_scan_req->n_channels = n_chans; ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, - req->ie, req->ie_len, band, (u32) -1, - 0); + req->ie, req->ie_len, band, + sdata->rc_rateidx_mask[band], 0); local->hw_scan_req->ie_len = ielen; return true; -- cgit v1.2.3-70-g09d2 From dcfcbd590d91e8385eb554aaed419bdebaf4c72a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 23 Jun 2011 13:39:13 +0530 Subject: ath9k_hw: Fix false tx hung detection in AR9003 chips The edma based (AR9003 family) chips update tx status descriptors in a common ring buffer for all transmitted frames. Whenever tx interrupt is raised, the descriptors are processed and tx status index is moved. The complete tx stauts ring are updated with beacons tx status when there are no data frames to be sent for a period of time. In this state, transmitting data frames causes the driver to wait for the tx status on an incorrect tx status index though the status was updated by hw properly. The driver detects this condition as a h/w hang and does unnecessary chip resets. This issue was orginally reported in adhoc mode while sending frames after an idle time. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 8 ++++++-- drivers/net/wireless/ath/ath9k/beacon.c | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 04e6be04acf..575e185f454 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -229,6 +229,7 @@ static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { + struct ar9003_txc *txc = (struct ar9003_txc *) ds; struct ar9003_txs *ads; u32 status; @@ -238,7 +239,11 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, if ((status & AR_TxDone) == 0) return -EINPROGRESS; - ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; + ts->qid = MS(ads->ds_info, AR_TxQcuNum); + if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid)) + ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; + else + return -ENOENT; if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || (MS(ads->ds_info, AR_TxRxDesc) != 1)) { @@ -254,7 +259,6 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, ts->ts_seqnum = MS(status, AR_SeqNum); ts->tid = MS(status, AR_TxTid); - ts->qid = MS(ads->ds_info, AR_TxQcuNum); ts->desc_id = MS(ads->status1, AR_TxDescId); ts->ts_tstamp = ads->status4; ts->ts_status = 0; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 0174cdb65a8..0b6e3b65bb0 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -360,6 +360,7 @@ void ath_beacon_tasklet(unsigned long data) struct ath_common *common = ath9k_hw_common(ah); struct ath_buf *bf = NULL; struct ieee80211_vif *vif; + struct ath_tx_status ts; int slot; u32 bfaddr, bc = 0; @@ -464,6 +465,11 @@ void ath_beacon_tasklet(unsigned long data) ath9k_hw_txstart(ah, sc->beacon.beaconq); sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + spin_lock_bh(&sc->sc_pcu_lock); + ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); + spin_unlock_bh(&sc->sc_pcu_lock); + } } } -- cgit v1.2.3-70-g09d2 From f68e20f0f8bc57dc91d132eaa66956e9ba5aafcf Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 23 Jun 2011 20:03:38 +0530 Subject: ath9k_hw: Add carrier leak correction in desired gain calculation Cc: muddin@qca.qualcomm.com Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 34 +++++++++++++++++++-------- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 3 +++ 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 8f6d11dfa37..6e9e892e528 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -246,13 +246,13 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah) static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, int target_power) { - int olpc_gain_delta = 0; + int olpc_gain_delta = 0, cl_gain_mod; int alpha_therm, alpha_volt; int therm_cal_value, volt_cal_value; int therm_value, volt_value; int thermal_gain_corr, voltage_gain_corr; int desired_scale, desired_gain = 0; - u32 reg; + u32 reg_olpc = 0, reg_cl_gain = 0; REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); @@ -271,15 +271,29 @@ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE); - if (chain == 0) - reg = AR_PHY_TPC_11_B0; - else if (chain == 1) - reg = AR_PHY_TPC_11_B1; - else - reg = AR_PHY_TPC_11_B2; + switch (chain) { + case 0: + reg_olpc = AR_PHY_TPC_11_B0; + reg_cl_gain = AR_PHY_CL_TAB_0; + break; + case 1: + reg_olpc = AR_PHY_TPC_11_B1; + reg_cl_gain = AR_PHY_CL_TAB_1; + break; + case 2: + reg_olpc = AR_PHY_TPC_11_B2; + reg_cl_gain = AR_PHY_CL_TAB_2; + break; + default: + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "Invalid chainmask: %d\n", chain); + break; + } - olpc_gain_delta = REG_READ_FIELD(ah, reg, + olpc_gain_delta = REG_READ_FIELD(ah, reg_olpc, AR_PHY_TPC_11_OLPC_GAIN_DELTA); + cl_gain_mod = REG_READ_FIELD(ah, reg_cl_gain, + AR_PHY_CL_TAB_CL_GAIN_MOD); if (olpc_gain_delta >= 128) olpc_gain_delta = olpc_gain_delta - 256; @@ -289,7 +303,7 @@ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) + (128 / 2)) / 128; desired_gain = target_power - olpc_gain_delta - thermal_gain_corr - - voltage_gain_corr + desired_scale; + voltage_gain_corr + desired_scale + cl_gain_mod; return desired_gain; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 9eb3aa21168..6de3f0bc18e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -1121,6 +1121,9 @@ #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00 #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8 +#define AR_PHY_CL_TAB_CL_GAIN_MOD 0x1f +#define AR_PHY_CL_TAB_CL_GAIN_MOD_S 0 + void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); #endif /* AR9003_PHY_H */ -- cgit v1.2.3-70-g09d2 From 05b60d4e3796c25ae1c78b10d5676ab27062d9b4 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 23 Jun 2011 20:14:29 +0530 Subject: ath9k_hw: make use of the gain_table_entry macro Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 6e9e892e528..de1972307b0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -236,7 +236,7 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah) memset(entry, 0, sizeof(ah->paprd_gain_table_entries)); memset(index, 0, sizeof(ah->paprd_gain_table_index)); - for (i = 0; i < 32; i++) { + for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) { entry[i] = REG_READ(ah, reg); index[i] = (entry[i] >> 24) & 0xff; reg += 4; @@ -741,7 +741,7 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) desired_gain = ar9003_get_desired_gain(ah, chain, train_power); gain_index = 0; - for (i = 0; i < 32; i++) { + for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) { if (ah->paprd_gain_table_index[i] >= desired_gain) break; gain_index++; -- cgit v1.2.3-70-g09d2 From 1d616b14cf3266684af46db614b7de03c7a8a538 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 23 Jun 2011 15:35:18 -0700 Subject: rt2x00: Fix unspeficied typo Signed-off-by: Joe Perches Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 167d45873dc..590047499e3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -54,7 +54,7 @@ * @QID_RX: RX queue * @QID_OTHER: None of the above (don't use, only present for completeness) * @QID_BEACON: Beacon queue (value unspecified, don't send it to device) - * @QID_ATIM: Atim queue (value unspeficied, don't send it to device) + * @QID_ATIM: Atim queue (value unspecified, don't send it to device) */ enum data_queue_qid { QID_AC_VO = 0, -- cgit v1.2.3-70-g09d2 From 428bc8c3960d2b18cb9f0d90cfe197ec9a822a54 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 24 Jun 2011 11:34:34 +0200 Subject: iwlagn: fix rmmod crash priv->bus.bus_specific pointer is used after priv structures was freed, in iwl_pci_remove(), what make ugly rmmod crash. This bug was introduced by current pci changes. On the way remove fake check, if prober error code is returned from .probe() function, .remove() will never be called be null drvdata. Signed-off-by: Stanislaw Gruszka Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 3927c802a5d..d582cc11145 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -496,14 +496,11 @@ static void iwl_pci_down(void *bus) static void __devexit iwl_pci_remove(struct pci_dev *pdev) { struct iwl_priv *priv = pci_get_drvdata(pdev); - - /* This can happen if probe failed */ - if (unlikely(!priv)) - return; + void *bus_specific = priv->bus.bus_specific; iwl_remove(priv); - iwl_pci_down(IWL_BUS_GET_PCI_BUS(&priv->bus)); + iwl_pci_down(bus_specific); } #ifdef CONFIG_PM -- cgit v1.2.3-70-g09d2 From f6b4e4d476b890e1ddebbed8ec4924f9c2750a31 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 24 Jun 2011 17:38:13 +0530 Subject: ath9k: Fix locking issue during tx completion The received tx status of aggregated frame without BlockAck may cause deaf state in AR5416 cards. So the driver does a reset to recover. When this happens, we release the pcu_lock before doing a reset as ath_rest acquires pcu_lock. This is ugly and also not atomic. Fixing this addresses the TX DMA failure also. ath_tx_complete_aggr can be called from different paths which takes different variants of spin_lock. This patch also addresses the following warning. WARNING: at kernel/timer.c:1011 del_timer_sync+0x4e/0x50() Call Trace: [] warn_slowpath_common+0x7a/0xb0 [] warn_slowpath_null+0x15/0x20 [] del_timer_sync+0x4e/0x50 [] ath_reset+0x3e/0x210 [ath9k] [] ? _raw_spin_unlock_bh+0x1f/0x30 [] ath_tx_complete_aggr.isra.26+0x54a/0xa40 [ath9k] Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 13 +++++++++---- drivers/net/wireless/ath/ath9k/xmit.c | 7 +++---- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 0b6e3b65bb0..e19a230dfff 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -385,7 +385,9 @@ void ath_beacon_tasklet(unsigned long data) ath_dbg(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); sc->sc_flags |= SC_OP_TSF_RESET; + spin_lock(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock(&sc->sc_pcu_lock); } return; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5ae303b11e6..9098aaad97a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -617,8 +617,11 @@ void ath_hw_check(struct work_struct *work) ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); if (busy >= 99) { - if (++sc->hw_busy_count >= 3) + if (++sc->hw_busy_count >= 3) { + spin_lock_bh(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); + } } else if (busy >= 0) sc->hw_busy_count = 0; @@ -637,7 +640,9 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) /* Rx is hung for more than 500ms. Reset it */ ath_dbg(common, ATH_DBG_RESET, "Possible RX hang, resetting"); + spin_lock_bh(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); count = 0; } } else @@ -674,7 +679,9 @@ void ath9k_tasklet(unsigned long data) if ((status & ATH9K_INT_FATAL) || (status & ATH9K_INT_BB_WATCHDOG)) { + spin_lock(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock(&sc->sc_pcu_lock); return; } @@ -980,7 +987,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) del_timer_sync(&common->ani.timer); ath9k_ps_wakeup(sc); - spin_lock_bh(&sc->sc_pcu_lock); ieee80211_stop_queues(hw); @@ -1023,7 +1029,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) } ieee80211_wake_queues(hw); - spin_unlock_bh(&sc->sc_pcu_lock); /* Start ANI */ if (!common->disable_ani) @@ -2326,9 +2331,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) ath9k_ps_wakeup(sc); spin_lock_bh(&sc->sc_pcu_lock); drain_txq = ath_drain_all_txq(sc, false); - spin_unlock_bh(&sc->sc_pcu_lock); if (!drain_txq) ath_reset(sc, false); + spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); ieee80211_wake_queues(hw); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index ec012b4317a..a1fed6c8ff9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -565,11 +565,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, rcu_read_unlock(); - if (needreset) { - spin_unlock_bh(&sc->sc_pcu_lock); + if (needreset) ath_reset(sc, false); - spin_lock_bh(&sc->sc_pcu_lock); - } } static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, @@ -2169,7 +2166,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) if (needreset) { ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, "tx hung, resetting the chip\n"); + spin_lock_bh(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); } ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, -- cgit v1.2.3-70-g09d2 From a5e5aa6cee4cdb967a1f1c33a31165062783ccea Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 24 Jun 2011 16:33:35 +0300 Subject: mwifiex: restore handling of NULL parameters Prior to a5ffddb70c5cab "mwifiex: remove casts of void pointers" the code assumed that the data_buf parameter could be a NULL pointer. The patch preserved some NULL checks but not consistently, so there was a potential for NULL dereferences and it changed the behavior. This patch restores the original behavior. Signed-off-by: Dan Carpenter Acked-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_cmd.c | 2 ++ drivers/net/wireless/mwifiex/sta_cmdresp.c | 29 ++++++++++++++++------------- 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index d85a0a60aa6..49b9c1309f7 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -779,6 +779,8 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, case HostCmd_ACT_GEN_SET: if (enable) ibss_coal->enable = cpu_to_le16(*enable); + else + ibss_coal->enable = 0; break; /* In other case.. Nothing to do */ diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index ad64c87b91d..6804239d87b 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -183,30 +183,32 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - u32 *ul_temp) + u32 *data_buf) { struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; u16 oid = le16_to_cpu(smib->oid); u16 query_type = le16_to_cpu(smib->query_type); + u32 ul_temp; dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," " query_type = %#x, buf size = %#x\n", oid, query_type, le16_to_cpu(smib->buf_size)); if (query_type == HostCmd_ACT_GEN_GET) { - if (ul_temp) - *ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); + ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); + if (data_buf) + *data_buf = ul_temp; switch (oid) { case FRAG_THRESH_I: dev_dbg(priv->adapter->dev, - "info: SNMP_RESP: FragThsd =%u\n", *ul_temp); + "info: SNMP_RESP: FragThsd =%u\n", ul_temp); break; case RTS_THRESH_I: dev_dbg(priv->adapter->dev, - "info: SNMP_RESP: RTSThsd =%u\n", *ul_temp); + "info: SNMP_RESP: RTSThsd =%u\n", ul_temp); break; case SHORT_RETRY_LIM_I: dev_dbg(priv->adapter->dev, - "info: SNMP_RESP: TxRetryCount=%u\n", *ul_temp); + "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp); break; default: break; @@ -622,22 +624,23 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - u16 *new_channel) + u16 *data_buf) { struct host_cmd_ds_802_11_rf_channel *rf_channel = &resp->params.rf_channel; + u16 new_channel = le16_to_cpu(rf_channel->current_channel); - if (new_channel) - *new_channel = le16_to_cpu(rf_channel->current_channel); - - if (priv->curr_bss_params.bss_descriptor.channel != *new_channel) { + if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", priv->curr_bss_params.bss_descriptor.channel, - *new_channel); + new_channel); /* Update the channel again */ - priv->curr_bss_params.bss_descriptor.channel = *new_channel; + priv->curr_bss_params.bss_descriptor.channel = new_channel; } + if (data_buf) + *data_buf = new_channel; + return 0; } -- cgit v1.2.3-70-g09d2 From 6691678dca1057840d8f25ee038541d4e4100b17 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 24 Jun 2011 19:39:37 +0400 Subject: iwlwifi: use pci_dev->revision, again Commit ff938e43d39e926de74b32a3656c190f979ab642 (net: use pci_dev->revision, again) already converted this driver to using the 'revision' field of 'struct pci_dev' but commit 084dd79172cb3aad11d2b7ee5628d57badca7c6e (iwlagn: move PCI related operations from probe and remove to PCI layer) has again added the code to read the PCI revision ID register... Signed-off-by: Sergei Shtylyov Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index d582cc11145..3b5844b60e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -383,7 +383,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_pci_bus *bus; - u8 rev_id; u16 pci_cmd; int err; @@ -440,8 +439,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (unsigned long long) pci_resource_len(pdev, 0)); pr_info("pci_resource_base = %p\n", bus->hw_base); - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); - pr_info("HW Revision ID = 0x%X\n", rev_id); + pr_info("HW Revision ID = 0x%X\n", pdev->revision); /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ -- cgit v1.2.3-70-g09d2 From aca7a3acb19a7a4b1084f6f2411f6eaf52dd79c0 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 23 Jun 2011 04:44:30 +0000 Subject: mlx4: use pci_dev->revision Commit 725c89997e03d71b09ea3c17c997da0712b9d835 (mlx4_en: Reporting HW revision in ethtool -i) added code to read the revision ID from the PCI configuration register while it's already stored by PCI subsystem in the 'revision' field of 'struct pci_dev'... While at it, move the code being changed a bit in order to not break the initialization sequence. Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/mlx4/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 3814fc9b114..0cb0431ee19 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -1230,11 +1230,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(&priv->pgdir_list); mutex_init(&priv->pgdir_mutex); - pci_read_config_byte(pdev, PCI_REVISION_ID, &dev->rev_id); - INIT_LIST_HEAD(&priv->bf_list); mutex_init(&priv->bf_mutex); + dev->rev_id = pdev->revision; + /* * Now reset the HCA before we touch the PCI capabilities or * attempt a firmware command, since a boot ROM may have left -- cgit v1.2.3-70-g09d2 From 9118f08a7794e9a4908afbb0f9bc9455325a5631 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 24 Jun 2011 04:33:01 +0000 Subject: can: bfin_can: simplify xmit id1 setup If we look closely, the 4 writes to TRANSMIT_CHL.id1 can be collapsed down into much simpler code. So do just that. This also fixes a build failure due to the I/O macros no longer getting pulled in. Their minor (and accidental) usage here gets dropped as part of the unification. Signed-off-by: Mike Frysinger Acked-by: Wolfgang Grandegger Acked-by: Kurt Van Dijck Signed-off-by: David S. Miller --- drivers/net/can/bfin_can.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index b6e890d2836..dc6ef4a9e02 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -243,21 +243,12 @@ static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev) /* fill id */ if (id & CAN_EFF_FLAG) { bfin_write16(®->chl[TRANSMIT_CHL].id0, id); - if (id & CAN_RTR_FLAG) - writew(((id & 0x1FFF0000) >> 16) | IDE | AME | RTR, - ®->chl[TRANSMIT_CHL].id1); - else - writew(((id & 0x1FFF0000) >> 16) | IDE | AME, - ®->chl[TRANSMIT_CHL].id1); - - } else { - if (id & CAN_RTR_FLAG) - writew((id << 2) | AME | RTR, - ®->chl[TRANSMIT_CHL].id1); - else - bfin_write16(®->chl[TRANSMIT_CHL].id1, - (id << 2) | AME); - } + val = ((id & 0x1FFF0000) >> 16) | IDE; + } else + val = (id << 2); + if (id & CAN_RTR_FLAG) + val |= RTR; + bfin_write16(®->chl[TRANSMIT_CHL].id1, val | AME); /* fill payload */ for (i = 0; i < 8; i += 2) { -- cgit v1.2.3-70-g09d2 From cfbf7586bc07cd6d14cd93ca56d8a3f90e248625 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 24 Jun 2011 04:33:02 +0000 Subject: can: bfin_can: auto-calculate accessor sizes Since we have a struct that defines the sizes of the registers, we don't need to explicitly use the 16bit read/write helpers. Let the code figure out which size access to make based on the size of the C type. There should be no functional changes here. Signed-off-by: Mike Frysinger Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller --- drivers/net/can/bfin_can.c | 118 ++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index dc6ef4a9e02..a1c5abc38cd 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -79,8 +79,8 @@ static int bfin_can_set_bittiming(struct net_device *dev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) timing |= SAM; - bfin_write16(®->clock, clk); - bfin_write16(®->timing, timing); + bfin_write(®->clock, clk); + bfin_write(®->timing, timing); dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n", clk, timing); @@ -96,16 +96,16 @@ static void bfin_can_set_reset_mode(struct net_device *dev) int i; /* disable interrupts */ - bfin_write16(®->mbim1, 0); - bfin_write16(®->mbim2, 0); - bfin_write16(®->gim, 0); + bfin_write(®->mbim1, 0); + bfin_write(®->mbim2, 0); + bfin_write(®->gim, 0); /* reset can and enter configuration mode */ - bfin_write16(®->control, SRS | CCR); + bfin_write(®->control, SRS | CCR); SSYNC(); - bfin_write16(®->control, CCR); + bfin_write(®->control, CCR); SSYNC(); - while (!(bfin_read16(®->control) & CCA)) { + while (!(bfin_read(®->control) & CCA)) { udelay(10); if (--timeout == 0) { dev_err(dev->dev.parent, @@ -119,33 +119,33 @@ static void bfin_can_set_reset_mode(struct net_device *dev) * by writing to CAN Mailbox Configuration Registers 1 and 2 * For all bits: 0 - Mailbox disabled, 1 - Mailbox enabled */ - bfin_write16(®->mc1, 0); - bfin_write16(®->mc2, 0); + bfin_write(®->mc1, 0); + bfin_write(®->mc2, 0); /* Set Mailbox Direction */ - bfin_write16(®->md1, 0xFFFF); /* mailbox 1-16 are RX */ - bfin_write16(®->md2, 0); /* mailbox 17-32 are TX */ + bfin_write(®->md1, 0xFFFF); /* mailbox 1-16 are RX */ + bfin_write(®->md2, 0); /* mailbox 17-32 are TX */ /* RECEIVE_STD_CHL */ for (i = 0; i < 2; i++) { - bfin_write16(®->chl[RECEIVE_STD_CHL + i].id0, 0); - bfin_write16(®->chl[RECEIVE_STD_CHL + i].id1, AME); - bfin_write16(®->chl[RECEIVE_STD_CHL + i].dlc, 0); - bfin_write16(®->msk[RECEIVE_STD_CHL + i].amh, 0x1FFF); - bfin_write16(®->msk[RECEIVE_STD_CHL + i].aml, 0xFFFF); + bfin_write(®->chl[RECEIVE_STD_CHL + i].id0, 0); + bfin_write(®->chl[RECEIVE_STD_CHL + i].id1, AME); + bfin_write(®->chl[RECEIVE_STD_CHL + i].dlc, 0); + bfin_write(®->msk[RECEIVE_STD_CHL + i].amh, 0x1FFF); + bfin_write(®->msk[RECEIVE_STD_CHL + i].aml, 0xFFFF); } /* RECEIVE_EXT_CHL */ for (i = 0; i < 2; i++) { - bfin_write16(®->chl[RECEIVE_EXT_CHL + i].id0, 0); - bfin_write16(®->chl[RECEIVE_EXT_CHL + i].id1, AME | IDE); - bfin_write16(®->chl[RECEIVE_EXT_CHL + i].dlc, 0); - bfin_write16(®->msk[RECEIVE_EXT_CHL + i].amh, 0x1FFF); - bfin_write16(®->msk[RECEIVE_EXT_CHL + i].aml, 0xFFFF); + bfin_write(®->chl[RECEIVE_EXT_CHL + i].id0, 0); + bfin_write(®->chl[RECEIVE_EXT_CHL + i].id1, AME | IDE); + bfin_write(®->chl[RECEIVE_EXT_CHL + i].dlc, 0); + bfin_write(®->msk[RECEIVE_EXT_CHL + i].amh, 0x1FFF); + bfin_write(®->msk[RECEIVE_EXT_CHL + i].aml, 0xFFFF); } - bfin_write16(®->mc2, BIT(TRANSMIT_CHL - 16)); - bfin_write16(®->mc1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL)); + bfin_write(®->mc2, BIT(TRANSMIT_CHL - 16)); + bfin_write(®->mc1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL)); SSYNC(); priv->can.state = CAN_STATE_STOPPED; @@ -160,9 +160,9 @@ static void bfin_can_set_normal_mode(struct net_device *dev) /* * leave configuration mode */ - bfin_write16(®->control, bfin_read16(®->control) & ~CCR); + bfin_write(®->control, bfin_read(®->control) & ~CCR); - while (bfin_read16(®->status) & CCA) { + while (bfin_read(®->status) & CCA) { udelay(10); if (--timeout == 0) { dev_err(dev->dev.parent, @@ -174,25 +174,25 @@ static void bfin_can_set_normal_mode(struct net_device *dev) /* * clear _All_ tx and rx interrupts */ - bfin_write16(®->mbtif1, 0xFFFF); - bfin_write16(®->mbtif2, 0xFFFF); - bfin_write16(®->mbrif1, 0xFFFF); - bfin_write16(®->mbrif2, 0xFFFF); + bfin_write(®->mbtif1, 0xFFFF); + bfin_write(®->mbtif2, 0xFFFF); + bfin_write(®->mbrif1, 0xFFFF); + bfin_write(®->mbrif2, 0xFFFF); /* * clear global interrupt status register */ - bfin_write16(®->gis, 0x7FF); /* overwrites with '1' */ + bfin_write(®->gis, 0x7FF); /* overwrites with '1' */ /* * Initialize Interrupts * - set bits in the mailbox interrupt mask register * - global interrupt mask */ - bfin_write16(®->mbim1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL)); - bfin_write16(®->mbim2, BIT(TRANSMIT_CHL - 16)); + bfin_write(®->mbim1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL)); + bfin_write(®->mbim2, BIT(TRANSMIT_CHL - 16)); - bfin_write16(®->gim, EPIM | BOIM | RMLIM); + bfin_write(®->gim, EPIM | BOIM | RMLIM); SSYNC(); } @@ -242,28 +242,28 @@ static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev) /* fill id */ if (id & CAN_EFF_FLAG) { - bfin_write16(®->chl[TRANSMIT_CHL].id0, id); + bfin_write(®->chl[TRANSMIT_CHL].id0, id); val = ((id & 0x1FFF0000) >> 16) | IDE; } else val = (id << 2); if (id & CAN_RTR_FLAG) val |= RTR; - bfin_write16(®->chl[TRANSMIT_CHL].id1, val | AME); + bfin_write(®->chl[TRANSMIT_CHL].id1, val | AME); /* fill payload */ for (i = 0; i < 8; i += 2) { val = ((7 - i) < dlc ? (data[7 - i]) : 0) + ((6 - i) < dlc ? (data[6 - i] << 8) : 0); - bfin_write16(®->chl[TRANSMIT_CHL].data[i], val); + bfin_write(®->chl[TRANSMIT_CHL].data[i], val); } /* fill data length code */ - bfin_write16(®->chl[TRANSMIT_CHL].dlc, dlc); + bfin_write(®->chl[TRANSMIT_CHL].dlc, dlc); can_put_echo_skb(skb, dev, 0); /* set transmit request */ - bfin_write16(®->trs2, BIT(TRANSMIT_CHL - 16)); + bfin_write(®->trs2, BIT(TRANSMIT_CHL - 16)); return 0; } @@ -286,26 +286,26 @@ static void bfin_can_rx(struct net_device *dev, u16 isrc) /* get id */ if (isrc & BIT(RECEIVE_EXT_CHL)) { /* extended frame format (EFF) */ - cf->can_id = ((bfin_read16(®->chl[RECEIVE_EXT_CHL].id1) + cf->can_id = ((bfin_read(®->chl[RECEIVE_EXT_CHL].id1) & 0x1FFF) << 16) - + bfin_read16(®->chl[RECEIVE_EXT_CHL].id0); + + bfin_read(®->chl[RECEIVE_EXT_CHL].id0); cf->can_id |= CAN_EFF_FLAG; obj = RECEIVE_EXT_CHL; } else { /* standard frame format (SFF) */ - cf->can_id = (bfin_read16(®->chl[RECEIVE_STD_CHL].id1) + cf->can_id = (bfin_read(®->chl[RECEIVE_STD_CHL].id1) & 0x1ffc) >> 2; obj = RECEIVE_STD_CHL; } - if (bfin_read16(®->chl[obj].id1) & RTR) + if (bfin_read(®->chl[obj].id1) & RTR) cf->can_id |= CAN_RTR_FLAG; /* get data length code */ - cf->can_dlc = get_can_dlc(bfin_read16(®->chl[obj].dlc) & 0xF); + cf->can_dlc = get_can_dlc(bfin_read(®->chl[obj].dlc) & 0xF); /* get payload */ for (i = 0; i < 8; i += 2) { - val = bfin_read16(®->chl[obj].data[i]); + val = bfin_read(®->chl[obj].data[i]); cf->data[7 - i] = (7 - i) < cf->can_dlc ? val : 0; cf->data[6 - i] = (6 - i) < cf->can_dlc ? (val >> 8) : 0; } @@ -359,7 +359,7 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING || state == CAN_STATE_ERROR_PASSIVE)) { - u16 cec = bfin_read16(®->cec); + u16 cec = bfin_read(®->cec); u8 rxerr = cec; u8 txerr = cec >> 8; @@ -410,23 +410,23 @@ irqreturn_t bfin_can_interrupt(int irq, void *dev_id) struct net_device_stats *stats = &dev->stats; u16 status, isrc; - if ((irq == priv->tx_irq) && bfin_read16(®->mbtif2)) { + if ((irq == priv->tx_irq) && bfin_read(®->mbtif2)) { /* transmission complete interrupt */ - bfin_write16(®->mbtif2, 0xFFFF); + bfin_write(®->mbtif2, 0xFFFF); stats->tx_packets++; - stats->tx_bytes += bfin_read16(®->chl[TRANSMIT_CHL].dlc); + stats->tx_bytes += bfin_read(®->chl[TRANSMIT_CHL].dlc); can_get_echo_skb(dev, 0); netif_wake_queue(dev); - } else if ((irq == priv->rx_irq) && bfin_read16(®->mbrif1)) { + } else if ((irq == priv->rx_irq) && bfin_read(®->mbrif1)) { /* receive interrupt */ - isrc = bfin_read16(®->mbrif1); - bfin_write16(®->mbrif1, 0xFFFF); + isrc = bfin_read(®->mbrif1); + bfin_write(®->mbrif1, 0xFFFF); bfin_can_rx(dev, isrc); - } else if ((irq == priv->err_irq) && bfin_read16(®->gis)) { + } else if ((irq == priv->err_irq) && bfin_read(®->gis)) { /* error interrupt */ - isrc = bfin_read16(®->gis); - status = bfin_read16(®->esr); - bfin_write16(®->gis, 0x7FF); + isrc = bfin_read(®->gis); + status = bfin_read(®->esr); + bfin_write(®->gis, 0x7FF); bfin_can_err(dev, isrc, status); } else { return IRQ_NONE; @@ -631,9 +631,9 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) if (netif_running(dev)) { /* enter sleep mode */ - bfin_write16(®->control, bfin_read16(®->control) | SMR); + bfin_write(®->control, bfin_read(®->control) | SMR); SSYNC(); - while (!(bfin_read16(®->intr) & SMACK)) { + while (!(bfin_read(®->intr) & SMACK)) { udelay(10); if (--timeout == 0) { dev_err(dev->dev.parent, @@ -654,7 +654,7 @@ static int bfin_can_resume(struct platform_device *pdev) if (netif_running(dev)) { /* leave sleep mode */ - bfin_write16(®->intr, 0); + bfin_write(®->intr, 0); SSYNC(); } -- cgit v1.2.3-70-g09d2 From 72e85c45b9541e1f3d233e775da1dc6f68b85867 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 23 Jun 2011 13:04:39 +0000 Subject: vmxnet3: Convert to new vlan model. This converts the vmxnet3 driver to use the new vlan model. In doing so it fixes missing tags in tcpdump and failure to do checksum offload when tx vlan offload is disabled. CC: Shreyas Bhatewara CC: VMware PV-Drivers Signed-off-by: Jesse Gross Signed-off-by: Scott J. Goldman Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 111 +++++++++------------------------- drivers/net/vmxnet3/vmxnet3_ethtool.c | 9 ++- drivers/net/vmxnet3/vmxnet3_int.h | 3 +- 3 files changed, 40 insertions(+), 83 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 33097ec1c51..c84b1dd02a7 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -918,7 +918,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + skb_shinfo(skb)->nr_frags + 1; - ctx.ipv4 = (skb->protocol == cpu_to_be16(ETH_P_IP)); + ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); ctx.mss = skb_shinfo(skb)->gso_size; if (ctx.mss) { @@ -1231,12 +1231,10 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, (union Vmxnet3_GenericDesc *)rcd); skb->protocol = eth_type_trans(skb, adapter->netdev); - if (unlikely(adapter->vlan_grp && rcd->ts)) { - vlan_hwaccel_receive_skb(skb, - adapter->vlan_grp, rcd->tci); - } else { - netif_receive_skb(skb); - } + if (unlikely(rcd->ts)) + __vlan_hwaccel_put_tag(skb, rcd->tci); + + netif_receive_skb(skb); ctx->skb = NULL; } @@ -1856,79 +1854,18 @@ vmxnet3_free_irqs(struct vmxnet3_adapter *adapter) } } -static void -vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) -{ - struct vmxnet3_adapter *adapter = netdev_priv(netdev); - struct Vmxnet3_DriverShared *shared = adapter->shared; - u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; - unsigned long flags; - - if (grp) { - /* add vlan rx stripping. */ - if (adapter->netdev->features & NETIF_F_HW_VLAN_RX) { - int i; - adapter->vlan_grp = grp; - - /* - * Clear entire vfTable; then enable untagged pkts. - * Note: setting one entry in vfTable to non-zero turns - * on VLAN rx filtering. - */ - for (i = 0; i < VMXNET3_VFT_SIZE; i++) - vfTable[i] = 0; - - VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0); - spin_lock_irqsave(&adapter->cmd_lock, flags); - VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, - VMXNET3_CMD_UPDATE_VLAN_FILTERS); - spin_unlock_irqrestore(&adapter->cmd_lock, flags); - } else { - printk(KERN_ERR "%s: vlan_rx_register when device has " - "no NETIF_F_HW_VLAN_RX\n", netdev->name); - } - } else { - /* remove vlan rx stripping. */ - struct Vmxnet3_DSDevRead *devRead = &shared->devRead; - adapter->vlan_grp = NULL; - - if (devRead->misc.uptFeatures & UPT1_F_RXVLAN) { - int i; - - for (i = 0; i < VMXNET3_VFT_SIZE; i++) { - /* clear entire vfTable; this also disables - * VLAN rx filtering - */ - vfTable[i] = 0; - } - spin_lock_irqsave(&adapter->cmd_lock, flags); - VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, - VMXNET3_CMD_UPDATE_VLAN_FILTERS); - spin_unlock_irqrestore(&adapter->cmd_lock, flags); - } - } -} - static void vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter) { - if (adapter->vlan_grp) { - u16 vid; - u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; - bool activeVlan = false; + u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; + u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (vlan_group_get_device(adapter->vlan_grp, vid)) { - VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid); - activeVlan = true; - } - } - if (activeVlan) { - /* continue to allow untagged pkts */ - VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0); - } - } + /* allow untagged pkts */ + VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0); + + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid); } @@ -1944,6 +1881,8 @@ vmxnet3_vlan_rx_add_vid(struct net_device *netdev, u16 vid) VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_VLAN_FILTERS); spin_unlock_irqrestore(&adapter->cmd_lock, flags); + + set_bit(vid, adapter->active_vlans); } @@ -1959,6 +1898,8 @@ vmxnet3_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_VLAN_FILTERS); spin_unlock_irqrestore(&adapter->cmd_lock, flags); + + clear_bit(vid, adapter->active_vlans); } @@ -1995,8 +1936,14 @@ vmxnet3_set_mc(struct net_device *netdev) u8 *new_table = NULL; u32 new_mode = VMXNET3_RXM_UCAST; - if (netdev->flags & IFF_PROMISC) + if (netdev->flags & IFF_PROMISC) { + u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; + memset(vfTable, 0, VMXNET3_VFT_SIZE * sizeof(*vfTable)); + new_mode |= VMXNET3_RXM_PROMISC; + } else { + vmxnet3_restore_vlan(adapter); + } if (netdev->flags & IFF_BROADCAST) new_mode |= VMXNET3_RXM_BCAST; @@ -2030,6 +1977,8 @@ vmxnet3_set_mc(struct net_device *netdev) rxConf->rxMode = cpu_to_le32(new_mode); VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_RX_MODE); + VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, + VMXNET3_CMD_UPDATE_VLAN_FILTERS); } VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, @@ -2639,12 +2588,13 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64) netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX | - NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_LRO; + NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_LRO; if (dma64) netdev->features |= NETIF_F_HIGHDMA; - netdev->vlan_features = netdev->hw_features & ~NETIF_F_HW_VLAN_TX; - netdev->features = netdev->hw_features | - NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; + netdev->vlan_features = netdev->hw_features & + ~(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); + netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_FILTER; netdev_info(adapter->netdev, "features: sg csum vlan jf tso tsoIPv6 lro%s\n", @@ -2865,7 +2815,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, .ndo_get_stats64 = vmxnet3_get_stats64, .ndo_tx_timeout = vmxnet3_tx_timeout, .ndo_set_multicast_list = vmxnet3_set_mc, - .ndo_vlan_rx_register = vmxnet3_vlan_rx_register, .ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index bba7c15de5b..27400edeef5 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -268,7 +268,7 @@ int vmxnet3_set_features(struct net_device *netdev, u32 features) unsigned long flags; u32 changed = features ^ netdev->features; - if (changed & (NETIF_F_RXCSUM|NETIF_F_LRO)) { + if (changed & (NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_RX)) { if (features & NETIF_F_RXCSUM) adapter->shared->devRead.misc.uptFeatures |= UPT1_F_RXCSUM; @@ -284,6 +284,13 @@ int vmxnet3_set_features(struct net_device *netdev, u32 features) adapter->shared->devRead.misc.uptFeatures &= ~UPT1_F_LRO; + if (features & NETIF_F_HW_VLAN_RX) + adapter->shared->devRead.misc.uptFeatures |= + UPT1_F_RXVLAN; + else + adapter->shared->devRead.misc.uptFeatures &= + ~UPT1_F_RXVLAN; + spin_lock_irqsave(&adapter->cmd_lock, flags); VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_FEATURE); diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 0e567c249d6..2e37985809d 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -27,6 +27,7 @@ #ifndef _VMXNET3_INT_H #define _VMXNET3_INT_H +#include #include #include #include @@ -315,7 +316,7 @@ struct vmxnet3_intr { struct vmxnet3_adapter { struct vmxnet3_tx_queue tx_queue[VMXNET3_DEVICE_MAX_TX_QUEUES]; struct vmxnet3_rx_queue rx_queue[VMXNET3_DEVICE_MAX_RX_QUEUES]; - struct vlan_group *vlan_grp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct vmxnet3_intr intr; spinlock_t cmd_lock; struct Vmxnet3_DriverShared *shared; -- cgit v1.2.3-70-g09d2 From ec0d75518cb06261f1823fa2713fe52b9b26455e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 23 Jun 2011 16:02:38 +0000 Subject: net: sh_eth: tidyup compile warning This patch tidyup below warning ${LINUX}/drivers/net/sh_eth.c:1773: warning: 'mdp' may be used uninitialized in this function Cc: Yoshihiro Shimoda Signed-off-by: Kuninori Morimoto Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 8a72a979ee7..96a629f1678 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1770,7 +1770,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) int ret, devno = 0; struct resource *res; struct net_device *ndev = NULL; - struct sh_eth_private *mdp; + struct sh_eth_private *mdp = NULL; struct sh_eth_plat_data *pd; /* get base addr */ @@ -1888,7 +1888,7 @@ out_unregister: out_release: /* net_dev free */ - if (mdp->tsu_addr) + if (mdp && mdp->tsu_addr) iounmap(mdp->tsu_addr); if (ndev) free_netdev(ndev); -- cgit v1.2.3-70-g09d2 From 708ebb3a51489e70bc2b67b2772deea336eba849 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 12:56:50 +0000 Subject: tg3: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. Use the value from pci_dev instead of checking in the driver and saving it off the the driver specific structure. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. v2 of the patch re-adds the PCI_EXPRESS flag and adds comments describing why it is necessary. [ pdev->pcie_cap --> pci_pcie_cap(pdev) -DaveM ] Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/tg3.c | 25 ++++++++++++++----------- drivers/net/tg3.h | 5 +---- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 97cd02d0802..8211b9a29d6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2679,11 +2679,11 @@ static int tg3_power_down_prepare(struct tg3 *tp) u16 lnkctl; pci_read_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_LNKCTL, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, &lnkctl); lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN; pci_write_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_LNKCTL, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, lnkctl); } @@ -3485,7 +3485,7 @@ relink: u16 oldlnkctl, newlnkctl; pci_read_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_LNKCTL, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, &oldlnkctl); if (tp->link_config.active_speed == SPEED_100 || tp->link_config.active_speed == SPEED_10) @@ -3494,7 +3494,7 @@ relink: newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN; if (newlnkctl != oldlnkctl) pci_write_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_LNKCTL, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, newlnkctl); } @@ -7226,7 +7226,7 @@ static int tg3_chip_reset(struct tg3 *tp) udelay(120); - if (tg3_flag(tp, PCI_EXPRESS) && tp->pcie_cap) { + if (tg3_flag(tp, PCI_EXPRESS) && pci_pcie_cap(tp->pdev)) { u16 val16; if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) { @@ -7244,7 +7244,7 @@ static int tg3_chip_reset(struct tg3 *tp) /* Clear the "no snoop" and "relaxed ordering" bits. */ pci_read_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_DEVCTL, + pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL, &val16); val16 &= ~(PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN); @@ -7255,14 +7255,14 @@ static int tg3_chip_reset(struct tg3 *tp) if (!tg3_flag(tp, CPMU_PRESENT)) val16 &= ~PCI_EXP_DEVCTL_PAYLOAD; pci_write_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_DEVCTL, + pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL, val16); pcie_set_readrq(tp->pdev, tp->pcie_readrq); /* Clear error status */ pci_write_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_DEVSTA, + pci_pcie_cap(tp->pdev) + PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED | PCI_EXP_DEVSTA_FED | @@ -13777,8 +13777,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, &pci_state_reg); - tp->pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP); - if (tp->pcie_cap != 0) { + if (pci_is_pcie(tp->pdev)) { u16 lnkctl; tg3_flag_set(tp, PCI_EXPRESS); @@ -13791,7 +13790,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) pcie_set_readrq(tp->pdev, tp->pcie_readrq); pci_read_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_LNKCTL, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, &lnkctl); if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == @@ -13808,6 +13807,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tg3_flag_set(tp, L1PLLPD_EN); } } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) { + /* BCM5785 devices are effectively PCIe devices, and should + * follow PCIe codepaths, but do not have a PCIe capabilities + * section. + */ tg3_flag_set(tp, PCI_EXPRESS); } else if (!tg3_flag(tp, 5705_PLUS) || tg3_flag(tp, 5780_CLASS)) { diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index bedc3b4557b..5f250aef7c9 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2857,7 +2857,7 @@ enum TG3_FLAGS { TG3_FLAG_IS_5788, TG3_FLAG_MAX_RXPEND_64, TG3_FLAG_TSO_CAPABLE, - TG3_FLAG_PCI_EXPRESS, + TG3_FLAG_PCI_EXPRESS, /* BCM5785 + pci_is_pcie() */ TG3_FLAG_ASF_NEW_HANDSHAKE, TG3_FLAG_HW_AUTONEG, TG3_FLAG_IS_NIC, @@ -3022,10 +3022,7 @@ struct tg3 { int pm_cap; int msi_cap; - union { int pcix_cap; - int pcie_cap; - }; int pcie_readrq; struct mii_bus *mdio_bus; -- cgit v1.2.3-70-g09d2 From a875a4c7404c8e259236b650136b8a603923daf9 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:42:17 +0000 Subject: mlx4: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/mlx4/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c index e5741dab382..11e7c1cb99b 100644 --- a/drivers/net/mlx4/reset.c +++ b/drivers/net/mlx4/reset.c @@ -77,7 +77,7 @@ int mlx4_reset(struct mlx4_dev *dev) goto out; } - pcie_cap = pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); + pcie_cap = pci_pcie_cap(dev->pdev); for (i = 0; i < 64; ++i) { if (i == 22 || i == 23) -- cgit v1.2.3-70-g09d2 From 6532e9cb33221a31c8514441a972486af713ad6e Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:42:49 +0000 Subject: cxgb3: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/cxgb3/common.h | 1 - drivers/net/cxgb3/t3_hw.c | 11 ++++------- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index 056ee8c831f..df01b634324 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -367,7 +367,6 @@ struct vpd_params { struct pci_params { unsigned int vpd_cap_addr; - unsigned int pcie_cap_addr; unsigned short speed; unsigned char width; unsigned char variant; diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index c688421da9c..44ac2f40b64 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -3290,22 +3290,20 @@ static void config_pcie(struct adapter *adap) unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt; pci_read_config_word(adap->pdev, - adap->params.pci.pcie_cap_addr + PCI_EXP_DEVCTL, + adap->pdev->pcie_cap + PCI_EXP_DEVCTL, &val); pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5; pci_read_config_word(adap->pdev, 0x2, &devid); if (devid == 0x37) { pci_write_config_word(adap->pdev, - adap->params.pci.pcie_cap_addr + - PCI_EXP_DEVCTL, + adap->pdev->pcie_cap + PCI_EXP_DEVCTL, val & ~PCI_EXP_DEVCTL_READRQ & ~PCI_EXP_DEVCTL_PAYLOAD); pldsize = 0; } - pci_read_config_word(adap->pdev, - adap->params.pci.pcie_cap_addr + PCI_EXP_LNKCTL, + pci_read_config_word(adap->pdev, adap->pdev->pcie_cap + PCI_EXP_LNKCTL, &val); fst_trn_tx = G_NUMFSTTRNSEQ(t3_read_reg(adap, A_PCIE_PEX_CTRL0)); @@ -3429,12 +3427,11 @@ static void get_pci_mode(struct adapter *adapter, struct pci_params *p) static unsigned short speed_map[] = { 33, 66, 100, 133 }; u32 pci_mode, pcie_cap; - pcie_cap = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); + pcie_cap = pci_pcie_cap(adapter->pdev); if (pcie_cap) { u16 val; p->variant = PCI_VARIANT_PCIE; - p->pcie_cap_addr = pcie_cap; pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA, &val); p->width = (val >> 4) & 0x3f; -- cgit v1.2.3-70-g09d2 From 353064de8af3bf46757376db66c29fa87a9fda3a Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:43:47 +0000 Subject: e1000e: remove unnecessary reads of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/e1000e/lib.c | 2 +- drivers/net/e1000e/netdev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index dd8ab05b559..bd72b8167df 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -56,7 +56,7 @@ s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) struct e1000_adapter *adapter = hw->adapter; u16 pcie_link_status, cap_offset; - cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); + cap_offset = adapter->pdev->pcie_cap; if (!cap_offset) { bus->width = e1000_bus_width_unknown; } else { diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3bf52499743..ed7a93d356f 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5318,7 +5318,7 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, */ if (adapter->flags & FLAG_IS_QUAD_PORT) { struct pci_dev *us_dev = pdev->bus->self; - int pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP); + int pos = pci_pcie_cap(us_dev); u16 devctl; pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl); -- cgit v1.2.3-70-g09d2 From bdaae04c65ef88645f50dabb43992033c754c4a7 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:44:01 +0000 Subject: igb: remove unnecessary reads of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 6e67258c4b4..d6c4bd8438e 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -6267,7 +6267,7 @@ s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) struct igb_adapter *adapter = hw->back; u16 cap_offset; - cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); + cap_offset = adapter->pdev->pcie_cap; if (!cap_offset) return -E1000_ERR_CONFIG; @@ -6281,7 +6281,7 @@ s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) struct igb_adapter *adapter = hw->back; u16 cap_offset; - cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); + cap_offset = adapter->pdev->pcie_cap; if (!cap_offset) return -E1000_ERR_CONFIG; -- cgit v1.2.3-70-g09d2 From e82760e7d6498d24d1a92f22767ba578c8980a6d Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:44:43 +0000 Subject: bnx2: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Also, pci_is_pcie is a better way of determining if the device is PCIE or not (as it uses the same saved PCIE capability offset). Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 74580bb175f..7915d140457 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -7911,9 +7911,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->chip_id = REG_RD(bp, BNX2_MISC_ID); if (CHIP_NUM(bp) == CHIP_NUM_5709) { - if (pci_find_capability(pdev, PCI_CAP_ID_EXP) == 0) { - dev_err(&pdev->dev, - "Cannot find PCIE capability, aborting\n"); + if (!pci_is_pcie(pdev)) { + dev_err(&pdev->dev, "Not PCIE, aborting\n"); rc = -EIO; goto err_out_unmap; } -- cgit v1.2.3-70-g09d2 From 77c98e6a7a3ab76340b315d31fe1edded17cba15 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:45:12 +0000 Subject: bnx2x: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Also, pci_is_pcie is a better way of determining if the device is PCIE or not (as it uses the same saved PCIE capability offset). Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 1 - drivers/net/bnx2x/bnx2x_main.c | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index eff78a439ee..0d4b9812624 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1156,7 +1156,6 @@ struct bnx2x { #define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) int pm_cap; - int pcie_cap; int mrrs; struct delayed_work sp_task; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index af5721754f6..b6f82ebc30a 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1222,7 +1222,7 @@ static inline u8 bnx2x_is_pcie_pending(struct pci_dev *dev) int pos; u16 status; - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + pos = pci_pcie_cap(dev); if (!pos) return false; @@ -5498,7 +5498,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp) int r_order, w_order; pci_read_config_word(bp->pdev, - bp->pcie_cap + PCI_EXP_DEVCTL, &devctl); + bp->pdev->pcie_cap + PCI_EXP_DEVCTL, &devctl); DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl); w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); if (bp->mrrs == -1) @@ -9759,10 +9759,8 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, goto err_out_release; } - bp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (bp->pcie_cap == 0) { - dev_err(&bp->pdev->dev, - "Cannot find PCI Express capability, aborting\n"); + if (!pci_is_pcie(pdev)) { + dev_err(&bp->pdev->dev, "Not PCI Express, aborting\n"); rc = -EIO; goto err_out_release; } -- cgit v1.2.3-70-g09d2 From d3aa0cb44f2cfcdfa6df1bd40b9c182b35528849 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:45:44 +0000 Subject: niu: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/niu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 1c7b790217f..cd6c2317e29 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9797,7 +9797,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, goto err_out_disable_pdev; } - pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + pos = pci_pcie_cap(pdev); if (pos <= 0) { dev_err(&pdev->dev, "Cannot find PCI Express capability, aborting\n"); goto err_out_free_res; -- cgit v1.2.3-70-g09d2 From e44daaded19baf8b7cf9ab3dedad8a01b8c49251 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:46:31 +0000 Subject: r8169: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. Use the value from pci_dev instead of checking in the driver and saving it off the the driver specific structure. Also, it will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/r8169.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index f8c4435afe5..fbd68383ca6 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -659,7 +659,6 @@ struct rtl8169_private { unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); unsigned int (*link_ok)(void __iomem *); int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); - int pcie_cap; struct delayed_work task; unsigned features; @@ -3444,9 +3443,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } tp->mmio_addr = ioaddr; - tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (!tp->pcie_cap) - netif_info(tp, probe, dev, "no PCI Express capability\n"); + if (!pci_is_pcie(pdev)) + netif_info(tp, probe, dev, "not PCI Express\n"); RTL_W16(IntrMask, 0x0000); @@ -3898,9 +3896,7 @@ static void rtl_hw_start_8169(struct net_device *dev) static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) { - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - int cap = tp->pcie_cap; + int cap = pci_pcie_cap(pdev); if (cap) { u16 ctl; @@ -3948,9 +3944,7 @@ static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int l static void rtl_disable_clock_request(struct pci_dev *pdev) { - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - int cap = tp->pcie_cap; + int cap = pci_pcie_cap(pdev); if (cap) { u16 ctl; @@ -3963,9 +3957,7 @@ static void rtl_disable_clock_request(struct pci_dev *pdev) static void rtl_enable_clock_request(struct pci_dev *pdev) { - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - int cap = tp->pcie_cap; + int cap = pci_pcie_cap(pdev); if (cap) { u16 ctl; @@ -4395,7 +4387,7 @@ static void rtl_hw_start_8101(struct net_device *dev) if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) { - int cap = tp->pcie_cap; + int cap = pci_pcie_cap(pdev); if (cap) { pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, -- cgit v1.2.3-70-g09d2 From 1a10ccae9003826cee6f2c625fa4caf51cfc0f40 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:46:56 +0000 Subject: sky2: remove unnecessary reads of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Also, pci_is_pcie is a better way of determining if the device is PCIE or not (as it uses the same saved PCIE capability offset). Signed-off-by: Jon Mason Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d252cb123a5..e14b86e27dc 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1449,7 +1449,7 @@ static void sky2_rx_start(struct sky2_port *sky2) sky2_qset(hw, rxq); /* On PCI express lowering the watermark gives better performance */ - if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) + if (pci_is_pcie(hw->pdev)) sky2_write32(hw, Q_ADDR(rxq, Q_WM), BMU_WM_PEX); /* These chips have no ram buffer? @@ -3072,7 +3072,7 @@ static void sky2_reset(struct sky2_hw *hw) { struct pci_dev *pdev = hw->pdev; u16 status; - int i, cap; + int i; u32 hwe_mask = Y2_HWE_ALL_MASK; /* disable ASF */ @@ -3108,8 +3108,7 @@ static void sky2_reset(struct sky2_hw *hw) sky2_write8(hw, B0_CTST, CS_MRST_CLR); - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (cap) { + if (pci_is_pcie(pdev)) { sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, 0xfffffffful); @@ -3171,11 +3170,11 @@ static void sky2_reset(struct sky2_hw *hw) /* check if PSMv2 was running before */ reg = sky2_pci_read16(hw, PSM_CONFIG_REG3); - if (reg & PCI_EXP_LNKCTL_ASPMC) { - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (reg & PCI_EXP_LNKCTL_ASPMC) /* restore the PCIe Link Control register */ - sky2_pci_write16(hw, cap + PCI_EXP_LNKCTL, reg); - } + sky2_pci_write16(hw, pdev->pcie_cap + PCI_EXP_LNKCTL, + reg); + sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */ -- cgit v1.2.3-70-g09d2 From 95cab7386bef62f8c7535d4726573ce230778e7b Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 07:48:11 +0000 Subject: vxge: remove unnecessary reads of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 857618afa14..1520c574cb2 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -753,12 +753,11 @@ static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) static enum vxge_hw_status __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev) { - int exp_cap; + struct pci_dev *dev = hldev->pdev; u16 lnk; /* Get the negotiated link width and speed from PCI config space */ - exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP); - pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); + pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk); if ((lnk & PCI_EXP_LNKSTA_CLS) != 1) return VXGE_HW_ERR_INVALID_PCI_INFO; @@ -1982,13 +1981,11 @@ exit: u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev) { - int link_width, exp_cap; + struct pci_dev *dev = hldev->pdev; u16 lnk; - exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP); - pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); - link_width = (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4; - return link_width; + pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk); + return (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4; } /* -- cgit v1.2.3-70-g09d2 From 213ade8ca8c854435d99e4d2927655b2ae4191e9 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 24 Jun 2011 14:24:35 +0000 Subject: vmxnet3: Enable GRO support. When receiving packets from another guest on the same hypervisor, it's generally possible to receive large packets because no segmentation is necessary and these packets are handled by LRO. However, when doing routing or bridging we must disable LRO and lose this benefit. In these cases GRO can still be used and it is very effective because the packets which are segmented in the hypervisor are received very close together and can easily be merged. CC: Shreyas Bhatewara CC: Scott Goldman CC: VMware PV-Drivers Signed-off-by: Jesse Gross Signed-off-by: Scott J. Goldman Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index c84b1dd02a7..2c1473686ab 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1234,7 +1234,10 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, if (unlikely(rcd->ts)) __vlan_hwaccel_put_tag(skb, rcd->tci); - netif_receive_skb(skb); + if (adapter->netdev->features & NETIF_F_LRO) + netif_receive_skb(skb); + else + napi_gro_receive(&rq->napi, skb); ctx->skb = NULL; } -- cgit v1.2.3-70-g09d2 From 8d0f7cea7aa1bb63ddd0e94589d2c33bc99f0d9a Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 29 Jun 2011 02:55:28 -0700 Subject: net: include io.h in sja1000_of_platform.c for iounmap etc fixes these build errors: drivers/net/can/sja1000/sja1000_of_platform.c: In function 'sja1000_ofp_read_reg': drivers/net/can/sja1000/sja1000_of_platform.c:61:2: error: implicit declaration of function 'in_8' drivers/net/can/sja1000/sja1000_of_platform.c: In function 'sja1000_ofp_write_reg': drivers/net/can/sja1000/sja1000_of_platform.c:67:2: error: implicit declaration of function 'out_8' drivers/net/can/sja1000/sja1000_of_platform.c: In function 'sja1000_ofp_remove': drivers/net/can/sja1000/sja1000_of_platform.c:81:2: error: implicit declaration of function 'iounmap' drivers/net/can/sja1000/sja1000_of_platform.c: In function 'sja1000_ofp_probe': drivers/net/can/sja1000/sja1000_of_platform.c:113:2: error: implicit declaration of function 'ioremap_nocache' drivers/net/can/sja1000/sja1000_of_platform.c:113:7: warning: assignment makes pointer from integer without a cast Caused by commit b7f080cfe223 ("net: remove mm.h inclusion from netdevice.h"). Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/can/sja1000/sja1000_of_platform.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 9793df6e345..cee6ba2b8b5 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3-70-g09d2 From 84cac3989a0fa009fff63c315759006560c91c13 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 29 Jun 2011 02:55:59 -0700 Subject: net: include dma-mapping.h in ll_temac_main.c for dma_map_single etc fixes thses build errors: drivers/net/ll_temac_main.c: In function 'temac_dma_bd_release': drivers/net/ll_temac_main.c:209:4: error: implicit declaration of function 'dma_unmap_single' drivers/net/ll_temac_main.c:215:3: error: implicit declaration of function 'dma_free_coherent' drivers/net/ll_temac_main.c: In function 'temac_dma_bd_init': drivers/net/ll_temac_main.c:243:2: error: implicit declaration of function 'dma_alloc_coherent' drivers/net/ll_temac_main.c:243:14: warning: assignment makes pointer from integer without a cast drivers/net/ll_temac_main.c:251:14: warning: assignment makes pointer from integer without a cast drivers/net/ll_temac_main.c:280:3: error: implicit declaration of function 'dma_map_single' drivers/net/ll_temac_main.c: In function 'temac_start_xmit_done': drivers/net/ll_temac_main.c:628:22: warning: cast to pointer from integer of different size Caused by commit commit b7f080cfe223 ("net: remove mm.h inclusion from netdevice.h"). Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/ll_temac_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index e3f19255af2..728fe414147 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "ll_temac.h" -- cgit v1.2.3-70-g09d2 From 864834f935b5311004ebbf0c485dbfd10aa9a546 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 29 Jun 2011 05:52:03 -0700 Subject: caif: Fix recieve/receive typo Just spelling fixes. Actually, a twofer with vaiables/variables as well. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 7a8ce61234a..016108a3b1c 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -988,7 +988,7 @@ int cfhsi_probe(struct platform_device *pdev) goto err_alloc_rx; } - /* Initialize recieve vaiables. */ + /* Initialize receive variables. */ cfhsi->rx_ptr = cfhsi->rx_buf; cfhsi->rx_len = CFHSI_DESC_SZ; -- cgit v1.2.3-70-g09d2 From 3b20b2dc5f713aa7eca20a8ff942292974a1cc94 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 05:05:00 +0000 Subject: myri10ge: ensure tx queues remain stopped Ensure that our tx queues remain stopped when we stop them in myri10ge_close(). Not doing so can potentially lead to traffic being transmitted when the interface is removed, which can lead to NULL pointer dereferences. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 3ed5f3505ce..a8ae641d0bd 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1461,7 +1461,8 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index) /* start the queue if we've stopped it */ if (netif_tx_queue_stopped(dev_queue) && - tx->req - tx->done < (tx->mask >> 1)) { + tx->req - tx->done < (tx->mask >> 1) && + ss->mgp->running == MYRI10GE_ETH_RUNNING) { tx->wake_queue++; netif_tx_wake_queue(dev_queue); } -- cgit v1.2.3-70-g09d2 From 7539a613c646f9e870bbedfa753a54cf13b98d22 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 05:05:01 +0000 Subject: myri10ge: Mask PCI Surprise Link Down Events A SRAM parity error can cause a surprise link down. Since We can recover from SRAM parity errors, mask PCI surprise down events. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index a8ae641d0bd..0f0f83d50dd 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -3327,6 +3327,26 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) mgp->fw_name); } +static void myri10ge_mask_surprise_down(struct pci_dev *pdev) +{ + struct pci_dev *bridge = pdev->bus->self; + int cap; + u32 mask; + + if (bridge == NULL) + return; + + cap = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ERR); + if (cap) { + /* a sram parity error can cause a surprise link + * down; since we expect and can recover from sram + * parity errors, mask surprise link down events */ + pci_read_config_dword(bridge, cap + PCI_ERR_UNCOR_MASK, &mask); + mask |= 0x20; + pci_write_config_dword(bridge, cap + PCI_ERR_UNCOR_MASK, mask); + } +} + #ifdef CONFIG_PM static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) { @@ -3845,6 +3865,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto abort_with_enabled; } + myri10ge_mask_surprise_down(pdev); pci_set_master(pdev); dac_enabled = 1; status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); -- cgit v1.2.3-70-g09d2 From c689b81b4267b1335b11f18fe8a79c56880d9d43 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 17:57:28 +0000 Subject: myri10ge: rework parity error check and cleanup Clean up watchdog reset code: - move code that checks for stuck slice to a common routine - unless there is a confirmed h/w fault, verify that a stuck slice is still stuck in the watchdog worker; if the slice is no longer stuck, abort the reset. - this removes an egregious 2000ms pause in the watchdog worker that was a diagnostic aid (to look for spurious resets) the snuck into production code. v3 includes corrections from Joe Perches Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 100 ++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 40 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 0f0f83d50dd..ca0345795fa 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -193,6 +193,7 @@ struct myri10ge_slice_state { int watchdog_tx_done; int watchdog_tx_req; int watchdog_rx_done; + int stuck; #ifdef CONFIG_MYRI10GE_DCA int cached_dca_tag; int cpu; @@ -3442,6 +3443,42 @@ static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp) return reboot; } +static void +myri10ge_check_slice(struct myri10ge_slice_state *ss, int *reset_needed, + int *busy_slice_cnt, u32 rx_pause_cnt) +{ + struct myri10ge_priv *mgp = ss->mgp; + int slice = ss - mgp->ss; + + if (ss->tx.req != ss->tx.done && + ss->tx.done == ss->watchdog_tx_done && + ss->watchdog_tx_req != ss->watchdog_tx_done) { + /* nic seems like it might be stuck.. */ + if (rx_pause_cnt != mgp->watchdog_pause) { + if (net_ratelimit()) + netdev_warn(mgp->dev, "slice %d: TX paused, " + "check link partner\n", slice); + } else { + netdev_warn(mgp->dev, + "slice %d: TX stuck %d %d %d %d %d %d\n", + slice, ss->tx.queue_active, ss->tx.req, + ss->tx.done, ss->tx.pkt_start, + ss->tx.pkt_done, + (int)ntohl(mgp->ss[slice].fw_stats-> + send_done_count)); + *reset_needed = 1; + ss->stuck = 1; + } + } + if (ss->watchdog_tx_done != ss->tx.done || + ss->watchdog_rx_done != ss->rx_done.cnt) { + *busy_slice_cnt += 1; + } + ss->watchdog_tx_done = ss->tx.done; + ss->watchdog_tx_req = ss->tx.req; + ss->watchdog_rx_done = ss->rx_done.cnt; +} + /* * This watchdog is used to check whether the board has suffered * from a parity error and needs to be recovered. @@ -3450,10 +3487,12 @@ static void myri10ge_watchdog(struct work_struct *work) { struct myri10ge_priv *mgp = container_of(work, struct myri10ge_priv, watchdog_work); - struct myri10ge_tx_buf *tx; - u32 reboot; + struct myri10ge_slice_state *ss; + u32 reboot, rx_pause_cnt; int status, rebooted; int i; + int reset_needed = 0; + int busy_slice_cnt = 0; u16 cmd, vendor; mgp->watchdog_resets++; @@ -3465,8 +3504,7 @@ static void myri10ge_watchdog(struct work_struct *work) * For now, just report it */ reboot = myri10ge_read_reboot(mgp); netdev_err(mgp->dev, "NIC rebooted (0x%x),%s resetting\n", - reboot, - myri10ge_reset_recover ? "" : " not"); + reboot, myri10ge_reset_recover ? "" : " not"); if (myri10ge_reset_recover == 0) return; rtnl_lock(); @@ -3498,23 +3536,24 @@ static void myri10ge_watchdog(struct work_struct *work) return; } } - /* Perhaps it is a software error. Try to reset */ - - netdev_err(mgp->dev, "device timeout, resetting\n"); + /* Perhaps it is a software error. See if stuck slice + * has recovered, reset if not */ + rx_pause_cnt = ntohl(mgp->ss[0].fw_stats->dropped_pause); for (i = 0; i < mgp->num_slices; i++) { - tx = &mgp->ss[i].tx; - netdev_err(mgp->dev, "(%d): %d %d %d %d %d %d\n", - i, tx->queue_active, tx->req, - tx->done, tx->pkt_start, tx->pkt_done, - (int)ntohl(mgp->ss[i].fw_stats-> - send_done_count)); - msleep(2000); - netdev_info(mgp->dev, "(%d): %d %d %d %d %d %d\n", - i, tx->queue_active, tx->req, - tx->done, tx->pkt_start, tx->pkt_done, - (int)ntohl(mgp->ss[i].fw_stats-> - send_done_count)); + ss = mgp->ss; + if (ss->stuck) { + myri10ge_check_slice(ss, &reset_needed, + &busy_slice_cnt, + rx_pause_cnt); + ss->stuck = 0; + } } + if (!reset_needed) { + netdev_dbg(mgp->dev, "not resetting\n"); + return; + } + + netdev_err(mgp->dev, "device timeout, resetting\n"); } if (!rebooted) { @@ -3567,27 +3606,8 @@ static void myri10ge_watchdog_timer(unsigned long arg) myri10ge_fill_thresh) ss->rx_big.watchdog_needed = 0; } - - if (ss->tx.req != ss->tx.done && - ss->tx.done == ss->watchdog_tx_done && - ss->watchdog_tx_req != ss->watchdog_tx_done) { - /* nic seems like it might be stuck.. */ - if (rx_pause_cnt != mgp->watchdog_pause) { - if (net_ratelimit()) - netdev_err(mgp->dev, "slice %d: TX paused, check link partner\n", - i); - } else { - netdev_warn(mgp->dev, "slice %d stuck:", i); - reset_needed = 1; - } - } - if (ss->watchdog_tx_done != ss->tx.done || - ss->watchdog_rx_done != ss->rx_done.cnt) { - busy_slice_cnt++; - } - ss->watchdog_tx_done = ss->tx.done; - ss->watchdog_tx_req = ss->tx.req; - ss->watchdog_rx_done = ss->rx_done.cnt; + myri10ge_check_slice(ss, &reset_needed, &busy_slice_cnt, + rx_pause_cnt); } /* if we've sent or received no traffic, poll the NIC to * ensure it is still there. Otherwise, we risk not noticing -- cgit v1.2.3-70-g09d2 From 4b47638ab25d90faf4e5499aecd8812f247181fd Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 05:05:03 +0000 Subject: myri10ge: allow small_bytes = 0 Allow page-based receive to work when small_bytes is set to 0. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index ca0345795fa..57bb7f782c3 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2004,8 +2004,12 @@ static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss) ss->rx_big.page_offset = MYRI10GE_ALLOC_SIZE; ss->rx_small.watchdog_needed = 0; ss->rx_big.watchdog_needed = 0; - myri10ge_alloc_rx_pages(mgp, &ss->rx_small, - mgp->small_bytes + MXGEFW_PAD, 0); + if (mgp->small_bytes == 0) { + ss->rx_small.fill_cnt = ss->rx_small.mask + 1; + } else { + myri10ge_alloc_rx_pages(mgp, &ss->rx_small, + mgp->small_bytes + MXGEFW_PAD, 0); + } if (ss->rx_small.fill_cnt < ss->rx_small.mask + 1) { netdev_err(dev, "slice-%d: alloced only %d small bufs\n", @@ -2031,6 +2035,8 @@ abort_with_rx_big_ring: } abort_with_rx_small_ring: + if (mgp->small_bytes == 0) + ss->rx_small.fill_cnt = ss->rx_small.cnt; for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) { int idx = i & ss->rx_small.mask; myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx], @@ -2081,6 +2087,8 @@ static void myri10ge_free_rings(struct myri10ge_slice_state *ss) put_page(ss->rx_big.info[idx].page); } + if (mgp->small_bytes == 0) + ss->rx_small.fill_cnt = ss->rx_small.cnt; for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) { idx = i & ss->rx_small.mask; if (i == ss->rx_small.fill_cnt - 1) @@ -2418,7 +2426,7 @@ static int myri10ge_open(struct net_device *dev) mgp->small_bytes = VLAN_ETH_FRAME_LEN; /* Override the small buffer size? */ - if (myri10ge_small_bytes > 0) + if (myri10ge_small_bytes >= 0) mgp->small_bytes = myri10ge_small_bytes; /* Firmware needs the big buff size as a power of 2. Lie and -- cgit v1.2.3-70-g09d2 From 5dcd846712046d68020e9dfddd7ca491dc138f0d Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 05:05:04 +0000 Subject: myri10ge: add support for set_phys_id Add myri10ge driver support for the ethtool identify operation. NOTE: Rather than blinking (which is the normal case), when identify is used, the yellow LED turns solid. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 55 ++++++++++++++++++++++++++ drivers/net/myri10ge/myri10ge_mcp_gen_header.h | 2 + 2 files changed, 57 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 57bb7f782c3..a0d4c619e85 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1911,6 +1911,60 @@ static u32 myri10ge_get_msglevel(struct net_device *netdev) return mgp->msg_enable; } +/* + * Use a low-level command to change the LED behavior. Rather than + * blinking (which is the normal case), when identify is used, the + * yellow LED turns solid. + */ +static int myri10ge_led(struct myri10ge_priv *mgp, int on) +{ + struct mcp_gen_header *hdr; + struct device *dev = &mgp->pdev->dev; + size_t hdr_off, pattern_off, hdr_len; + u32 pattern = 0xfffffffe; + + /* find running firmware header */ + hdr_off = swab32(readl(mgp->sram + MCP_HEADER_PTR_OFFSET)); + if ((hdr_off & 3) || hdr_off + sizeof(*hdr) > mgp->sram_size) { + dev_err(dev, "Running firmware has bad header offset (%d)\n", + (int)hdr_off); + return -EIO; + } + hdr_len = swab32(readl(mgp->sram + hdr_off + + offsetof(struct mcp_gen_header, header_length))); + pattern_off = hdr_off + offsetof(struct mcp_gen_header, led_pattern); + if (pattern_off >= (hdr_len + hdr_off)) { + dev_info(dev, "Firmware does not support LED identification\n"); + return -EINVAL; + } + if (!on) + pattern = swab32(readl(mgp->sram + pattern_off + 4)); + writel(htonl(pattern), mgp->sram + pattern_off); + return 0; +} + +static int +myri10ge_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state) +{ + struct myri10ge_priv *mgp = netdev_priv(netdev); + int rc; + + switch (state) { + case ETHTOOL_ID_ACTIVE: + rc = myri10ge_led(mgp, 1); + break; + + case ETHTOOL_ID_INACTIVE: + rc = myri10ge_led(mgp, 0); + break; + + default: + rc = -EINVAL; + } + + return rc; +} + static const struct ethtool_ops myri10ge_ethtool_ops = { .get_settings = myri10ge_get_settings, .get_drvinfo = myri10ge_get_drvinfo, @@ -1925,6 +1979,7 @@ static const struct ethtool_ops myri10ge_ethtool_ops = { .get_ethtool_stats = myri10ge_get_ethtool_stats, .set_msglevel = myri10ge_set_msglevel, .get_msglevel = myri10ge_get_msglevel, + .set_phys_id = myri10ge_phys_id, }; static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss) diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h index 62a1cbab603..7ec4b864a55 100644 --- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h +++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h @@ -45,6 +45,8 @@ struct mcp_gen_header { unsigned bss_addr; /* start of bss */ unsigned features; unsigned ee_hdr_addr; + unsigned led_pattern; + unsigned led_pattern_dflt; /* 8 */ }; -- cgit v1.2.3-70-g09d2 From effd1edab9fd3dc03cb87097a9da2552b940456b Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 05:05:05 +0000 Subject: myri10ge: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index a0d4c619e85..42ea4f80917 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1081,7 +1081,7 @@ static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on) int ret, cap, err; u16 ctl; - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + cap = pci_pcie_cap(pdev); if (!cap) return 0; @@ -3191,7 +3191,7 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) { struct pci_dev *bridge = mgp->pdev->bus->self; struct device *dev = &mgp->pdev->dev; - unsigned cap; + int cap; unsigned err_cap; u16 val; u8 ext_type; @@ -3201,7 +3201,7 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) return; /* check that the bridge is a root port */ - cap = pci_find_capability(bridge, PCI_CAP_ID_EXP); + cap = pci_pcie_cap(bridge); pci_read_config_word(bridge, cap + PCI_CAP_FLAGS, &val); ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; if (ext_type != PCI_EXP_TYPE_ROOT_PORT) { @@ -3219,8 +3219,7 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) " to force ECRC\n"); return; } - cap = - pci_find_capability(bridge, PCI_CAP_ID_EXP); + cap = pci_pcie_cap(bridge); pci_read_config_word(bridge, cap + PCI_CAP_FLAGS, &val); ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; @@ -3341,7 +3340,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) int link_width, exp_cap; u16 lnk; - exp_cap = pci_find_capability(mgp->pdev, PCI_CAP_ID_EXP); + exp_cap = pci_pcie_cap(mgp->pdev); pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); link_width = (lnk >> 4) & 0x3f; -- cgit v1.2.3-70-g09d2 From b3b6ae2c2ac39efbd95b012bb5396edf9c87ecc6 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 10:56:41 +0000 Subject: myri10ge: misc style cleanups Miscellaneous white space, style, and other cleanups v2 includes corrections from Joe Perches Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 42ea4f80917..fde62100c97 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1086,6 +1086,9 @@ static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on) return 0; err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); + if (err) + return 0; + ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4; if (ret != on) { ctl &= ~PCI_EXP_DEVCTL_RELAX_EN; @@ -1140,20 +1143,19 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp) mgp->ss[i].cpu = -1; mgp->ss[i].cached_dca_tag = -1; myri10ge_update_dca(&mgp->ss[i]); - } + } } static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) { struct pci_dev *pdev = mgp->pdev; - int err; if (!mgp->dca_enabled) return; mgp->dca_enabled = 0; if (mgp->relaxed_order) myri10ge_toggle_relaxed(pdev, 1); - err = dca_remove_requester(&pdev->dev); + dca_remove_requester(&pdev->dev); } static int myri10ge_notify_dca_device(struct device *dev, void *data) @@ -1314,7 +1316,7 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev, static inline int myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, - int lro_enabled) + bool lro_enabled) { struct myri10ge_priv *mgp = ss->mgp; struct sk_buff *skb; @@ -1474,11 +1476,9 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) { struct myri10ge_rx_done *rx_done = &ss->rx_done; struct myri10ge_priv *mgp = ss->mgp; - unsigned long rx_bytes = 0; unsigned long rx_packets = 0; unsigned long rx_ok; - int idx = rx_done->idx; int cnt = rx_done->cnt; int work_done = 0; @@ -1531,16 +1531,14 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) mgp->link_state = link_up; if (mgp->link_state == MXGEFW_LINK_UP) { - if (netif_msg_link(mgp)) - netdev_info(mgp->dev, "link up\n"); + netif_info(mgp, link, mgp->dev, "link up\n"); netif_carrier_on(mgp->dev); mgp->link_changes++; } else { - if (netif_msg_link(mgp)) - netdev_info(mgp->dev, "link %s\n", - link_up == MXGEFW_LINK_MYRINET ? + netif_info(mgp, link, mgp->dev, "link %s\n", + (link_up == MXGEFW_LINK_MYRINET ? "mismatch (Myrinet detected)" : - "down"); + "down")); netif_carrier_off(mgp->dev); mgp->link_changes++; } @@ -1621,7 +1619,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) if (send_done_count != tx->pkt_done) myri10ge_tx_done(ss, (int)send_done_count); if (unlikely(i > myri10ge_max_irq_loops)) { - netdev_err(mgp->dev, "irq stuck?\n"); + netdev_warn(mgp->dev, "irq stuck?\n"); stats->valid = 0; schedule_work(&mgp->watchdog_work); } @@ -1785,9 +1783,8 @@ static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = { "----------- slice ---------", "tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", - "wake_queue", "stop_queue", "tx_linearized", "LRO aggregated", - "LRO flushed", - "LRO avg aggr", "LRO no_desc" + "wake_queue", "stop_queue", "tx_linearized", + "LRO aggregated", "LRO flushed", "LRO avg aggr", "LRO no_desc", }; #define MYRI10GE_NET_STATS_LEN 21 @@ -3329,7 +3326,6 @@ abort: /* fall back to using the unaligned firmware */ mgp->tx_boundary = 2048; set_fw_name(mgp, myri10ge_fw_unaligned, false); - } static void myri10ge_select_firmware(struct myri10ge_priv *mgp) @@ -3715,8 +3711,8 @@ static void myri10ge_free_slices(struct myri10ge_priv *mgp) dma_free_coherent(&pdev->dev, bytes, ss->fw_stats, ss->fw_stats_bus); ss->fw_stats = NULL; - netif_napi_del(&ss->napi); } + netif_napi_del(&ss->napi); } kfree(mgp->ss); mgp->ss = NULL; -- cgit v1.2.3-70-g09d2 From 3bea123791d36a7b15f0d14ba5af9bdeb0c51cfc Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 05:05:07 +0000 Subject: myri10ge: update version Update version and copyright Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index fde62100c97..1d2247554a3 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1,7 +1,7 @@ /************************************************************************* * myri10ge.c: Myricom Myri-10G Ethernet driver. * - * Copyright (C) 2005 - 2009 Myricom, Inc. + * Copyright (C) 2005 - 2011 Myricom, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -79,7 +79,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.5.2-1.459" +#define MYRI10GE_VERSION_STR "1.5.3-1.534" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); -- cgit v1.2.3-70-g09d2 From 1a93139237180404dc01970dfd33f4a5d5b2054c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 27 Jun 2011 14:58:50 +0200 Subject: b43: HT-PHY: prepare place for HT-PHY tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are big arrays uploaded to the hardware on init, calibration, etc. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/tables_phy_ht.c | 162 +++++++++++++++++++++++++++++++ drivers/net/wireless/b43/tables_phy_ht.h | 20 ++++ 3 files changed, 183 insertions(+) create mode 100644 drivers/net/wireless/b43/tables_phy_ht.c create mode 100644 drivers/net/wireless/b43/tables_phy_ht.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 900dc9c8c68..1b25604be54 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -11,6 +11,7 @@ b43-$(CONFIG_B43_PHY_N) += phy_n.o b43-$(CONFIG_B43_PHY_LP) += phy_lp.o b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o b43-$(CONFIG_B43_PHY_HT) += phy_ht.o +b43-$(CONFIG_B43_PHY_HT) += tables_phy_ht.o b43-$(CONFIG_B43_PHY_HT) += radio_2059.o b43-y += sysfs.o b43-y += xmit.o diff --git a/drivers/net/wireless/b43/tables_phy_ht.c b/drivers/net/wireless/b43/tables_phy_ht.c new file mode 100644 index 00000000000..df08be28f50 --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_ht.c @@ -0,0 +1,162 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n HT-PHY data tables + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "tables_phy_ht.h" +#include "phy_common.h" +#include "phy_ht.h" + +u32 b43_httab_read(struct b43_wldev *dev, u32 offset) +{ + u32 type, value; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= ~B43_HTTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + switch (type) { + case B43_HTTAB_8BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO) & 0xFF; + break; + case B43_HTTAB_16BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + break; + case B43_HTTAB_32BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATAHI); + value <<= 16; + value |= b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + break; + default: + B43_WARN_ON(1); + value = 0; + } + + return value; +} + +void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, void *_data) +{ + u32 type; + u8 *data = _data; + unsigned int i; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= ~B43_HTTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + + for (i = 0; i < nr_elements; i++) { + switch (type) { + case B43_HTTAB_8BIT: + *data = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO) & 0xFF; + data++; + break; + case B43_HTTAB_16BIT: + *((u16 *)data) = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + data += 2; + break; + case B43_HTTAB_32BIT: + *((u32 *)data) = b43_phy_read(dev, B43_PHY_HT_TABLE_DATAHI); + *((u32 *)data) <<= 16; + *((u32 *)data) |= b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO); + data += 4; + break; + default: + B43_WARN_ON(1); + } + } +} + +void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value) +{ + u32 type; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= 0xFFFF; + + switch (type) { + case B43_HTTAB_8BIT: + B43_WARN_ON(value & ~0xFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_16BIT: + B43_WARN_ON(value & ~0xFFFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_32BIT: + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, value >> 16); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value & 0xFFFF); + break; + default: + B43_WARN_ON(1); + } + + return; +} + +void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, const void *_data) +{ + u32 type, value; + const u8 *data = _data; + unsigned int i; + + type = offset & B43_HTTAB_TYPEMASK; + offset &= ~B43_HTTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset); + + for (i = 0; i < nr_elements; i++) { + switch (type) { + case B43_HTTAB_8BIT: + value = *data; + data++; + B43_WARN_ON(value & ~0xFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_16BIT: + value = *((u16 *)data); + data += 2; + B43_WARN_ON(value & ~0xFFFF); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value); + break; + case B43_HTTAB_32BIT: + value = *((u32 *)data); + data += 4; + b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, value >> 16); + b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, + value & 0xFFFF); + break; + default: + B43_WARN_ON(1); + } + } +} diff --git a/drivers/net/wireless/b43/tables_phy_ht.h b/drivers/net/wireless/b43/tables_phy_ht.h new file mode 100644 index 00000000000..6a136148edd --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_ht.h @@ -0,0 +1,20 @@ +#ifndef B43_TABLES_PHY_HT_H_ +#define B43_TABLES_PHY_HT_H_ + +/* The HT-PHY tables. */ +#define B43_HTTAB_TYPEMASK 0xF0000000 +#define B43_HTTAB_8BIT 0x10000000 +#define B43_HTTAB_16BIT 0x20000000 +#define B43_HTTAB_32BIT 0x30000000 +#define B43_HTTAB8(table, offset) (((table) << 10) | (offset) | B43_HTTAB_8BIT) +#define B43_HTTAB16(table, offset) (((table) << 10) | (offset) | B43_HTTAB_16BIT) +#define B43_HTTAB32(table, offset) (((table) << 10) | (offset) | B43_HTTAB_32BIT) + +u32 b43_httab_read(struct b43_wldev *dev, u32 offset); +void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, void *_data); +void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value); +void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, const void *_data); + +#endif /* B43_TABLES_PHY_HT_H_ */ -- cgit v1.2.3-70-g09d2 From bdb2dfb237997babac7b32c7a94dcfa18507a055 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 27 Jun 2011 14:58:51 +0200 Subject: b43: HT-PHY: upload PHY values when switching channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After calibrating radio you can find few PHY writes in MMIO dumps: phy_read(0x0009) -> 0x0000 phy_write(0x01ce) <- 0x03dd phy_write(0x01cf) <- 0x03d9 phy_write(0x01d0) <- 0x03d5 phy_write(0x01d1) <- 0x0424 phy_write(0x01d2) <- 0x0429 phy_write(0x01d3) <- 0x042d By comparing to N-PHY code we found out that they are PHY tables for channel switching plus band info read at the beginning. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 16 +++++++++++++++- drivers/net/wireless/b43/phy_ht.h | 14 +++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 72f01ce8b42..c48bcf6b7d1 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -82,7 +82,21 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, const struct b43_phy_ht_channeltab_e_phy *e, struct ieee80211_channel *new_channel) { - /* TODO */ + bool old_band_5ghz; + + old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ + if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { + /* TODO */ + } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) { + /* TODO */ + } + + b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1); + b43_phy_write(dev, B43_PHY_HT_BW2, e->bw2); + b43_phy_write(dev, B43_PHY_HT_BW3, e->bw3); + b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4); + b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5); + b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6); } static int b43_phy_ht_set_channel(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index afa448d6571..7ad7affc8df 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h @@ -4,9 +4,16 @@ #include "phy_common.h" +#define B43_PHY_HT_BANDCTL 0x009 /* Band control */ #define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ #define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ #define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ +#define B43_PHY_HT_BW1 0x1CE +#define B43_PHY_HT_BW2 0x1CF +#define B43_PHY_HT_BW3 0x1D0 +#define B43_PHY_HT_BW4 0x1D1 +#define B43_PHY_HT_BW5 0x1D2 +#define B43_PHY_HT_BW6 0x1D3 #define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) @@ -20,7 +27,12 @@ /* Values for PHY registers used on channel switching */ struct b43_phy_ht_channeltab_e_phy { - /* TODO */ + u16 bw1; + u16 bw2; + u16 bw3; + u16 bw4; + u16 bw5; + u16 bw6; }; -- cgit v1.2.3-70-g09d2 From e5b61007bc15b34fe78d4100dbe1be209b761d9b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 27 Jun 2011 14:58:52 +0200 Subject: b43: HT-PHY: perform some tables ops on channel switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starring at MMIO dumps around PHY channel switching has led to finding serie of 3 similar ops this patch implements. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index c48bcf6b7d1..42bea3041e5 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -24,6 +24,7 @@ #include "b43.h" #include "phy_ht.h" +#include "tables_phy_ht.h" #include "radio_2059.h" #include "main.h" @@ -83,6 +84,7 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, struct ieee80211_channel *new_channel) { bool old_band_5ghz; + u8 i; old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { @@ -97,6 +99,23 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4); b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5); b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6); + + /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */ + + /* TODO: separated function? */ + for (i = 0; i < 3; i++) { + u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8)); + + /* TODO: some op on PHY reg 0x908 */ + + b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16); + b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)), + tmp & 0xFF); + b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)), + tmp & 0xFF); + } + + b43_phy_write(dev, 0x017e, 0x3830); } static int b43_phy_ht_set_channel(struct b43_wldev *dev, -- cgit v1.2.3-70-g09d2 From feb90636cc6a99733d3b0b18344b04ca2d2f203e Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 27 Jun 2011 14:58:54 +0200 Subject: b43: HT-PHY: add channel switching tables for 2 GHz band MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tables were taken from observing writes in MMIO dumps. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2059.c | 135 ++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c index 55d7da74f15..23dea4ba821 100644 --- a/drivers/net/wireless/b43/radio_2059.c +++ b/drivers/net/wireless/b43/radio_2059.c @@ -23,6 +23,141 @@ #include "b43.h" #include "radio_2059.h" +#define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ + r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ + r20, r21, r22, r23, r24, r25, r26, r27, r28) \ + .radio_syn16 = r00, \ + .radio_syn17 = r01, \ + .radio_syn22 = r02, \ + .radio_syn25 = r03, \ + .radio_syn27 = r04, \ + .radio_syn28 = r05, \ + .radio_syn29 = r06, \ + .radio_syn2c = r07, \ + .radio_syn2d = r08, \ + .radio_syn37 = r09, \ + .radio_syn41 = r10, \ + .radio_syn43 = r11, \ + .radio_syn47 = r12, \ + .radio_syn4a = r13, \ + .radio_syn58 = r14, \ + .radio_syn5a = r15, \ + .radio_syn6a = r16, \ + .radio_syn6d = r17, \ + .radio_syn6e = r18, \ + .radio_syn92 = r19, \ + .radio_syn98 = r20, \ + .radio_rxtx4a = r21, \ + .radio_rxtx58 = r22, \ + .radio_rxtx5a = r23, \ + .radio_rxtx6a = r24, \ + .radio_rxtx6d = r25, \ + .radio_rxtx6e = r26, \ + .radio_rxtx92 = r27, \ + .radio_rxtx98 = r28 + +#define PHYREGS(r0, r1, r2, r3, r4, r5) \ + .phy_regs.bw1 = r0, \ + .phy_regs.bw2 = r1, \ + .phy_regs.bw3 = r2, \ + .phy_regs.bw4 = r3, \ + .phy_regs.bw5 = r4, \ + .phy_regs.bw6 = r5 + +static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = { + { .freq = 2412, + RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, + 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), + }, + { .freq = 2417, + RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, + 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), + }, + { .freq = 2422, + RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, + 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), + }, + { .freq = 2427, + RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, + 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), + }, + { .freq = 2432, + RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, + 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), + }, + { .freq = 2437, + RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, + 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), + }, + { .freq = 2442, + RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), + }, + { .freq = 2447, + RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), + }, + { .freq = 2452, + RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), + }, + { .freq = 2457, + RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, + 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), + }, + { .freq = 2462, + RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, + 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), + }, + { .freq = 2467, + RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, + 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), + }, + { .freq = 2472, + RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, + 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, + 0x00, 0x00, 0x00, 0xf0, 0x00), + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), + }, +}; + const struct b43_phy_ht_channeltab_e_radio2059 *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq) { -- cgit v1.2.3-70-g09d2 From bfc8dfec45237e4c9e28f96fdb91167e7e8ddb96 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 27 Jun 2011 15:04:47 +0200 Subject: b43: HT-PHY: implement lacking 0x908 PHY reg op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 42bea3041e5..f09bb6e6307 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -104,9 +104,14 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, /* TODO: separated function? */ for (i = 0; i < 3; i++) { + u16 mask; u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8)); - /* TODO: some op on PHY reg 0x908 */ + if (0) /* FIXME */ + mask = 0x2 << (i * 4); + else + mask = 0; + b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask); b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16); b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)), -- cgit v1.2.3-70-g09d2 From f05b691150af4cfccbfba6cc708b9a58b9216903 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 12:48:54 -0500 Subject: iwlegacy: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index a2de7e99170..84da79376ef 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -484,7 +484,7 @@ static inline u16 iwl_legacy_pcie_link_ctl(struct iwl_priv *priv) { int pos; u16 pci_lnk_ctl; - pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP); + pos = pci_pcie_cap(priv->pci_dev); pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); return pci_lnk_ctl; } -- cgit v1.2.3-70-g09d2 From 6a4ecc29c90c322e28941e6dec406b08b5e1f0ea Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 12:50:14 -0500 Subject: rtlwifi: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Also, remove unnecessary and unused #defines for PCI. Signed-off-by: Jon Mason Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 2 +- drivers/net/wireless/rtlwifi/pci.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 6a15f368ebb..aa0ba9ec6aa 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -390,7 +390,7 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, u8 linkctrl_reg; /*Link Control Register */ - pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + pos = pci_pcie_cap(pdev); pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg; diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 671b1f5aa0c..76f42005a11 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -75,11 +75,6 @@ #define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */ #define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */ -#define PCI_CLASS_BRIDGE_DEV 0x06 -#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04 -#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10 -#define PCI_CAP_ID_EXP 0x10 - #define U1DONTCARE 0xFF #define U2DONTCARE 0xFFFF #define U4DONTCARE 0xFFFFFFFF -- cgit v1.2.3-70-g09d2 From f01dce9474e9f09290707b523a134a9605845b00 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 27 Jun 2011 13:03:44 -0500 Subject: rtlwifi: use PCI_VENDOR_ID_* Use PCI_VENDOR_ID_* from pci_ids.h instead of creating #define locally. Signed-off-by: Jon Mason Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 8 ++++---- drivers/net/wireless/rtlwifi/pci.h | 6 ------ 2 files changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index aa0ba9ec6aa..532c7d38dae 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -35,10 +35,10 @@ #include "efuse.h" static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { - INTEL_VENDOR_ID, - ATI_VENDOR_ID, - AMD_VENDOR_ID, - SIS_VENDOR_ID + PCI_VENDOR_ID_INTEL, + PCI_VENDOR_ID_ATI, + PCI_VENDOR_ID_AMD, + PCI_VENDOR_ID_SI }; static const u8 ac_to_hwq[] = { diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 76f42005a11..a50e5513256 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -62,12 +62,6 @@ .subdevice = PCI_ANY_ID,\ .driver_data = (kernel_ulong_t)&(cfg) -#define INTEL_VENDOR_ID 0x8086 -#define SIS_VENDOR_ID 0x1039 -#define ATI_VENDOR_ID 0x1002 -#define ATI_DEVICE_ID 0x7914 -#define AMD_VENDOR_ID 0x1022 - #define PCI_MAX_BRIDGE_NUMBER 255 #define PCI_MAX_DEVICES 32 #define PCI_MAX_FUNCTION 8 -- cgit v1.2.3-70-g09d2 From b4d38db121c19fe94862357763b374e44fc23ebb Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 27 Jun 2011 23:58:46 +0300 Subject: wl12xx: AP-mode - use mac80211 indication about STA WME support When adding a station, use the information given in the mac80211 populated ieee80211_sta structure to determine if it supports WME. Provide this information to the FW. This patch depends on "mac80211: propagate information about STA WME support down". Signed-off-by: Arik Nemtsov Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/cmd.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 42935ac7266..5d0ad2d93cb 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -1167,14 +1167,7 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) cmd->bss_index = WL1271_AP_BSS_INDEX; cmd->aid = sta->aid; cmd->hlid = hlid; - - /* - * FIXME: Does STA support QOS? We need to propagate this info from - * hostapd. Currently not that important since this is only used for - * sending the correct flavor of null-data packet in response to a - * trigger. - */ - cmd->wmm = 0; + cmd->wmm = sta->wme ? 1 : 0; cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta->supp_rates[wl->band])); -- cgit v1.2.3-70-g09d2 From e8dec1e99aee468c6fb19f07a2660f9205a70f2c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 28 Jun 2011 00:08:52 +0200 Subject: b43: HT-PHY: replace radio routing magic numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 2 +- drivers/net/wireless/b43/radio_2059.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index f09bb6e6307..8df92e12799 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -57,7 +57,7 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, b43_radio_write(dev, 0x98, e->radio_syn98); for (i = 0; i < 2; i++) { - routing = i ? 0x800 : 0x400; + routing = i ? R2059_RXRX1 : R2059_TXRX0; b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a); b43_radio_write(dev, routing | 0x58, e->radio_rxtx58); b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a); diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h index c2874b14526..e4d69e55e9f 100644 --- a/drivers/net/wireless/b43/radio_2059.h +++ b/drivers/net/wireless/b43/radio_2059.h @@ -5,6 +5,11 @@ #include "phy_ht.h" +#define R2059_SYN 0x000 +#define R2059_TXRX0 0x400 +#define R2059_RXRX1 0x800 +#define R2059_ALL 0xC00 + /* Values for various registers uploaded on channel switching */ struct b43_phy_ht_channeltab_e_radio2059 { /* The channel frequency in MHz */ -- cgit v1.2.3-70-g09d2 From 3e644ab47e0cbedc7dd694d3af9996dc514ebf4a Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 28 Jun 2011 00:08:53 +0200 Subject: b43: HT-PHY: init radio when enabling it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Masks and sets were found in MMIO dumps by using MMIO hacks. Shortly: radio_write(0x0c51) <- 0x0070 radio_write(0x0c5a) <- 0x0003 radio_write(0x0146) <- 0x0003 radio_write(0x0546) <- 0x0003 radio_write(0x0946) <- 0x0003 radio_write(0x002e) <- 0x0078 radio_write(0x00c0) <- 0x0080 radio_write(0x002e) <- 0xff87 radio_write(0x00c0) <- 0xff7f radio_write(0x0011) <- 0xfff7 Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 8df92e12799..28fb7464c31 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -28,6 +28,10 @@ #include "radio_2059.h" #include "main.h" +/************************************************** + * Radio 2059. + **************************************************/ + static void b43_radio_2059_channel_setup(struct b43_wldev *dev, const struct b43_phy_ht_channeltab_e_radio2059 *e) { @@ -79,6 +83,30 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, udelay(300); } +static void b43_radio_2059_init(struct b43_wldev *dev) +{ + const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 }; + u8 i; + + b43_radio_write(dev, R2059_ALL | 0x51, 0x0070); + b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003); + + for (i = 0; i < ARRAY_SIZE(routing); i++) + b43_radio_set(dev, routing[i] | 0x146, 0x3); + + b43_radio_set(dev, 0x2e, 0x0078); + b43_radio_set(dev, 0xc0, 0x0080); + msleep(2); + b43_radio_mask(dev, 0x2e, ~0x0078); + b43_radio_mask(dev, 0xc0, ~0x0080); + + b43_radio_mask(dev, 0x11, 0x0008); +} + +/************************************************** + * Channel switching ops. + **************************************************/ + static void b43_phy_ht_channel_setup(struct b43_wldev *dev, const struct b43_phy_ht_channeltab_e_phy *e, struct ieee80211_channel *new_channel) @@ -200,6 +228,11 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1); b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2); + + if (dev->phy.radio_ver == 0x2059) + b43_radio_2059_init(dev); + else + B43_WARN_ON(1); } } -- cgit v1.2.3-70-g09d2 From 71d3b0d592601f26be2233a7922d53e762516fee Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 28 Jun 2011 09:28:38 +0200 Subject: b43: HT-PHY: add init tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They were written from observing MMIO writes to registers 0x72 0x74 and 0x73 right after phy_write(0x017e) <- 0x3830 which finishes chennel switching. RegExps were used to translate writes to arrays. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_phy_ht.c | 588 +++++++++++++++++++++++++++++++ 1 file changed, 588 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/tables_phy_ht.c b/drivers/net/wireless/b43/tables_phy_ht.c index df08be28f50..603938657b1 100644 --- a/drivers/net/wireless/b43/tables_phy_ht.c +++ b/drivers/net/wireless/b43/tables_phy_ht.c @@ -25,6 +25,559 @@ #include "phy_common.h" #include "phy_ht.h" +static const u16 b43_httab_0x12[] = { + 0x0000, 0x0008, 0x000a, 0x0010, 0x0012, 0x0019, + 0x001a, 0x001c, 0x0080, 0x0088, 0x008a, 0x0090, + 0x0092, 0x0099, 0x009a, 0x009c, 0x0100, 0x0108, + 0x010a, 0x0110, 0x0112, 0x0119, 0x011a, 0x011c, + 0x0180, 0x0188, 0x018a, 0x0190, 0x0192, 0x0199, + 0x019a, 0x019c, 0x0000, 0x0098, 0x00a0, 0x00a8, + 0x009a, 0x00a2, 0x00aa, 0x0120, 0x0128, 0x0128, + 0x0130, 0x0138, 0x0138, 0x0140, 0x0122, 0x012a, + 0x012a, 0x0132, 0x013a, 0x013a, 0x0142, 0x01a8, + 0x01b0, 0x01b8, 0x01b0, 0x01b8, 0x01c0, 0x01c8, + 0x01c0, 0x01c8, 0x01d0, 0x01d0, 0x01d8, 0x01aa, + 0x01b2, 0x01ba, 0x01b2, 0x01ba, 0x01c2, 0x01ca, + 0x01c2, 0x01ca, 0x01d2, 0x01d2, 0x01da, 0x0001, + 0x0002, 0x0004, 0x0009, 0x000c, 0x0011, 0x0014, + 0x0018, 0x0020, 0x0021, 0x0022, 0x0024, 0x0081, + 0x0082, 0x0084, 0x0089, 0x008c, 0x0091, 0x0094, + 0x0098, 0x00a0, 0x00a1, 0x00a2, 0x00a4, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, +}; + +static const u16 b43_httab_0x27[] = { + 0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a, + 0x001d, 0x0020, 0x0009, 0x000e, 0x0011, 0x0014, + 0x0017, 0x001a, 0x001d, 0x0020, 0x0009, 0x000e, + 0x0011, 0x0014, 0x0017, 0x001a, 0x001d, 0x0020, + 0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a, + 0x001d, 0x0020, +}; + +static const u16 b43_httab_0x26[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u32 b43_httab_0x25[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_httab_0x2f[] = { + 0x00035700, 0x0002cc9a, 0x00026666, 0x0001581f, + 0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f, + 0x0001581f, 0x0001581f, 0x0001581f, 0x00035700, + 0x0002cc9a, 0x00026666, 0x0001581f, 0x0001581f, + 0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f, + 0x0001581f, 0x0001581f, +}; + +static const u16 b43_httab_0x1a[] = { + 0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e, + 0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a, + 0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046, + 0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040, + 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a, + 0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033, + 0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b, + 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e, + 0x000b, 0x0007, 0x0002, 0x00fd, +}; + +static const u16 b43_httab_0x1b[] = { + 0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e, + 0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a, + 0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046, + 0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040, + 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a, + 0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033, + 0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b, + 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e, + 0x000b, 0x0007, 0x0002, 0x00fd, +}; + +static const u16 b43_httab_0x1c[] = { + 0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e, + 0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a, + 0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046, + 0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040, + 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a, + 0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033, + 0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b, + 0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f, + 0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e, + 0x000b, 0x0007, 0x0002, 0x00fd, +}; + +static const u32 b43_httab_0x1a_0xc0[] = { + 0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e, + 0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037, + 0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031, + 0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040, + 0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039, + 0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033, + 0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e, + 0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037, + 0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031, + 0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c, + 0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e, + 0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037, + 0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031, + 0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c, + 0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042, + 0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b, + 0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034, + 0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f, + 0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e, + 0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037, + 0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031, + 0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c, + 0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027, + 0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023, + 0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e, + 0x5b07003c, 0x5b07003b, 0x5b070039, 0x5b070037, + 0x5b070036, 0x5b070034, 0x5b070033, 0x5b070031, + 0x5b070030, 0x5b07002f, 0x5b07002d, 0x5b07002c, + 0x5b07002b, 0x5b07002a, 0x5b070028, 0x5b070027, + 0x5b070026, 0x5b070025, 0x5b070024, 0x5b070023, + 0x5b070022, 0x5b070021, 0x5b070020, 0x5b07001f, + 0x5b07001e, 0x5b07001d, 0x5b07001d, 0x5b07001c, +}; + +static const u32 b43_httab_0x1a_0x140[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_httab_0x1b_0x140[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_httab_0x1c_0x140[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u16 b43_httab_0x1a_0x1c0[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u16 b43_httab_0x1b_0x1c0[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u16 b43_httab_0x1c_0x1c0[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u16 b43_httab_0x1a_0x240[] = { + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, +}; + +static const u16 b43_httab_0x1b_0x240[] = { + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, +}; + +static const u16 b43_httab_0x1c_0x240[] = { + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036, + 0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e, + 0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, + 0x01d6, 0x01d6, +}; + +static const u32 b43_httab_0x1f[] = { + 0x00000000, 0x00000000, 0x00016023, 0x00006028, + 0x00034036, 0x0003402e, 0x0007203c, 0x0006e037, + 0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d, + 0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9, + 0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9, + 0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6, + 0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c, + 0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b, + 0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15, + 0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9, + 0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87, + 0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3, + 0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa, + 0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff, + 0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff, + 0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff, +}; + +static const u32 b43_httab_0x21[] = { + 0x00000000, 0x00000000, 0x00016023, 0x00006028, + 0x00034036, 0x0003402e, 0x0007203c, 0x0006e037, + 0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d, + 0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9, + 0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9, + 0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6, + 0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c, + 0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b, + 0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15, + 0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9, + 0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87, + 0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3, + 0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa, + 0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff, + 0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff, + 0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff, +}; + +static const u32 b43_httab_0x23[] = { + 0x00000000, 0x00000000, 0x00016023, 0x00006028, + 0x00034036, 0x0003402e, 0x0007203c, 0x0006e037, + 0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d, + 0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9, + 0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9, + 0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6, + 0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c, + 0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b, + 0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15, + 0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9, + 0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87, + 0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3, + 0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa, + 0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff, + 0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff, + 0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff, +}; + +static const u32 b43_httab_0x20[] = { + 0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035, + 0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043, + 0x07340047, 0x06d2004b, 0x067a004f, 0x06170054, + 0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a, + 0x04910070, 0x044c0077, 0x040f007e, 0x03d90085, + 0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8, + 0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3, + 0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a, + 0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e, + 0x01720162, 0x015d0177, 0x0149018e, 0x013701a5, + 0x012601be, 0x011501d8, 0x010601f4, 0x00f70212, + 0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b, + 0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348, + 0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422, + 0x00750460, 0x006e04a3, 0x006804e9, 0x00620533, + 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c, +}; + +static const u32 b43_httab_0x22[] = { + 0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035, + 0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043, + 0x07340047, 0x06d2004b, 0x067a004f, 0x06170054, + 0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a, + 0x04910070, 0x044c0077, 0x040f007e, 0x03d90085, + 0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8, + 0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3, + 0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a, + 0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e, + 0x01720162, 0x015d0177, 0x0149018e, 0x013701a5, + 0x012601be, 0x011501d8, 0x010601f4, 0x00f70212, + 0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b, + 0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348, + 0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422, + 0x00750460, 0x006e04a3, 0x006804e9, 0x00620533, + 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c, +}; + +static const u32 b43_httab_0x24[] = { + 0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035, + 0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043, + 0x07340047, 0x06d2004b, 0x067a004f, 0x06170054, + 0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a, + 0x04910070, 0x044c0077, 0x040f007e, 0x03d90085, + 0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8, + 0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3, + 0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a, + 0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e, + 0x01720162, 0x015d0177, 0x0149018e, 0x013701a5, + 0x012601be, 0x011501d8, 0x010601f4, 0x00f70212, + 0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b, + 0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348, + 0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422, + 0x00750460, 0x006e04a3, 0x006804e9, 0x00620533, + 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c, +}; + +/************************************************** + * R/W ops. + **************************************************/ + u32 b43_httab_read(struct b43_wldev *dev, u32 offset) { u32 type, value; @@ -160,3 +713,38 @@ void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, } } } + +/************************************************** + * Tables ops. + **************************************************/ + +#define httab_upload(dev, offset, data) do { \ + b43_httab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ + } while (0) +void b43_phy_ht_tables_init(struct b43_wldev *dev) +{ + httab_upload(dev, B43_HTTAB16(0x12, 0), b43_httab_0x12); + httab_upload(dev, B43_HTTAB16(0x27, 0), b43_httab_0x27); + httab_upload(dev, B43_HTTAB16(0x26, 0), b43_httab_0x26); + httab_upload(dev, B43_HTTAB32(0x25, 0), b43_httab_0x25); + httab_upload(dev, B43_HTTAB32(0x2f, 0), b43_httab_0x2f); + httab_upload(dev, B43_HTTAB16(0x1a, 0), b43_httab_0x1a); + httab_upload(dev, B43_HTTAB16(0x1b, 0), b43_httab_0x1b); + httab_upload(dev, B43_HTTAB16(0x1c, 0), b43_httab_0x1c); + httab_upload(dev, B43_HTTAB32(0x1a, 0x0c0), b43_httab_0x1a_0xc0); + httab_upload(dev, B43_HTTAB32(0x1a, 0x140), b43_httab_0x1a_0x140); + httab_upload(dev, B43_HTTAB32(0x1b, 0x140), b43_httab_0x1b_0x140); + httab_upload(dev, B43_HTTAB32(0x1c, 0x140), b43_httab_0x1c_0x140); + httab_upload(dev, B43_HTTAB16(0x1a, 0x1c0), b43_httab_0x1a_0x1c0); + httab_upload(dev, B43_HTTAB16(0x1b, 0x1c0), b43_httab_0x1b_0x1c0); + httab_upload(dev, B43_HTTAB16(0x1c, 0x1c0), b43_httab_0x1c_0x1c0); + httab_upload(dev, B43_HTTAB16(0x1a, 0x240), b43_httab_0x1a_0x240); + httab_upload(dev, B43_HTTAB16(0x1b, 0x240), b43_httab_0x1b_0x240); + httab_upload(dev, B43_HTTAB16(0x1c, 0x240), b43_httab_0x1c_0x240); + httab_upload(dev, B43_HTTAB32(0x1f, 0), b43_httab_0x1f); + httab_upload(dev, B43_HTTAB32(0x21, 0), b43_httab_0x21); + httab_upload(dev, B43_HTTAB32(0x23, 0), b43_httab_0x23); + httab_upload(dev, B43_HTTAB32(0x20, 0), b43_httab_0x20); + httab_upload(dev, B43_HTTAB32(0x22, 0), b43_httab_0x22); + httab_upload(dev, B43_HTTAB32(0x24, 0), b43_httab_0x24); +} -- cgit v1.2.3-70-g09d2 From 2d02c86b7720c2f0614ed838187b05a7ddb0ea83 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 28 Jun 2011 09:28:39 +0200 Subject: b43: HT-PHY: basic PHY init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 9 +++++++-- drivers/net/wireless/b43/tables_phy_ht.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 28fb7464c31..69412d1fb65 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -205,6 +205,13 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev) memset(phy_ht, 0, sizeof(*phy_ht)); } +static int b43_phy_ht_op_init(struct b43_wldev *dev) +{ + b43_phy_ht_tables_init(dev); + + return 0; +} + static void b43_phy_ht_op_free(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; @@ -326,9 +333,7 @@ const struct b43_phy_operations b43_phyops_ht = { .allocate = b43_phy_ht_op_allocate, .free = b43_phy_ht_op_free, .prepare_structs = b43_phy_ht_op_prepare_structs, - /* .init = b43_phy_ht_op_init, - */ .phy_read = b43_phy_ht_op_read, .phy_write = b43_phy_ht_op_write, .phy_maskset = b43_phy_ht_op_maskset, diff --git a/drivers/net/wireless/b43/tables_phy_ht.h b/drivers/net/wireless/b43/tables_phy_ht.h index 6a136148edd..ea3be382c89 100644 --- a/drivers/net/wireless/b43/tables_phy_ht.h +++ b/drivers/net/wireless/b43/tables_phy_ht.h @@ -17,4 +17,6 @@ void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value); void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, unsigned int nr_elements, const void *_data); +void b43_phy_ht_tables_init(struct b43_wldev *dev); + #endif /* B43_TABLES_PHY_HT_H_ */ -- cgit v1.2.3-70-g09d2 From c3d77696b084a644693db0b02419d13375cb5b89 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 28 Jun 2011 17:30:54 +0530 Subject: ath9k: move few descriptor macros to ath9k.h Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 5 +++++ drivers/net/wireless/ath/ath9k/init.c | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 56a0ac4ddc6..964fb971fd6 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -100,6 +100,11 @@ enum buffer_type { #define ATH_TXSTATUS_RING_SIZE 64 +#define DS2PHYS(_dd, _ds) \ + ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) +#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) +#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) + struct ath_descdma { void *dd_desc; dma_addr_t dd_desc_paddr; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 50103b2792b..ce297173e0d 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -298,10 +298,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct list_head *head, const char *name, int nbuf, int ndesc, bool is_tx) { -#define DS2PHYS(_dd, _ds) \ - ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) -#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) -#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) struct ath_common *common = ath9k_hw_common(sc->sc_ah); u8 *ds; struct ath_buf *bf; @@ -396,9 +392,6 @@ fail2: fail: memset(dd, 0, sizeof(*dd)); return error; -#undef ATH_DESC_4KB_BOUND_CHECK -#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED -#undef DS2PHYS } void ath9k_init_crypto(struct ath_softc *sc) -- cgit v1.2.3-70-g09d2 From 5cf6fa784a979dce59a5c1b7085e59ee130369e8 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 28 Jun 2011 20:13:41 +0530 Subject: ath9k_htc: Add device ID for Sony UWA-BR100 for more details please take a look at: http://comments.gmane.org/gmane.linux.drivers.ath9k.devel/6541 http://www.wikidevi.com/wiki/Sony_UWA-BR100 Reported-by: Thomas Novin Cc: Rajkumar Manoharan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 260f1f37a60..8028fe90f66 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -49,6 +49,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { .driver_info = AR9280_USB }, /* Netgear WNDA3200 */ { USB_DEVICE(0x083A, 0xA704), .driver_info = AR9280_USB }, /* SMC Networks */ + { USB_DEVICE(0x0411, 0x017f), + .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ { USB_DEVICE(0x0cf3, 0x20ff), .driver_info = STORAGE_DEVICE }, -- cgit v1.2.3-70-g09d2 From a5f377fb9c9758b248773c5b8b1a20d4e7e2c982 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 29 Jun 2011 00:56:49 +0200 Subject: b43: HT-PHY: correct 0x2059 radio init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes additional steps are performed while initializing 2059 radio. We did not find the condition yet, so make it always true for now. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 50 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 69412d1fb65..30b19c61037 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -86,7 +86,10 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, static void b43_radio_2059_init(struct b43_wldev *dev) { const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 }; - u8 i; + const u16 radio_values[3][2] = { + { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, + }; + u16 i, j; b43_radio_write(dev, R2059_ALL | 0x51, 0x0070); b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003); @@ -100,6 +103,51 @@ static void b43_radio_2059_init(struct b43_wldev *dev) b43_radio_mask(dev, 0x2e, ~0x0078); b43_radio_mask(dev, 0xc0, ~0x0080); + if (1) { /* FIXME */ + b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1); + udelay(10); + b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1); + b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2); + + b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2); + udelay(100); + b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2); + + for (i = 0; i < 10000; i++) { + if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) { + i = 0; + break; + } + udelay(100); + } + if (i) + b43err(dev->wl, "radio 0x945 timeout\n"); + + b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1); + b43_radio_set(dev, 0xa, 0x60); + + for (i = 0; i < 3; i++) { + b43_radio_write(dev, 0x17F, radio_values[i][0]); + b43_radio_write(dev, 0x13D, 0x6E); + b43_radio_write(dev, 0x13E, radio_values[i][1]); + b43_radio_write(dev, 0x13C, 0x55); + + for (j = 0; j < 10000; j++) { + if (b43_radio_read(dev, 0x140) & 2) { + j = 0; + break; + } + udelay(500); + } + if (j) + b43err(dev->wl, "radio 0x140 timeout\n"); + + b43_radio_write(dev, 0x13C, 0x15); + } + + b43_radio_mask(dev, 0x17F, ~0x1); + } + b43_radio_mask(dev, 0x11, 0x0008); } -- cgit v1.2.3-70-g09d2 From ab049fbf5ea87fc92441fc5211c315d04a312cca Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 28 Jun 2011 18:55:50 -0500 Subject: rtlwifi: rtl8192de: Fix build errors when using allyes configuration After adding rtl8192de to linux-next, making the rtlwifi drivers be built-in results in the following warnings: LD drivers/net/wireless/rtlwifi/built-in.o drivers/net/wireless/rtlwifi/rtl8192de/built-in.o: In function `rtl92ce_sw_led_on': (.text+0x11fb6): multiple definition of `rtl92ce_sw_led_on' drivers/net/wireless/rtlwifi/rtl8192ce/built-in.o:(.text+0xa326): first defined here drivers/net/wireless/rtlwifi/rtl8192de/built-in.o:(.bss+0x0): multiple definition of `dm_digtable' drivers/net/wireless/rtlwifi/rtl8192c/built-in.o:(.bss+0x0): first defined here ld: Warning: size of symbol `dm_digtable' changed from 40 in drivers/net/wireless/rtlwifi/rtl8192c/built-in.o to 48 in drivers/net/wireless/rtlwifi/rtl8192de/built-in.o drivers/net/wireless/rtlwifi/rtl8192de/built-in.o: In function `rtl92ce_sw_led_off': (.text+0x11cfe): multiple definition of `rtl92ce_sw_led_off' drivers/net/wireless/rtlwifi/rtl8192ce/built-in.o:(.text+0xa06e): first defined here Reported-by: Stephen Rothwell Signed-off-by: Larry Finger Acked-by: Stephen Rothwell Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 176 +++++++++++++-------------- drivers/net/wireless/rtlwifi/rtl8192de/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192de/led.c | 8 +- drivers/net/wireless/rtlwifi/rtl8192de/led.h | 4 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 6 +- 6 files changed, 101 insertions(+), 101 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index d0baaf269a1..3cd0736fe8e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -37,7 +37,7 @@ #define UNDEC_SM_PWDB entry_min_undecoratedsmoothed_pwdb -struct dig_t dm_digtable; +struct dig_t de_digtable; static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = { 0x7f8001fe, /* 0, +6.0dB */ @@ -159,27 +159,27 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { static void rtl92d_dm_diginit(struct ieee80211_hw *hw) { - dm_digtable.dig_enable_flag = true; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable.cur_igvalue = 0x20; - dm_digtable.pre_igvalue = 0x0; - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; - dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; - dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; - dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; - dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; - dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; - dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; - dm_digtable.rx_gain_range_max = DM_DIG_FA_UPPER; - dm_digtable.rx_gain_range_min = DM_DIG_FA_LOWER; - dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; - dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI; - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; - dm_digtable.large_fa_hit = 0; - dm_digtable.recover_cnt = 0; - dm_digtable.forbidden_igi = DM_DIG_FA_LOWER; + de_digtable.dig_enable_flag = true; + de_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + de_digtable.cur_igvalue = 0x20; + de_digtable.pre_igvalue = 0x0; + de_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + de_digtable.presta_connectstate = DIG_STA_DISCONNECT; + de_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; + de_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; + de_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; + de_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + de_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + de_digtable.rx_gain_range_max = DM_DIG_FA_UPPER; + de_digtable.rx_gain_range_min = DM_DIG_FA_LOWER; + de_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + de_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; + de_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; + de_digtable.pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI; + de_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; + de_digtable.large_fa_hit = 0; + de_digtable.recover_cnt = 0; + de_digtable.forbidden_igi = DM_DIG_FA_LOWER; } static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) @@ -273,35 +273,35 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) /* Determine the minimum RSSI */ if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { - dm_digtable.min_undecorated_pwdb_for_dm = 0; + de_digtable.min_undecorated_pwdb_for_dm = 0; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, ("Not connected to any\n")); } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { - dm_digtable.min_undecorated_pwdb_for_dm = + de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, ("AP Client PWDB = 0x%lx\n", rtlpriv->dm.UNDEC_SM_PWDB)); } else { - dm_digtable.min_undecorated_pwdb_for_dm = + de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, ("STA Default Port PWDB = 0x%x\n", - dm_digtable.min_undecorated_pwdb_for_dm)); + de_digtable.min_undecorated_pwdb_for_dm)); } } else { - dm_digtable.min_undecorated_pwdb_for_dm = + de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, ("AP Ext Port or disconnet PWDB = 0x%x\n", - dm_digtable.min_undecorated_pwdb_for_dm)); + de_digtable.min_undecorated_pwdb_for_dm)); } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n", - dm_digtable.min_undecorated_pwdb_for_dm)); + de_digtable.min_undecorated_pwdb_for_dm)); } static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) @@ -309,27 +309,27 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); unsigned long flag = 0; - if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { - if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { - if (dm_digtable.min_undecorated_pwdb_for_dm <= 25) - dm_digtable.cur_cck_pd_state = + if (de_digtable.cursta_connectctate == DIG_STA_CONNECT) { + if (de_digtable.pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + if (de_digtable.min_undecorated_pwdb_for_dm <= 25) + de_digtable.cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; else - dm_digtable.cur_cck_pd_state = + de_digtable.cur_cck_pd_state = CCK_PD_STAGE_HIGHRSSI; } else { - if (dm_digtable.min_undecorated_pwdb_for_dm <= 20) - dm_digtable.cur_cck_pd_state = + if (de_digtable.min_undecorated_pwdb_for_dm <= 20) + de_digtable.cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; else - dm_digtable.cur_cck_pd_state = + de_digtable.cur_cck_pd_state = CCK_PD_STAGE_HIGHRSSI; } } else { - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; + de_digtable.cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; } - if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { - if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { + if (de_digtable.pre_cck_pd_state != de_digtable.cur_cck_pd_state) { + if (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0x83); rtl92d_release_cckandrw_pagea_ctl(hw, &flag); @@ -338,13 +338,13 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0xcd); rtl92d_release_cckandrw_pagea_ctl(hw, &flag); } - dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; + de_digtable.pre_cck_pd_state = de_digtable.cur_cck_pd_state; } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n", - (dm_digtable.cursta_connectctate == DIG_STA_CONNECT ? + (de_digtable.cursta_connectctate == DIG_STA_CONNECT ? "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"))); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n", - (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? + (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? "Low RSSI " : "High RSSI "))); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n", IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))); @@ -357,19 +357,19 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, " "pre_igvalue = 0x%x, backoff_val = %d\n", - dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, - dm_digtable.backoff_val)); - if (dm_digtable.dig_enable_flag == false) { + de_digtable.cur_igvalue, de_digtable.pre_igvalue, + de_digtable.backoff_val)); + if (de_digtable.dig_enable_flag == false) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n")); - dm_digtable.pre_igvalue = 0x17; + de_digtable.pre_igvalue = 0x17; return; } - if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { + if (de_digtable.pre_igvalue != de_digtable.cur_igvalue) { rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); + de_digtable.cur_igvalue); rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); - dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; + de_digtable.cur_igvalue); + de_digtable.pre_igvalue = de_digtable.cur_igvalue; } } @@ -379,13 +379,13 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) (rtlpriv->mac80211.vendor == PEER_CISCO)) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("IOT_PEER = CISCO\n")); - if (dm_digtable.last_min_undecorated_pwdb_for_dm >= 50 - && dm_digtable.min_undecorated_pwdb_for_dm < 50) { + if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50 + && de_digtable.min_undecorated_pwdb_for_dm < 50) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode Off\n")); - } else if (dm_digtable.last_min_undecorated_pwdb_for_dm <= 55 && - dm_digtable.min_undecorated_pwdb_for_dm > 55) { + } else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 && + de_digtable.min_undecorated_pwdb_for_dm > 55) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n")); @@ -399,14 +399,14 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) static void rtl92d_dm_dig(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value_igi = dm_digtable.cur_igvalue; + u8 value_igi = de_digtable.cur_igvalue; struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n")); if (rtlpriv->rtlhal.earlymode_enable) { rtl92d_early_mode_enabled(rtlpriv); - dm_digtable.last_min_undecorated_pwdb_for_dm = - dm_digtable.min_undecorated_pwdb_for_dm; + de_digtable.last_min_undecorated_pwdb_for_dm = + de_digtable.min_undecorated_pwdb_for_dm; } if (rtlpriv->dm.dm_initialgain_enable == false) return; @@ -424,9 +424,9 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n")); /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) - dm_digtable.cursta_connectctate = DIG_STA_CONNECT; + de_digtable.cursta_connectctate = DIG_STA_CONNECT; else - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + de_digtable.cursta_connectctate = DIG_STA_DISCONNECT; /* adjust initial gain according to false alarm counter */ if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0) @@ -439,64 +439,64 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) value_igi += 2; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", - dm_digtable.large_fa_hit, dm_digtable.forbidden_igi)); + de_digtable.large_fa_hit, de_digtable.forbidden_igi)); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", - dm_digtable.recover_cnt, dm_digtable.rx_gain_range_min)); + de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); /* deal with abnorally large false alarm */ if (falsealm_cnt->cnt_all > 10000) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("dm_DIG(): Abnornally false alarm case.\n")); - dm_digtable.large_fa_hit++; - if (dm_digtable.forbidden_igi < dm_digtable.cur_igvalue) { - dm_digtable.forbidden_igi = dm_digtable.cur_igvalue; - dm_digtable.large_fa_hit = 1; + de_digtable.large_fa_hit++; + if (de_digtable.forbidden_igi < de_digtable.cur_igvalue) { + de_digtable.forbidden_igi = de_digtable.cur_igvalue; + de_digtable.large_fa_hit = 1; } - if (dm_digtable.large_fa_hit >= 3) { - if ((dm_digtable.forbidden_igi + 1) > DM_DIG_MAX) - dm_digtable.rx_gain_range_min = DM_DIG_MAX; + if (de_digtable.large_fa_hit >= 3) { + if ((de_digtable.forbidden_igi + 1) > DM_DIG_MAX) + de_digtable.rx_gain_range_min = DM_DIG_MAX; else - dm_digtable.rx_gain_range_min = - (dm_digtable.forbidden_igi + 1); - dm_digtable.recover_cnt = 3600; /* 3600=2hr */ + de_digtable.rx_gain_range_min = + (de_digtable.forbidden_igi + 1); + de_digtable.recover_cnt = 3600; /* 3600=2hr */ } } else { /* Recovery mechanism for IGI lower bound */ - if (dm_digtable.recover_cnt != 0) { - dm_digtable.recover_cnt--; + if (de_digtable.recover_cnt != 0) { + de_digtable.recover_cnt--; } else { - if (dm_digtable.large_fa_hit == 0) { - if ((dm_digtable.forbidden_igi - 1) < + if (de_digtable.large_fa_hit == 0) { + if ((de_digtable.forbidden_igi - 1) < DM_DIG_FA_LOWER) { - dm_digtable.forbidden_igi = + de_digtable.forbidden_igi = DM_DIG_FA_LOWER; - dm_digtable.rx_gain_range_min = + de_digtable.rx_gain_range_min = DM_DIG_FA_LOWER; } else { - dm_digtable.forbidden_igi--; - dm_digtable.rx_gain_range_min = - (dm_digtable.forbidden_igi + 1); + de_digtable.forbidden_igi--; + de_digtable.rx_gain_range_min = + (de_digtable.forbidden_igi + 1); } - } else if (dm_digtable.large_fa_hit == 3) { - dm_digtable.large_fa_hit = 0; + } else if (de_digtable.large_fa_hit == 3) { + de_digtable.large_fa_hit = 0; } } } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", - dm_digtable.large_fa_hit, dm_digtable.forbidden_igi)); + de_digtable.large_fa_hit, de_digtable.forbidden_igi)); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", - dm_digtable.recover_cnt, dm_digtable.rx_gain_range_min)); + de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); if (value_igi > DM_DIG_MAX) value_igi = DM_DIG_MAX; - else if (value_igi < dm_digtable.rx_gain_range_min) - value_igi = dm_digtable.rx_gain_range_min; - dm_digtable.cur_igvalue = value_igi; + else if (value_igi < de_digtable.rx_gain_range_min) + value_igi = de_digtable.rx_gain_range_min; + de_digtable.cur_igvalue = value_igi; rtl92d_dm_write_dig(hw); if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) rtl92d_dm_cck_packet_detection_thresh(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h index b3a42ff8145..69354657f0f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h @@ -200,7 +200,7 @@ enum dm_dig_connect { DIG_CONNECT_MAX }; -extern struct dig_t dm_digtable; +extern struct dig_t de_digtable; void rtl92d_dm_init(struct ieee80211_hw *hw); void rtl92d_dm_watchdog(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index eedfb38bec8..31bdea8c700 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -627,11 +627,11 @@ static void _rtl92de_gen_refresh_led_state(struct ieee80211_hw *hw) if (rtlpci->up_first_time) return; if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) - rtl92ce_sw_led_on(hw, pLed0); + rtl92de_sw_led_on(hw, pLed0); else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) - rtl92ce_sw_led_on(hw, pLed0); + rtl92de_sw_led_on(hw, pLed0); else - rtl92ce_sw_led_off(hw, pLed0); + rtl92de_sw_led_off(hw, pLed0); } static bool _rtl92de_init_mac(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c index c965c73cf18..719972c16fc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -40,7 +40,7 @@ static void _rtl92ce_init_led(struct ieee80211_hw *hw, pled->ledon = false; } -void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) { u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -77,7 +77,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) pled->ledon = true; } -void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); @@ -128,10 +128,10 @@ static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, case LED_CTL_POWER_ON: case LED_CTL_LINK: case LED_CTL_NO_LINK: - rtl92ce_sw_led_on(hw, pLed0); + rtl92de_sw_led_on(hw, pLed0); break; case LED_CTL_POWER_OFF: - rtl92ce_sw_led_off(hw, pLed0); + rtl92de_sw_led_off(hw, pLed0); break; default: break; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/rtlwifi/rtl8192de/led.h index f6d33a6f0f8..57f4a3c583d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.h @@ -31,8 +31,8 @@ #define __RTL92CE_LED_H__ void rtl92de_init_sw_leds(struct ieee80211_hw *hw); -void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); -void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 4d4c8ebc77a..97fb6ca39d7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -3192,13 +3192,13 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) rtlphy->current_io_type, rtlphy->set_io_inprogress)); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: - dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; + de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; rtl92d_dm_write_dig(hw); rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); break; case IO_CMD_PAUSE_DM_BY_SCAN: - rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; - dm_digtable.cur_igvalue = 0x17; + rtlphy->initgain_backup.xaagccore1 = de_digtable.cur_igvalue; + de_digtable.cur_igvalue = 0x17; rtl92d_dm_write_dig(hw); break; default: -- cgit v1.2.3-70-g09d2 From 9a4ba833a2d0016cf836827e136f0c219834bd41 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Jun 2011 09:31:49 +0300 Subject: rtlwifi: potential forever loop in rtl92de_hw_init() "i" should be an int here because we are trying to use it to count to 10000. The original code looks like it could hang in a forever loop. Signed-off-by: Dan Carpenter Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 31bdea8c700..e833bbf92c5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -908,7 +908,8 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool rtstatus = true; - u8 tmp_u1b, i; + u8 tmp_u1b; + int i; int err; unsigned long flags; -- cgit v1.2.3-70-g09d2 From f984cec64a8dbe559f357fa0ed3e1bef7c247700 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Thu, 30 Jun 2011 11:19:09 -0700 Subject: xen/netback: Add module alias for autoloading Add xen-backend:vif module alias to the xen-netback module. This allows automatic loading of the module. Signed-off-by: Bastian Blank Acked-by: Ian Campbell Acked-by: Konrad Rzeszutek Wilk --- drivers/net/xen-netback/netback.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 0e4851b8a77..fd00f25d985 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1743,3 +1743,4 @@ failed_init: module_init(netback_init); MODULE_LICENSE("Dual BSD/GPL"); +MODULE_ALIAS("xen-backend:vif"); -- cgit v1.2.3-70-g09d2 From 3fa2a1df909482cc234524906e4bd30dee3514df Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 15 Jun 2011 06:36:29 +0000 Subject: virtio-net: per cpu 64 bit stats (v2) Use per-cpu variables to maintain 64 bit statistics. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 85 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index be3686a298d..fbea637eb74 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -40,6 +40,15 @@ module_param(gso, bool, 0444); #define VIRTNET_SEND_COMMAND_SG_MAX 2 +struct virtnet_stats { + struct u64_stats_sync syncp; + u64 tx_bytes; + u64 tx_packets; + + u64 rx_bytes; + u64 rx_packets; +}; + struct virtnet_info { struct virtio_device *vdev; struct virtqueue *rvq, *svq, *cvq; @@ -56,6 +65,9 @@ struct virtnet_info { /* Host will merge rx buffers for big packets (shake it! shake it!) */ bool mergeable_rx_bufs; + /* Active statistics */ + struct virtnet_stats __percpu *stats; + /* Work struct for refilling if we run low on memory. */ struct delayed_work refill; @@ -209,7 +221,6 @@ static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb) skb->dev->stats.rx_length_errors++; return -EINVAL; } - page = virtqueue_get_buf(vi->rvq, &len); if (!page) { pr_debug("%s: rx error: %d buffers missing\n", @@ -217,6 +228,7 @@ static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb) skb->dev->stats.rx_length_errors++; return -EINVAL; } + if (len > PAGE_SIZE) len = PAGE_SIZE; @@ -230,6 +242,7 @@ static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb) static void receive_buf(struct net_device *dev, void *buf, unsigned int len) { struct virtnet_info *vi = netdev_priv(dev); + struct virtnet_stats __percpu *stats = this_cpu_ptr(vi->stats); struct sk_buff *skb; struct page *page; struct skb_vnet_hdr *hdr; @@ -265,8 +278,11 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len) hdr = skb_vnet_hdr(skb); skb->truesize += skb->data_len; - dev->stats.rx_bytes += skb->len; - dev->stats.rx_packets++; + + u64_stats_update_begin(&stats->syncp); + stats->rx_bytes += skb->len; + stats->rx_packets++; + u64_stats_update_end(&stats->syncp); if (hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { pr_debug("Needs csum!\n"); @@ -515,11 +531,16 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi) { struct sk_buff *skb; unsigned int len, tot_sgs = 0; + struct virtnet_stats __percpu *stats = this_cpu_ptr(vi->stats); while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) { pr_debug("Sent skb %p\n", skb); - vi->dev->stats.tx_bytes += skb->len; - vi->dev->stats.tx_packets++; + + u64_stats_update_begin(&stats->syncp); + stats->tx_bytes += skb->len; + stats->tx_packets++; + u64_stats_update_end(&stats->syncp); + tot_sgs += skb_vnet_hdr(skb)->num_sg; dev_kfree_skb_any(skb); } @@ -641,6 +662,40 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) return 0; } +static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev, + struct rtnl_link_stats64 *tot) +{ + struct virtnet_info *vi = netdev_priv(dev); + int cpu; + unsigned int start; + + for_each_possible_cpu(cpu) { + struct virtnet_stats __percpu *stats + = per_cpu_ptr(vi->stats, cpu); + u64 tpackets, tbytes, rpackets, rbytes; + + do { + start = u64_stats_fetch_begin(&stats->syncp); + tpackets = stats->tx_packets; + tbytes = stats->tx_bytes; + rpackets = stats->rx_packets; + rbytes = stats->rx_bytes; + } while (u64_stats_fetch_retry(&stats->syncp, start)); + + tot->rx_packets += rpackets; + tot->tx_packets += tpackets; + tot->rx_bytes += rbytes; + tot->tx_bytes += tbytes; + } + + tot->tx_dropped = dev->stats.tx_dropped; + tot->rx_dropped = dev->stats.rx_dropped; + tot->rx_length_errors = dev->stats.rx_length_errors; + tot->rx_frame_errors = dev->stats.rx_frame_errors; + + return tot; +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void virtnet_netpoll(struct net_device *dev) { @@ -650,6 +705,14 @@ static void virtnet_netpoll(struct net_device *dev) } #endif +static void virtnet_free(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); + + free_percpu(vi->stats); + free_netdev(dev); +} + static int virtnet_open(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); @@ -835,6 +898,7 @@ static const struct net_device_ops virtnet_netdev = { .ndo_set_mac_address = virtnet_set_mac_address, .ndo_set_rx_mode = virtnet_set_rx_mode, .ndo_change_mtu = virtnet_change_mtu, + .ndo_get_stats64 = virtnet_stats, .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -895,6 +959,8 @@ static int virtnet_probe(struct virtio_device *vdev) /* Set up network device as normal. */ dev->netdev_ops = &virtnet_netdev; dev->features = NETIF_F_HIGHDMA; + dev->destructor = virtnet_free; + SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops); SET_NETDEV_DEV(dev, &vdev->dev); @@ -939,6 +1005,11 @@ static int virtnet_probe(struct virtio_device *vdev) vi->vdev = vdev; vdev->priv = vi; vi->pages = NULL; + vi->stats = alloc_percpu(struct virtnet_stats); + err = -ENOMEM; + if (vi->stats == NULL) + goto free; + INIT_DELAYED_WORK(&vi->refill, refill_work); sg_init_table(vi->rx_sg, ARRAY_SIZE(vi->rx_sg)); sg_init_table(vi->tx_sg, ARRAY_SIZE(vi->tx_sg)); @@ -958,7 +1029,7 @@ static int virtnet_probe(struct virtio_device *vdev) err = vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names); if (err) - goto free; + goto free_stats; vi->rvq = vqs[0]; vi->svq = vqs[1]; @@ -1003,6 +1074,8 @@ unregister: cancel_delayed_work_sync(&vi->refill); free_vqs: vdev->config->del_vqs(vdev); +free_stats: + free_percpu(vi->stats); free: free_netdev(dev); return err; -- cgit v1.2.3-70-g09d2 From ea7ea65a3b37bf207d5c352ac6254506b3dc3901 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Fri, 17 Jun 2011 07:56:48 +0000 Subject: enic: Add support to configure hardware interrupt coalesce timers in a platform independent way enic driver and the underlying hardware use different units for representing the interrupt coalesce timer. Driver converts the interrupt coalesce timer in usec to hardware cycles while setting the relevant hardware registers. The conversion factor can be different for each of the adapter hardware types. So it is dynamically learnt from the adapter firmware using the devcmd CMD_INTR_COAL_CONVERT. This allows the driver to configure the hardware interrupt coalesce timers in a platform independent way. Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_dev.c | 11 ++++++++ drivers/net/enic/enic_dev.h | 1 + drivers/net/enic/enic_main.c | 26 +++++++++++------- drivers/net/enic/enic_res.c | 7 +++-- drivers/net/enic/vnic_dev.c | 60 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/enic/vnic_dev.h | 5 ++++ drivers/net/enic/vnic_devcmd.h | 19 +++++++++++++ drivers/net/enic/vnic_enet.h | 4 --- drivers/net/enic/vnic_intr.c | 7 ++--- drivers/net/enic/vnic_intr.h | 6 ++--- 11 files changed, 122 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f747bceb75b..f0b062b4a22 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.20" +#define DRV_VERSION "2.1.1.24" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c index 90687b14e60..fd6247b3c0e 100644 --- a/drivers/net/enic/enic_dev.c +++ b/drivers/net/enic/enic_dev.c @@ -166,6 +166,17 @@ int enic_dev_disable(struct enic *enic) return err; } +int enic_dev_intr_coal_timer_info(struct enic *enic) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_intr_coal_timer_info(enic->vdev); + spin_unlock(&enic->devcmd_lock); + + return err; +} + int enic_vnic_dev_deinit(struct enic *enic) { int err; diff --git a/drivers/net/enic/enic_dev.h b/drivers/net/enic/enic_dev.h index d5f68133762..ff8e87fdfc1 100644 --- a/drivers/net/enic/enic_dev.h +++ b/drivers/net/enic/enic_dev.h @@ -34,6 +34,7 @@ int enic_dev_hang_notify(struct enic *enic); int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic); int enic_dev_enable(struct enic *enic); int enic_dev_disable(struct enic *enic); +int enic_dev_intr_coal_timer_info(struct enic *enic); int enic_vnic_dev_deinit(struct enic *enic); int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp); int enic_dev_deinit_done(struct enic *enic, int *status); diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 4b3a93a924e..e25800fa96c 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -284,12 +284,10 @@ static int enic_set_coalesce(struct net_device *netdev, u32 rx_coalesce_usecs; unsigned int i, intr; - tx_coalesce_usecs = min_t(u32, - INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), - ecmd->tx_coalesce_usecs); - rx_coalesce_usecs = min_t(u32, - INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), - ecmd->rx_coalesce_usecs); + tx_coalesce_usecs = min_t(u32, ecmd->tx_coalesce_usecs, + vnic_dev_get_intr_coal_timer_max(enic->vdev)); + rx_coalesce_usecs = min_t(u32, ecmd->rx_coalesce_usecs, + vnic_dev_get_intr_coal_timer_max(enic->vdev)); switch (vnic_dev_get_intr_mode(enic->vdev)) { case VNIC_DEV_INTR_MODE_INTX: @@ -298,26 +296,26 @@ static int enic_set_coalesce(struct net_device *netdev, intr = enic_legacy_io_intr(); vnic_intr_coalescing_timer_set(&enic->intr[intr], - INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); + tx_coalesce_usecs); break; case VNIC_DEV_INTR_MODE_MSI: if (tx_coalesce_usecs != rx_coalesce_usecs) return -EINVAL; vnic_intr_coalescing_timer_set(&enic->intr[0], - INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); + tx_coalesce_usecs); break; case VNIC_DEV_INTR_MODE_MSIX: for (i = 0; i < enic->wq_count; i++) { intr = enic_msix_wq_intr(enic, i); vnic_intr_coalescing_timer_set(&enic->intr[intr], - INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); + tx_coalesce_usecs); } for (i = 0; i < enic->rq_count; i++) { intr = enic_msix_rq_intr(enic, i); vnic_intr_coalescing_timer_set(&enic->intr[intr], - INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs)); + rx_coalesce_usecs); } break; @@ -2175,6 +2173,14 @@ static int enic_dev_init(struct enic *enic) unsigned int i; int err; + /* Get interrupt coalesce timer info */ + err = enic_dev_intr_coal_timer_info(enic); + if (err) { + dev_warn(dev, "Using default conversion factor for " + "interrupt coalesce timer\n"); + vnic_dev_intr_coal_timer_info_default(enic->vdev); + } + /* Get vNIC configuration */ diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 34f42072b60..4a35367de79 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -90,9 +90,8 @@ int enic_get_vnic_config(struct enic *enic) max_t(u16, ENIC_MIN_MTU, c->mtu)); - c->intr_timer_usec = min_t(u32, - INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), - c->intr_timer_usec); + c->intr_timer_usec = min_t(u32, c->intr_timer_usec, + vnic_dev_get_intr_coal_timer_max(enic->vdev)); dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n", @@ -303,7 +302,7 @@ void enic_init_vnic_resources(struct enic *enic) for (i = 0; i < enic->intr_count; i++) { vnic_intr_init(&enic->intr[i], - INTR_COALESCE_USEC_TO_HW(enic->config.intr_timer_usec), + enic->config.intr_timer_usec, enic->config.intr_timer_type, mask_on_assertion); } diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 68f24ae860a..8c4c8cf486f 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -40,6 +40,12 @@ struct vnic_res { unsigned int count; }; +struct vnic_intr_coal_timer_info { + u32 mul; + u32 div; + u32 max_usec; +}; + struct vnic_dev { void *priv; struct pci_dev *pdev; @@ -58,6 +64,7 @@ struct vnic_dev { enum vnic_proxy_type proxy; u32 proxy_index; u64 args[VNIC_DEVCMD_NARGS]; + struct vnic_intr_coal_timer_info intr_coal_timer_info; }; #define VNIC_MAX_RES_HDR_SIZE \ @@ -794,6 +801,42 @@ int vnic_dev_deinit(struct vnic_dev *vdev) return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait); } +void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev) +{ + /* Default: hardware intr coal timer is in units of 1.5 usecs */ + vdev->intr_coal_timer_info.mul = 2; + vdev->intr_coal_timer_info.div = 3; + vdev->intr_coal_timer_info.max_usec = + vnic_dev_intr_coal_timer_hw_to_usec(vdev, 0xffff); +} + +int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev) +{ + int wait = 1000; + int err; + + memset(vdev->args, 0, sizeof(vdev->args)); + + err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait); + + /* Use defaults when firmware doesn't support the devcmd at all or + * supports it for only specific hardware + */ + if ((err == ERR_ECMDUNKNOWN) || + (!err && !(vdev->args[0] && vdev->args[1] && vdev->args[2]))) { + pr_warning("Using default conversion factor for " + "interrupt coalesce timer\n"); + vnic_dev_intr_coal_timer_info_default(vdev); + return 0; + } + + vdev->intr_coal_timer_info.mul = (u32) vdev->args[0]; + vdev->intr_coal_timer_info.div = (u32) vdev->args[1]; + vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2]; + + return err; +} + int vnic_dev_link_status(struct vnic_dev *vdev) { if (!vnic_dev_notify_ready(vdev)) @@ -838,6 +881,23 @@ enum vnic_dev_intr_mode vnic_dev_get_intr_mode( return vdev->intr_mode; } +u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec) +{ + return (usec * vdev->intr_coal_timer_info.mul) / + vdev->intr_coal_timer_info.div; +} + +u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles) +{ + return (hw_cycles * vdev->intr_coal_timer_info.div) / + vdev->intr_coal_timer_info.mul; +} + +u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev) +{ + return vdev->intr_coal_timer_info.max_usec; +} + void vnic_dev_unregister(struct vnic_dev *vdev) { if (vdev) { diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index cf482a2c9dd..852b698fbe7 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h @@ -109,11 +109,16 @@ int vnic_dev_open(struct vnic_dev *vdev, int arg); int vnic_dev_open_done(struct vnic_dev *vdev, int *done); int vnic_dev_init(struct vnic_dev *vdev, int arg); int vnic_dev_deinit(struct vnic_dev *vdev); +void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev); +int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev); int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg); int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done); void vnic_dev_set_intr_mode(struct vnic_dev *vdev, enum vnic_dev_intr_mode intr_mode); enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev); +u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec); +u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles); +u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev); void vnic_dev_unregister(struct vnic_dev *vdev); int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, u8 ig_vlan_rewrite_mode); diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h index c5569bfb47a..8025e8808d6 100644 --- a/drivers/net/enic/vnic_devcmd.h +++ b/drivers/net/enic/vnic_devcmd.h @@ -318,6 +318,25 @@ enum vnic_devcmd_cmd { * ERR_EINPROGRESS - command in a0 is still in progress */ CMD_STATUS = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 49), + + /* + * Returns interrupt coalescing timer conversion factors. + * After calling this devcmd, ENIC driver can convert + * interrupt coalescing timer in usec into CPU cycles as follows: + * + * intr_timer_cycles = intr_timer_usec * multiplier / divisor + * + * Interrupt coalescing timer in usecs can be obtained from + * CPU cycles as follows: + * + * intr_timer_usec = intr_timer_cycles * divisor / multiplier + * + * in: none + * out: (u32)a0 = multiplier + * (u32)a1 = divisor + * (u32)a2 = maximum timer value in usec + */ + CMD_INTR_COAL_CONVERT = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 50), }; /* CMD_ENABLE2 flags */ diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h index 061ad878079..609542848e0 100644 --- a/drivers/net/enic/vnic_enet.h +++ b/drivers/net/enic/vnic_enet.h @@ -20,10 +20,6 @@ #ifndef _VNIC_ENIC_H_ #define _VNIC_ENIC_H_ -/* Hardware intr coalesce timer is in units of 1.5us */ -#define INTR_COALESCE_USEC_TO_HW(usec) ((usec) * 2/3) -#define INTR_COALESCE_HW_TO_USEC(usec) ((usec) * 3/2) - /* Device-specific region: enet configuration */ struct vnic_enet_config { u32 flags; diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c index 3873771d75c..0ca107f7bc8 100644 --- a/drivers/net/enic/vnic_intr.c +++ b/drivers/net/enic/vnic_intr.c @@ -46,7 +46,7 @@ int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr, return 0; } -void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer, +void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer, unsigned int coalescing_type, unsigned int mask_on_assertion) { vnic_intr_coalescing_timer_set(intr, coalescing_timer); @@ -56,9 +56,10 @@ void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer, } void vnic_intr_coalescing_timer_set(struct vnic_intr *intr, - unsigned int coalescing_timer) + u32 coalescing_timer) { - iowrite32(coalescing_timer, &intr->ctrl->coalescing_timer); + iowrite32(vnic_dev_intr_coal_timer_usec_to_hw(intr->vdev, + coalescing_timer), &intr->ctrl->coalescing_timer); } void vnic_intr_clean(struct vnic_intr *intr) diff --git a/drivers/net/enic/vnic_intr.h b/drivers/net/enic/vnic_intr.h index 09dc0b73ff4..2b163639229 100644 --- a/drivers/net/enic/vnic_intr.h +++ b/drivers/net/enic/vnic_intr.h @@ -24,8 +24,6 @@ #include "vnic_dev.h" -#define VNIC_INTR_TIMER_MAX 0xffff - #define VNIC_INTR_TIMER_TYPE_ABS 0 #define VNIC_INTR_TIMER_TYPE_QUIET 1 @@ -104,10 +102,10 @@ static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba) void vnic_intr_free(struct vnic_intr *intr); int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr, unsigned int index); -void vnic_intr_init(struct vnic_intr *intr, unsigned int coalescing_timer, +void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer, unsigned int coalescing_type, unsigned int mask_on_assertion); void vnic_intr_coalescing_timer_set(struct vnic_intr *intr, - unsigned int coalescing_timer); + u32 coalescing_timer); void vnic_intr_clean(struct vnic_intr *intr); #endif /* _VNIC_INTR_H_ */ -- cgit v1.2.3-70-g09d2 From b21f3c7ed98a153865a7094af7d85d84c188667e Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Mon, 27 Jun 2011 05:00:13 +0000 Subject: can: remove useless defaults in Kconfig There's no need for "default N' (or 'default n') as it's default. Signed-off-by: Kurt Van Dijck Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index bbf06f77ee8..906366b5403 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -4,7 +4,6 @@ menu "CAN Device Drivers" config CAN_VCAN tristate "Virtual Local CAN Interface (vcan)" depends on CAN - default N ---help--- Similar to the network loopback devices, vcan offers a virtual local CAN interface. @@ -15,7 +14,6 @@ config CAN_VCAN config CAN_SLCAN tristate "Serial / USB serial CAN Adaptors (slcan)" depends on CAN - default N ---help--- CAN driver for several 'low cost' CAN interfaces that are attached via serial lines or via USB-to-serial adapters using the LAWICEL @@ -125,7 +123,6 @@ source "drivers/net/can/softing/Kconfig" config CAN_DEBUG_DEVICES bool "CAN devices debugging messages" depends on CAN - default N ---help--- Say Y here if you want the CAN device drivers to produce a bunch of debug messages to the system log. Select this if you are having -- cgit v1.2.3-70-g09d2 From aab6fb82b1912a312f7547c92ac8d4ecb072e807 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Mon, 27 Jun 2011 19:23:34 +0000 Subject: jme: Fix compile warning introduced by new pm macro SIMPLE_DEV_PM_OPS is using SET_SYSTEM_SLEEP_PM_OPS and SET_SYSTEM_SLEEP_PM_OPS is empty when CONFIG_PM_SLEEP is not defined. Switching #ifdef CONFIG_PM to #ifdef CONFIG_PM_SLEEP Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index b5b174a8c14..2ce93393320 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -3135,7 +3135,7 @@ jme_shutdown(struct pci_dev *pdev) pci_pme_active(pdev, true); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int jme_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); -- cgit v1.2.3-70-g09d2 From bc057e0366cad58e55038a2cb69572d51c40cdf3 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Tue, 28 Jun 2011 01:38:30 +0000 Subject: jme: Cleanup PM operations after using new PM API 1. Using enum name instead of numeric value. 2. device_set_wakeup_enable expect bool argument adding !!() to the argument to be passed. 3. Remove non-jme-hardware related operations from jme_clear_pm() 4. Reuse jme_clear_pm() in jme_resume() and jme_powersave_phy() Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 23 +++++++++++------------ drivers/net/jme.h | 2 ++ 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 2ce93393320..6b2a5e74425 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -271,9 +271,7 @@ jme_reset_mac_processor(struct jme_adapter *jme) static inline void jme_clear_pm(struct jme_adapter *jme) { - jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs); - pci_set_power_state(jme->pdev, PCI_D0); - device_set_wakeup_enable(&jme->pdev->dev, false); + jwrite32(jme, JME_PMCS, PMCS_STMASK | jme->reg_pmcs); } static int @@ -1817,11 +1815,9 @@ jme_powersave_phy(struct jme_adapter *jme) { if (jme->reg_pmcs) { jme_set_100m_half(jme); - if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN)) jme_wait_link(jme); - - jwrite32(jme, JME_PMCS, jme->reg_pmcs); + jme_clear_pm(jme); } else { jme_phy_off(jme); } @@ -2529,8 +2525,7 @@ jme_set_wol(struct net_device *netdev, jme->reg_pmcs |= PMCS_MFEN; jwrite32(jme, JME_PMCS, jme->reg_pmcs); - - device_set_wakeup_enable(&jme->pdev->dev, jme->reg_pmcs); + device_set_wakeup_enable(&jme->pdev->dev, !!(jme->reg_pmcs)); return 0; } @@ -3058,6 +3053,9 @@ jme_init_one(struct pci_dev *pdev, jme->mii_if.mdio_write = jme_mdio_write; jme_clear_pm(jme); + pci_set_power_state(jme->pdev, PCI_D0); + device_set_wakeup_enable(&pdev->dev, true); + jme_set_phyfifo_5level(jme); jme->pcirev = pdev->revision; if (!jme->fpgaver) @@ -3136,7 +3134,8 @@ jme_shutdown(struct pci_dev *pdev) } #ifdef CONFIG_PM_SLEEP -static int jme_suspend(struct device *dev) +static int +jme_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); @@ -3175,14 +3174,14 @@ static int jme_suspend(struct device *dev) return 0; } -static int jme_resume(struct device *dev) +static int +jme_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct jme_adapter *jme = netdev_priv(netdev); - jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs); - + jme_clear_pm(jme); jme_phy_on(jme); if (test_bit(JME_FLAG_SSET, &jme->flags)) jme_set_settings(netdev, &jme->old_ecmd); diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 0d5da06489d..1481a62a1f3 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -852,6 +852,7 @@ enum jme_ghc_txmac_clk { * Power management control and status register */ enum jme_pmcs_bit_masks { + PMCS_STMASK = 0xFFFF0000, PMCS_WF7DET = 0x80000000, PMCS_WF6DET = 0x40000000, PMCS_WF5DET = 0x20000000, @@ -863,6 +864,7 @@ enum jme_pmcs_bit_masks { PMCS_LFDET = 0x00040000, PMCS_LRDET = 0x00020000, PMCS_MFDET = 0x00010000, + PMCS_ENMASK = 0x0000FFFF, PMCS_WF7EN = 0x00008000, PMCS_WF6EN = 0x00004000, PMCS_WF5EN = 0x00002000, -- cgit v1.2.3-70-g09d2 From f82528bc13a157335dc53e78ce801883b26831e2 Mon Sep 17 00:00:00 2001 From: Alexander Smirnov Date: Tue, 28 Jun 2011 03:30:44 +0000 Subject: Exclude duplicated checking for iface-up. This flags is checked in 'is_skb_forwardable' function, which is subroutine of 'dev_forward_skb'. Signed-off-by: Alexander Smirnov Reviewed-by: WANG Cong Signed-off-by: David S. Miller --- drivers/net/veth.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 4b6db3b6c5d..9eb92bfa92a 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -126,9 +126,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) stats = this_cpu_ptr(priv->stats); rcv_stats = this_cpu_ptr(rcv_priv->stats); - if (!(rcv->flags & IFF_UP)) - goto tx_drop; - /* don't change ip_summed == CHECKSUM_PARTIAL, as that will cause bad checksum on forwarded packets */ if (skb->ip_summed == CHECKSUM_NONE && -- cgit v1.2.3-70-g09d2 From 0311ee2262440b903a81fa38512d12bc2478e66f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 28 Jun 2011 20:29:51 +0000 Subject: wanxl: remove a stray irq enable This is error path calls unlock_irq() where we haven't disabled the IRQs. The comment says that this error path can never happen. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/wan/wanxl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 8d7aa43dfba..44b70719725 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -284,7 +284,7 @@ static netdev_tx_t wanxl_xmit(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name); #endif netif_stop_queue(dev); - spin_unlock_irq(&port->lock); + spin_unlock(&port->lock); return NETDEV_TX_BUSY; /* request packet to be queued */ } -- cgit v1.2.3-70-g09d2 From bda7ed47937bd9ba8c10631ca884f7fefb162f4d Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 29 Jun 2011 02:14:46 +0000 Subject: net: am79c961a: Omit check for multicast bit in netdev_for_each_mc_addr There is no need to check for the address being a multicast address in the netdev_for_each_mc_addr loop, so remove it. Signed-off-by: Tobias Klauser Acked-by: Russell King Signed-off-by: David S. Miller --- drivers/net/arm/am79c961a.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 7b3e23f3891..52fe21e1e2c 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -199,17 +199,15 @@ am79c961_ramtest(struct net_device *dev, unsigned int val) static void am79c961_mc_hash(char *addr, u16 *hash) { - if (addr[0] & 0x01) { - int idx, bit; - u32 crc; + int idx, bit; + u32 crc; - crc = ether_crc_le(ETH_ALEN, addr); + crc = ether_crc_le(ETH_ALEN, addr); - idx = crc >> 30; - bit = (crc >> 26) & 15; + idx = crc >> 30; + bit = (crc >> 26) & 15; - hash[idx] |= 1 << bit; - } + hash[idx] |= 1 << bit; } static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash) -- cgit v1.2.3-70-g09d2 From 3170ff54c26004ea627022af695d0c8709d29b04 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 29 Jun 2011 02:15:15 +0000 Subject: net: depca: Omit check for multicast bit in netdev_for_each_mc_addr There is no need to check for the address being a multicast address in the netdev_for_each_mc_addr loop, so remove it. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/depca.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/depca.c b/drivers/net/depca.c index d54a0e93ba9..a7ccaa67c7d 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -1270,7 +1270,6 @@ static void SetMulticastFilter(struct net_device *dev) { struct depca_private *lp = netdev_priv(dev); struct netdev_hw_addr *ha; - char *addrs; int i, j, bit, byte; u16 hashcode; u32 crc; @@ -1285,19 +1284,15 @@ static void SetMulticastFilter(struct net_device *dev) } /* Add multicast addresses */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - if ((*addrs & 0x01) == 1) { /* multicast address? */ - crc = ether_crc(ETH_ALEN, addrs); - hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */ - for (j = 0; j < 5; j++) { /* ... in reverse order. */ - hashcode = (hashcode << 1) | ((crc >>= 1) & 1); - } - - - byte = hashcode >> 3; /* bit[3-5] -> byte in filter */ - bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */ - lp->init_block.mcast_table[byte] |= bit; + crc = ether_crc(ETH_ALEN, ha->addr); + hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */ + for (j = 0; j < 5; j++) { /* ... in reverse order. */ + hashcode = (hashcode << 1) | ((crc >>= 1) & 1); } + + byte = hashcode >> 3; /* bit[3-5] -> byte in filter */ + bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */ + lp->init_block.mcast_table[byte] |= bit; } } } -- cgit v1.2.3-70-g09d2 From eb31c4e0b0d8d7f673f95644cbfd2993f1c36840 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 29 Jun 2011 02:15:35 +0000 Subject: net: iseries_veth: Omit check for multicast bit in netdev_for_each_mc_addr There is no need to check for the address being a multicast address in the netdev_for_each_mc_addr loop, so remove it. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/iseries_veth.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index b6c296f4b4d..242bf524273 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -964,11 +964,9 @@ static void veth_set_multicast_list(struct net_device *dev) u8 *addr = ha->addr; u64 xaddr = 0; - if (addr[0] & 0x01) {/* multicast address? */ - memcpy(&xaddr, addr, ETH_ALEN); - port->mcast_addr[port->num_mcast] = xaddr; - port->num_mcast++; - } + memcpy(&xaddr, addr, ETH_ALEN); + port->mcast_addr[port->num_mcast] = xaddr; + port->num_mcast++; } } -- cgit v1.2.3-70-g09d2 From 781b864711d8cff56af9478be1b892b098e10de8 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 29 Jun 2011 02:16:33 +0000 Subject: net: ucc_geth: Omit check for multicast bit in netdev_for_each_mc_addr There is no need to check for the address being a multicast address in the netdev_for_each_mc_addr loop, so remove it. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/ucc_geth.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 3127700f348..d3465ab50e5 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -2030,11 +2030,6 @@ static void ucc_geth_set_multi(struct net_device *dev) out_be32(&p_82xx_addr_filt->gaddr_l, 0x0); netdev_for_each_mc_addr(ha, dev) { - /* Only support group multicast for now. - */ - if (!is_multicast_ether_addr(ha->addr)) - continue; - /* Ask CPM to run CRC and set bit in * filter mask. */ -- cgit v1.2.3-70-g09d2 From e1428d26b404133dcbcc8f758f0f4f6575afd7b7 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Wed, 29 Jun 2011 20:00:50 +0000 Subject: qlcnic: add external loopback support o Add external loopback test in self test: - Send set external loopback mode request to fw. To quiscent other storage functions. - Perform test - Send unset loopback mode request to fw. o Rename ilb to lb. o Update driver version 5.0.20. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 5 +++-- drivers/net/qlcnic/qlcnic_ethtool.c | 26 +++++++++++++++++--------- drivers/net/qlcnic/qlcnic_init.c | 3 ++- 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index e5454502df6..9899a794771 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -36,8 +36,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 19 -#define QLCNIC_LINUX_VERSIONID "5.0.19" +#define _QLCNIC_LINUX_SUBVERSION 20 +#define QLCNIC_LINUX_VERSIONID "5.0.20" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -782,6 +782,7 @@ struct qlcnic_mac_list_s { #define QLCNIC_IP_DOWN 3 #define QLCNIC_ILB_MODE 0x1 +#define QLCNIC_ELB_MODE 0x2 #define QLCNIC_LINKEVENT 0x1 #define QLCNIC_LB_RESPONSE 0x2 diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 743035e4538..3ea04e7da91 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -85,7 +85,8 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { "Register_Test_on_offline", "Link_Test_on_offline", "Interrupt_Test_offline", - "Loopback_Test_offline" + "Internal_Loopback_offline", + "External_Loopback_offline" }; #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test) @@ -709,7 +710,7 @@ int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]) return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE); } -static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) +static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter) { struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; @@ -735,19 +736,19 @@ static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) dev_kfree_skb_any(skb); if (!adapter->diag_cnt) - dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet" + dev_warn(&adapter->pdev->dev, "LB Test: %dth packet" " not recevied\n", i + 1); else cnt++; } if (cnt != i) { - dev_warn(&adapter->pdev->dev, "ILB Test failed\n"); + dev_warn(&adapter->pdev->dev, "LB Test failed\n"); return -1; } return 0; } -static int qlcnic_iloopback_test(struct net_device *netdev) +static int qlcnic_loopback_test(struct net_device *netdev, u8 mode) { struct qlcnic_adapter *adapter = netdev_priv(netdev); int max_sds_rings = adapter->max_sds_rings; @@ -755,7 +756,8 @@ static int qlcnic_iloopback_test(struct net_device *netdev) int loop = 0; int ret; - netdev_info(netdev, "%s: in progress\n", __func__); + netdev_info(netdev, "%s loopback test in progress\n", + mode == QLCNIC_ILB_MODE ? "internal" : "external"); if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { netdev_warn(netdev, "Loopback test not supported for non " "privilege function\n"); @@ -772,7 +774,7 @@ static int qlcnic_iloopback_test(struct net_device *netdev) sds_ring = &adapter->recv_ctx->sds_rings[0]; - ret = qlcnic_set_lb_mode(adapter, QLCNIC_ILB_MODE); + ret = qlcnic_set_lb_mode(adapter, mode); if (ret) goto free_res; @@ -790,7 +792,7 @@ static int qlcnic_iloopback_test(struct net_device *netdev) goto free_res; } - ret = qlcnic_do_ilb_test(adapter); + ret = qlcnic_do_lb_test(adapter); qlcnic_clear_lb_mode(adapter); @@ -822,10 +824,16 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, if (data[2]) eth_test->flags |= ETH_TEST_FL_FAILED; - data[3] = qlcnic_iloopback_test(dev); + data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE); if (data[3]) eth_test->flags |= ETH_TEST_FL_FAILED; + if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) { + data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE); + if (data[4]) + eth_test->flags |= ETH_TEST_FL_FAILED; + eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE; + } } } diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 9d5bee03a58..6ec1baa85f6 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1303,7 +1303,8 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, dev_info(&netdev->dev, "unsupported cable length %d\n", cable_len); - if (!link_status && (lb_status == 1)) + if (!link_status && (lb_status == QLCNIC_ILB_MODE || + lb_status == QLCNIC_ELB_MODE)) adapter->ahw->loopback_state |= QLCNIC_LINKEVENT; qlcnic_advert_link_change(adapter, link_status); -- cgit v1.2.3-70-g09d2 From 2b3f291bf98e7cbf76afd9b0c96c81df5f5890f9 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 29 Jun 2011 23:32:56 +0000 Subject: be2net: fix certain cmd failure logging Some (older)versions of cards/fw may not recognize certain cmds and return illegal/unsupported errors. As long as the driver can handle this gracefully there is no need to log an error msg. Also finetuned 2 existing error log messages. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 24 +++++++++++++++++------- drivers/net/benet/be_cmds.h | 17 ++++++----------- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 30719f591fb..d09351c56a1 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -106,14 +106,24 @@ static int be_mcc_compl_process(struct be_adapter *adapter, netdev_stats_update(adapter); adapter->stats_cmd_sent = false; } - } else if ((compl_status != MCC_STATUS_NOT_SUPPORTED) && - (compl->tag0 != OPCODE_COMMON_NTWK_MAC_QUERY)) { - extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & - CQE_STATUS_EXTD_MASK; - dev_warn(&adapter->pdev->dev, - "Error in cmd completion - opcode %d, compl %d, extd %d\n", - compl->tag0, compl_status, extd_status); + } else { + if (compl_status == MCC_STATUS_NOT_SUPPORTED || + compl_status == MCC_STATUS_ILLEGAL_REQUEST) + goto done; + + if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { + dev_warn(&adapter->pdev->dev, "This domain(VM) is not " + "permitted to execute this cmd (opcode %d)\n", + compl->tag0); + } else { + extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & + CQE_STATUS_EXTD_MASK; + dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:" + "status %d, extd-status %d\n", + compl->tag0, compl_status, extd_status); + } } +done: return compl_status; } diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index d08289e21f6..f0d745742d9 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -51,17 +51,12 @@ struct be_mcc_wrb { /* Completion Status */ enum { - MCC_STATUS_SUCCESS = 0x0, -/* The client does not have sufficient privileges to execute the command */ - MCC_STATUS_INSUFFICIENT_PRIVILEGES = 0x1, -/* A parameter in the command was invalid. */ - MCC_STATUS_INVALID_PARAMETER = 0x2, -/* There are insufficient chip resources to execute the command */ - MCC_STATUS_INSUFFICIENT_RESOURCES = 0x3, -/* The command is completing because the queue was getting flushed */ - MCC_STATUS_QUEUE_FLUSHING = 0x4, -/* The command is completing with a DMA error */ - MCC_STATUS_DMA_FAILED = 0x5, + MCC_STATUS_SUCCESS = 0, + MCC_STATUS_FAILED = 1, + MCC_STATUS_ILLEGAL_REQUEST = 2, + MCC_STATUS_ILLEGAL_FIELD = 3, + MCC_STATUS_INSUFFICIENT_BUFFER = 4, + MCC_STATUS_UNAUTHORIZED_REQUEST = 5, MCC_STATUS_NOT_SUPPORTED = 66 }; -- cgit v1.2.3-70-g09d2 From 482c9e798738dea847a5e5e0d20692fe80d48a76 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 29 Jun 2011 23:33:17 +0000 Subject: be2net: create/destroy rx-queues on interface open/close On some skews, the BE card sends pause frames (and not drop pkts) if there are no more posted buffers available for packet reception. This behaviour has a side effect: When an interface is disabled, buffers are no longer posted on the corresponding RX rings. All broadcast and multicast traffic being received on the port will quickly fill up the PMEM and cause pause push back. As the PMEM is shared by both the ports, all traffic being received on the other (enabled) port also gets stalled. The fix is to destroy RX rings when the interface is disabled. If there is no RX ring match in the RXF lookup, the packets are discarded and so don't hog the PMEM. The RXQ creation cmd must now use MCC instead of MBOX as they are are called post MCC queue creation. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 48 +++++++++++++++++--- drivers/net/benet/be_cmds.h | 2 + drivers/net/benet/be_main.c | 105 ++++++++++++++++++++++++++++---------------- 3 files changed, 111 insertions(+), 44 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index d09351c56a1..f520a5c7503 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -984,7 +984,7 @@ int be_cmd_txq_create(struct be_adapter *adapter, return status; } -/* Uses mbox */ +/* Uses MCC */ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_queue_info *rxq, u16 cq_id, u16 frag_size, u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id) @@ -994,10 +994,13 @@ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_dma_mem *q_mem = &rxq->dma_mem; int status; - if (mutex_lock_interruptible(&adapter->mbox_lock)) - return -1; + spin_lock_bh(&adapter->mcc_lock); - wrb = wrb_from_mbox(adapter); + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } req = embedded_payload(wrb); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, @@ -1014,7 +1017,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, req->max_frame_size = cpu_to_le16(max_frame_size); req->rss_queue = cpu_to_le32(rss); - status = be_mbox_notify_wait(adapter); + status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); rxq->id = le16_to_cpu(resp->id); @@ -1022,8 +1025,8 @@ int be_cmd_rxq_create(struct be_adapter *adapter, *rss_id = resp->rss_id; } - mutex_unlock(&adapter->mbox_lock); - +err: + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1078,9 +1081,40 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, req->id = cpu_to_le16(q->id); status = be_mbox_notify_wait(adapter); + if (!status) + q->created = false; mutex_unlock(&adapter->mbox_lock); + return status; +} +/* Uses MCC */ +int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_q_destroy *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_RX_DESTROY); + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_RX_DESTROY, + sizeof(*req)); + req->id = cpu_to_le16(q->id); + + status = be_mcc_notify_wait(adapter); + if (!status) + q->created = false; + +err: + spin_unlock_bh(&adapter->mcc_lock); return status; } diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index f0d745742d9..1151df6b002 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -1482,6 +1482,8 @@ extern int be_cmd_rxq_create(struct be_adapter *adapter, u32 rss, u8 *rss_id); extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, int type); +extern int be_cmd_rxq_destroy(struct be_adapter *adapter, + struct be_queue_info *q); extern int be_cmd_link_status_query(struct be_adapter *adapter, bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom); extern int be_cmd_reset(struct be_adapter *adapter); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ae281de94b9..5b319d78f35 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1572,6 +1572,7 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) memset(page_info, 0, sizeof(*page_info)); } BUG_ON(atomic_read(&rxq->used)); + rxq->tail = rxq->head = 0; } static void be_tx_compl_clean(struct be_adapter *adapter, @@ -1752,29 +1753,16 @@ static void be_rx_queues_destroy(struct be_adapter *adapter) int i; for_all_rx_queues(adapter, rxo, i) { - q = &rxo->q; - if (q->created) { - be_cmd_q_destroy(adapter, q, QTYPE_RXQ); - /* After the rxq is invalidated, wait for a grace time - * of 1ms for all dma to end and the flush compl to - * arrive - */ - mdelay(1); - be_rx_q_clean(adapter, rxo); - } - be_queue_free(adapter, q); + be_queue_free(adapter, &rxo->q); q = &rxo->cq; if (q->created) be_cmd_q_destroy(adapter, q, QTYPE_CQ); be_queue_free(adapter, q); - /* Clear any residual events */ q = &rxo->rx_eq.q; - if (q->created) { - be_eq_clean(adapter, &rxo->rx_eq); + if (q->created) be_cmd_q_destroy(adapter, q, QTYPE_EQ); - } be_queue_free(adapter, q); } } @@ -1833,30 +1821,14 @@ static int be_rx_queues_create(struct be_adapter *adapter) rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); if (rc) goto err; - /* Rx Q */ + + /* Rx Q - will be created in be_open() */ q = &rxo->q; rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d)); if (rc) goto err; - rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size, - BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, - (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id); - if (rc) - goto err; - } - - if (be_multi_rxq(adapter)) { - u8 rsstable[MAX_RSS_QS]; - - for_all_rss_queues(adapter, rxo, i) - rsstable[i] = rxo->rss_id; - - rc = be_cmd_rss_config(adapter, rsstable, - adapter->num_rx_qs - 1); - if (rc) - goto err; } return 0; @@ -2302,6 +2274,31 @@ done: adapter->isr_registered = false; } +static void be_rx_queues_clear(struct be_adapter *adapter) +{ + struct be_queue_info *q; + struct be_rx_obj *rxo; + int i; + + for_all_rx_queues(adapter, rxo, i) { + q = &rxo->q; + if (q->created) { + be_cmd_rxq_destroy(adapter, q); + /* After the rxq is invalidated, wait for a grace time + * of 1ms for all dma to end and the flush compl to + * arrive + */ + mdelay(1); + be_rx_q_clean(adapter, rxo); + } + + /* Clear any residual events */ + q = &rxo->rx_eq.q; + if (q->created) + be_eq_clean(adapter, &rxo->rx_eq); + } +} + static int be_close(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); @@ -2350,6 +2347,40 @@ static int be_close(struct net_device *netdev) for_all_tx_queues(adapter, txo, i) be_tx_compl_clean(adapter, txo); + be_rx_queues_clear(adapter); + return 0; +} + +static int be_rx_queues_setup(struct be_adapter *adapter) +{ + struct be_rx_obj *rxo; + int rc, i; + u8 rsstable[MAX_RSS_QS]; + + for_all_rx_queues(adapter, rxo, i) { + rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, + rx_frag_size, BE_MAX_JUMBO_FRAME_SIZE, + adapter->if_handle, + (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id); + if (rc) + return rc; + } + + if (be_multi_rxq(adapter)) { + for_all_rss_queues(adapter, rxo, i) + rsstable[i] = rxo->rss_id; + + rc = be_cmd_rss_config(adapter, rsstable, + adapter->num_rx_qs - 1); + if (rc) + return rc; + } + + /* First time posting */ + for_all_rx_queues(adapter, rxo, i) { + be_post_rx_frags(rxo, GFP_KERNEL); + napi_enable(&rxo->rx_eq.napi); + } return 0; } @@ -2363,10 +2394,10 @@ static int be_open(struct net_device *netdev) u8 mac_speed; u16 link_speed; - for_all_rx_queues(adapter, rxo, i) { - be_post_rx_frags(rxo, GFP_KERNEL); - napi_enable(&rxo->rx_eq.napi); - } + status = be_rx_queues_setup(adapter); + if (status) + goto err; + napi_enable(&tx_eq->napi); be_irq_register(adapter); -- cgit v1.2.3-70-g09d2 From b9ab82c774d8abcca8b6c1d5f30f5912a4448980 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 29 Jun 2011 23:33:37 +0000 Subject: be2net: clear intr bit in be_probe() It may be set in the card while the driver is probed by kdump kernel after a crash. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 5b319d78f35..696f634b7e3 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -3417,6 +3417,12 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto stats_clean; + /* The INTR bit may be set in the card when probed by a kdump kernel + * after a crash. + */ + if (!lancer_chip(adapter)) + be_intr_set(adapter, false); + be_msix_enable(adapter); INIT_DELAYED_WORK(&adapter->work, be_worker); -- cgit v1.2.3-70-g09d2 From e77aeb71f04ed236fffe5f347e208c8b0e92d48a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 30 Jun 2011 21:37:52 +0000 Subject: net: de4x5: Omit check for multicast bit in netdev_for_each_mc_addr There is no need to check for the address being a multicast address in the netdev_for_each_mc_addr loop, so remove it. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/tulip/de4x5.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index efaa1d69b72..d8db2b664ac 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1964,9 +1964,7 @@ SetMulticastFilter(struct net_device *dev) omr |= OMR_PM; /* Pass all multicasts */ } else if (lp->setup_f == HASH_PERF) { /* Hash Filtering */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - if ((*addrs & 0x01) == 1) { /* multicast address? */ - crc = ether_crc_le(ETH_ALEN, addrs); + crc = ether_crc_le(ETH_ALEN, ha->addr); hashcode = crc & HASH_BITS; /* hashcode is 9 LSb of CRC */ byte = hashcode >> 3; /* bit[3-8] -> byte in filter */ @@ -1977,7 +1975,6 @@ SetMulticastFilter(struct net_device *dev) byte -= 1; } lp->setup_frame[byte] |= bit; - } } } else { /* Perfect filtering */ netdev_for_each_mc_addr(ha, dev) { -- cgit v1.2.3-70-g09d2 From 98a648e10a3c4eb30f8043281345506e17ace007 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Jun 2011 06:06:42 -0700 Subject: iwlagn: verify mutex held for sync commands Emmanuel noticed that there's no explicit checking that prevents the driver from attempting to issue multiple synchronous commands at the same time and wrote a patch to check. However, his patch warns only if a collision actually happened, an unlikely thing since the driver mutex should be held for synchronous command submissions. So instead of checking that a collision happened add a check that the mutex is held which ensures that collisions can't happen. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 13 +++---------- 2 files changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8ec04f20c96..ae2ecc24b91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1301,7 +1301,6 @@ struct iwl_priv { /* command queue number */ u8 cmd_queue; - u8 last_sync_cmd_id; /* max number of station keys */ u8 sta_key_max_num; diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index e3e5fb61417..107b38e2ee9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -171,6 +171,8 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) int cmd_idx; int ret; + lockdep_assert_held(&priv->mutex); + if (WARN_ON(cmd->flags & CMD_ASYNC)) return -EINVAL; @@ -181,16 +183,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); - if (test_and_set_bit(STATUS_HCMD_ACTIVE, &priv->status)) { - IWL_ERR(priv, "STATUS_HCMD_ACTIVE already set while sending %s" - ". Previous SYNC cmdn is %s\n", - get_cmd_string(cmd->id), - get_cmd_string(priv->last_sync_cmd_id)); - WARN_ON(1); - } else { - priv->last_sync_cmd_id = cmd->id; - } - + set_bit(STATUS_HCMD_ACTIVE, &priv->status); IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->id)); -- cgit v1.2.3-70-g09d2 From 4466320f053bb9aa1d68f73d92cb8d6c5bd75b1c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 24 Jun 2011 09:02:44 -0700 Subject: iwlagn: re-define the testmode cmd and attr enum To make sure not having issues when adding new testmode commands or attributes in the future, re-define the enum. no functional changes Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-testmode.h | 236 ++++++++++++++++------------ 1 file changed, 132 insertions(+), 104 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 160911a3716..d825188e521 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -66,116 +66,144 @@ #include -/* Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and +/* + * Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX). - * The command ID is carried with IWL_TM_ATTR_COMMAND. There are three types of - * of command from user space and two types of command from kernel space. - * See below. + * The command ID is carried with IWL_TM_ATTR_COMMAND. + * + * @IWL_TM_CMD_APP2DEV_UCODE: + * commands from user application to the uCode, + * the actual uCode host command ID is carried with + * IWL_TM_ATTR_UCODE_CMD_ID + * + * @IWL_TM_CMD_APP2DEV_REG_READ32: + * @IWL_TM_CMD_APP2DEV_REG_WRITE32: + * @IWL_TM_CMD_APP2DEV_REG_WRITE8: + * commands from user applicaiton to access register + * + * @IWL_TM_CMD_APP2DEV_GET_DEVICENAME: retrieve device name + * @IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: load initial uCode image + * @IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: perform calibration + * @IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: load runtime uCode image + * @IWL_TM_CMD_APP2DEV_GET_EEPROM: request EEPROM data + * @IWL_TM_CMD_APP2DEV_FIXRATE_REQ: set fix MCS + * commands fom user space for pure driver level operations + * + * @IWL_TM_CMD_APP2DEV_BEGIN_TRACE: + * @IWL_TM_CMD_APP2DEV_END_TRACE: + * @IWL_TM_CMD_APP2DEV_READ_TRACE: + * commands fom user space for uCode trace operations + * + * @IWL_TM_CMD_DEV2APP_SYNC_RSP: + * commands from kernel space to carry the synchronous response + * to user application + * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT: + * commands from kernel space to multicast the spontaneous messages + * to user application + * @IWL_TM_CMD_DEV2APP_EEPROM_RSP: + * commands from kernel space to carry the eeprom response + * to user application */ enum iwl_tm_cmd_t { - /* commands from user application to the uCode, - * the actual uCode host command ID is carried with - * IWL_TM_ATTR_UCODE_CMD_ID */ - IWL_TM_CMD_APP2DEV_UCODE = 1, - - /* commands from user applicaiton to access register */ - IWL_TM_CMD_APP2DEV_REG_READ32, - IWL_TM_CMD_APP2DEV_REG_WRITE32, - IWL_TM_CMD_APP2DEV_REG_WRITE8, - - /* commands fom user space for pure driver level operations */ - IWL_TM_CMD_APP2DEV_GET_DEVICENAME, - IWL_TM_CMD_APP2DEV_LOAD_INIT_FW, - IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB, - IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW, - IWL_TM_CMD_APP2DEV_GET_EEPROM, - IWL_TM_CMD_APP2DEV_FIXRATE_REQ, - /* if there is other new command for the driver layer operation, - * append them here */ - - /* commands fom user space for uCode trace operations */ - IWL_TM_CMD_APP2DEV_BEGIN_TRACE, - IWL_TM_CMD_APP2DEV_END_TRACE, - IWL_TM_CMD_APP2DEV_READ_TRACE, - - /* commands from kernel space to carry the synchronous response - * to user application */ - IWL_TM_CMD_DEV2APP_SYNC_RSP, - - /* commands from kernel space to multicast the spontaneous messages - * to user application */ - IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, - - /* commands from kernel space to carry the eeprom response - * to user application */ - IWL_TM_CMD_DEV2APP_EEPROM_RSP, - - IWL_TM_CMD_MAX, + IWL_TM_CMD_APP2DEV_UCODE = 1, + IWL_TM_CMD_APP2DEV_REG_READ32 = 2, + IWL_TM_CMD_APP2DEV_REG_WRITE32 = 3, + IWL_TM_CMD_APP2DEV_REG_WRITE8 = 4, + IWL_TM_CMD_APP2DEV_GET_DEVICENAME = 5, + IWL_TM_CMD_APP2DEV_LOAD_INIT_FW = 6, + IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB = 7, + IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW = 8, + IWL_TM_CMD_APP2DEV_GET_EEPROM = 9, + IWL_TM_CMD_APP2DEV_FIXRATE_REQ = 10, + IWL_TM_CMD_APP2DEV_BEGIN_TRACE = 11, + IWL_TM_CMD_APP2DEV_END_TRACE = 12, + IWL_TM_CMD_APP2DEV_READ_TRACE = 13, + IWL_TM_CMD_DEV2APP_SYNC_RSP = 14, + IWL_TM_CMD_DEV2APP_UCODE_RX_PKT = 15, + IWL_TM_CMD_DEV2APP_EEPROM_RSP = 16, + IWL_TM_CMD_MAX = 17, }; +/* + * Atrribute filed in testmode command + * See enum iwl_tm_cmd_t. + * + * @IWL_TM_ATTR_NOT_APPLICABLE: + * The attribute is not applicable or invalid + * @IWL_TM_ATTR_COMMAND: + * From user space to kernel space: + * the command either destines to ucode, driver, or register; + * From kernel space to user space: + * the command either carries synchronous response, + * or the spontaneous message multicast from the device; + * + * @IWL_TM_ATTR_UCODE_CMD_ID: + * @IWL_TM_ATTR_UCODE_CMD_DATA: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE, + * The mandatory fields are : + * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID; + * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands; + * The optional fields are: + * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload + * to the ucode + * + * @IWL_TM_ATTR_REG_OFFSET: + * @IWL_TM_ATTR_REG_VALUE8: + * @IWL_TM_ATTR_REG_VALUE32: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX, + * The mandatory fields are: + * IWL_TM_ATTR_REG_OFFSET for the offset of the target register; + * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value + * + * @IWL_TM_ATTR_SYNC_RSP: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP, + * The mandatory fields are: + * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user + * application command + * + * @IWL_TM_ATTR_UCODE_RX_PKT: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, + * The mandatory fields are: + * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user + * application + * + * @IWL_TM_ATTR_EEPROM: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM, + * The mandatory fields are: + * IWL_TM_ATTR_EEPROM for the data content responging to the user + * application + * + * @IWL_TM_ATTR_TRACE_ADDR: + * @IWL_TM_ATTR_TRACE_SIZE: + * @IWL_TM_ATTR_TRACE_DUMP: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE, + * The mandatory fields are: + * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address + * IWL_TM_ATTR_MEM_TRACE_SIZE for the trace buffer size + * IWL_TM_ATTR_MEM_TRACE_DUMP for the trace dump + * + * @IWL_TM_ATTR_FIXRATE: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, + * The mandatory fields are: + * IWL_TM_ATTR_FIXRATE for the fixed rate + * + */ enum iwl_tm_attr_t { - IWL_TM_ATTR_NOT_APPLICABLE = 0, - - /* From user space to kernel space: - * the command either destines to ucode, driver, or register; - * See enum iwl_tm_cmd_t. - * - * From kernel space to user space: - * the command either carries synchronous response, - * or the spontaneous message multicast from the device; - * See enum iwl_tm_cmd_t. */ - IWL_TM_ATTR_COMMAND, - - /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE, - * The mandatory fields are : - * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID; - * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands; - * The optional fields are: - * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload - * to the ucode */ - IWL_TM_ATTR_UCODE_CMD_ID, - IWL_TM_ATTR_UCODE_CMD_DATA, - - /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX, - * The mandatory fields are: - * IWL_TM_ATTR_REG_OFFSET for the offset of the target register; - * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value */ - IWL_TM_ATTR_REG_OFFSET, - IWL_TM_ATTR_REG_VALUE8, - IWL_TM_ATTR_REG_VALUE32, - - /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP, - * The mandatory fields are: - * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user - * application command */ - IWL_TM_ATTR_SYNC_RSP, - /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, - * The mandatory fields are: - * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user - * application */ - IWL_TM_ATTR_UCODE_RX_PKT, - - /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM, - * The mandatory fields are: - * IWL_TM_ATTR_EEPROM for the data content responging to the user - * application */ - IWL_TM_ATTR_EEPROM, - - /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE, - * The mandatory fields are: - * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address - */ - IWL_TM_ATTR_TRACE_ADDR, - IWL_TM_ATTR_TRACE_SIZE, - IWL_TM_ATTR_TRACE_DUMP, - - /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, - * The mandatory fields are: - * IWL_TM_ATTR_FIXRATE for the fixed rate - */ - IWL_TM_ATTR_FIXRATE, - - IWL_TM_ATTR_MAX, + IWL_TM_ATTR_NOT_APPLICABLE = 0, + IWL_TM_ATTR_COMMAND = 1, + IWL_TM_ATTR_UCODE_CMD_ID = 2, + IWL_TM_ATTR_UCODE_CMD_DATA = 3, + IWL_TM_ATTR_REG_OFFSET = 4, + IWL_TM_ATTR_REG_VALUE8 = 5, + IWL_TM_ATTR_REG_VALUE32 = 6, + IWL_TM_ATTR_SYNC_RSP = 7, + IWL_TM_ATTR_UCODE_RX_PKT = 8, + IWL_TM_ATTR_EEPROM = 9, + IWL_TM_ATTR_TRACE_ADDR = 10, + IWL_TM_ATTR_TRACE_SIZE = 11, + IWL_TM_ATTR_TRACE_DUMP = 12, + IWL_TM_ATTR_FIXRATE = 13, + IWL_TM_ATTR_MAX = 14, }; /* uCode trace buffer */ -- cgit v1.2.3-70-g09d2 From 54e9c409a5f9e58465d80d6774afd85a449a4615 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Jul 2011 07:47:59 -0700 Subject: iwlagn: add correct firmware name for 135 series 135 series are WiFi/BT combo and require different uCode from 105 series. [A Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 64ed1f247df..76a3e42a4ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -50,11 +50,13 @@ #define IWL2030_UCODE_API_MAX 5 #define IWL2000_UCODE_API_MAX 5 #define IWL105_UCODE_API_MAX 5 +#define IWL135_UCODE_API_MAX 5 /* Lowest firmware API version supported */ #define IWL2030_UCODE_API_MIN 5 #define IWL2000_UCODE_API_MIN 5 #define IWL105_UCODE_API_MIN 5 +#define IWL135_UCODE_API_MIN 5 #define IWL2030_FW_PRE "iwlwifi-2030-" #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" @@ -65,6 +67,9 @@ #define IWL105_FW_PRE "iwlwifi-105-" #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" +#define IWL135_FW_PRE "iwlwifi-135-" +#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE #api ".ucode" + static void iwl2000_set_ct_threshold(struct iwl_priv *priv) { /* want Celsius */ @@ -344,9 +349,9 @@ struct iwl_cfg iwl105_bgn_cfg = { }; #define IWL_DEVICE_135 \ - .fw_name_pre = IWL105_FW_PRE, \ - .ucode_api_max = IWL105_UCODE_API_MAX, \ - .ucode_api_min = IWL105_UCODE_API_MIN, \ + .fw_name_pre = IWL135_FW_PRE, \ + .ucode_api_max = IWL135_UCODE_API_MAX, \ + .ucode_api_min = IWL135_UCODE_API_MIN, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .ops = &iwl135_ops, \ @@ -359,12 +364,12 @@ struct iwl_cfg iwl105_bgn_cfg = { .rx_with_siso_diversity = true \ struct iwl_cfg iwl135_bg_cfg = { - .name = "105 Series 1x1 BG/BT", + .name = "135 Series 1x1 BG/BT", IWL_DEVICE_135, }; struct iwl_cfg iwl135_bgn_cfg = { - .name = "105 Series 1x1 BGN/BT", + .name = "135 Series 1x1 BGN/BT", IWL_DEVICE_135, .ht_params = &iwl2000_ht_params, }; @@ -372,3 +377,4 @@ struct iwl_cfg iwl135_bgn_cfg = { MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX)); -- cgit v1.2.3-70-g09d2 From 300d0834ebd3f3c57b0063c2fd6bc26d8405626c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 25 Jun 2011 09:17:41 -0700 Subject: iwlagn: add module parameter to disable stuck queue watchdog timer Add the parameter to disable stuck queue watchdog timer, different platforms might have different timing. Provide the option to disable the timer to prevent un-necessary firmware reload. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e2f6b2ab0d4..58789e876d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3820,6 +3820,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); +module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); +MODULE_PARM_DESC(wd_disable, + "Disable stuck queue watchdog timer (default: 0 [enabled])"); + /* * set bt_coex_active to true, uCode will do kill/defer * every time the priority line is asserted (BT is sending signals on the diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7f16d120305..c5fa232b5eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1853,7 +1853,7 @@ void iwl_setup_watchdog(struct iwl_priv *priv) { unsigned int timeout = priv->cfg->base_params->wd_timeout; - if (timeout) + if (timeout && !iwlagn_mod_params.wd_disable) mod_timer(&priv->watchdog, jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); else diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f881678be76..a311cf836ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -160,6 +160,7 @@ struct iwl_mod_params { int restart_fw; /* def: 1 = restart firmware */ bool plcp_check; /* def: true = enable plcp health check */ bool ack_check; /* def: false = disable ack health check */ + bool wd_disable; /* def: false = enable stuck queue check */ bool bt_coex_active; /* def: true = enable bt coex */ int led_mode; /* def: 0 = system default */ bool no_sleep_autoadjust; /* def: true = disable autoadjust */ -- cgit v1.2.3-70-g09d2 From c85eb6196958ae54eba3ff0660d2b5af3d58521a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jun 2011 10:13:24 +0300 Subject: iwlagn: introduce transport layer and implement rx_init The transport layer is responsible for all the queues, DMA rings etc... This is the beginning of the separation of all the code that is tighly related to HW design to the aforementioned transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 41 +------- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 16 +++ drivers/net/wireless/iwlwifi/iwl-pci.c | 1 + drivers/net/wireless/iwlwifi/iwl-rx.c | 40 -------- drivers/net/wireless/iwlwifi/iwl-trans.c | 155 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-trans.h | 64 ++++++++++++ 10 files changed, 241 insertions(+), 83 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-trans.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-trans.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 9a56ce54671..19150398a24 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -14,6 +14,7 @@ iwlagn-objs += iwl-6000.o iwlagn-objs += iwl-1000.o iwlagn-objs += iwl-2000.o iwlagn-objs += iwl-pci.o +iwlagn-objs += iwl-trans.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index efdab6506ae..3d971142786 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -628,38 +628,6 @@ struct iwl_mod_params iwlagn_mod_params = { /* the rest are 0 by default */ }; -void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - unsigned long flags; - int i; - spin_lock_irqsave(&rxq->lock, flags); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); - /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { - /* In the reset function, these buffers may have been allocated - * to an SKB, so we need to unmap and free potential storage */ - if (rxq->pool[i].page != NULL) { - dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - DMA_FROM_DEVICE); - __iwl_free_pages(priv, rxq->pool[i].page); - rxq->pool[i].page = NULL; - } - list_add_tail(&rxq->pool[i].list, &rxq->rx_used); - } - - for (i = 0; i < RX_QUEUE_SIZE; i++) - rxq->queue[i] = NULL; - - /* Set us so that we have processed and used all buffers, but have - * not restocked the Rx queue with fresh buffers */ - rxq->read = rxq->write = 0; - rxq->write_actual = 0; - rxq->free_count = 0; - spin_unlock_irqrestore(&rxq->lock, flags); -} - int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) { u32 rb_size; @@ -747,14 +715,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) priv->cfg->ops->lib->apm_ops.config(priv); /* Allocate the RX queue, or reset if it is already allocated */ - if (!rxq->bd) { - ret = iwl_rx_queue_alloc(priv); - if (ret) { - IWL_ERR(priv, "Unable to initialize Rx queue\n"); - return -ENOMEM; - } - } else - iwlagn_rx_queue_reset(priv, rxq); + priv->trans.ops->rx_init(priv); iwlagn_rx_replenish(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 58789e876d7..b0657187158 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -56,7 +56,7 @@ #include "iwl-agn-calib.h" #include "iwl-agn.h" #include "iwl-pci.h" - +#include "iwl-trans.h" /****************************************************************************** * @@ -3517,6 +3517,8 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, priv->bus.ops->set_drv_data(&priv->bus, priv); priv->bus.dev = priv->bus.ops->get_dev(&priv->bus); + iwl_trans_register(&priv->trans); + /* At this point both hw and priv are allocated. */ SET_IEEE80211_DEV(hw, priv->bus.dev); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index dcdf2259520..7273297a6f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -182,7 +182,6 @@ void iwlagn_temperature(struct iwl_priv *priv); u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); -void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); int iwlagn_hw_nic_init(struct iwl_priv *priv); int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a311cf836ef..13d819b94ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -383,7 +383,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, ******************************************************/ void iwl_cmd_queue_free(struct iwl_priv *priv); void iwl_cmd_queue_unmap(struct iwl_priv *priv); -int iwl_rx_queue_alloc(struct iwl_priv *priv); void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q); int iwl_rx_queue_space(const struct iwl_rx_queue *q); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ae2ecc24b91..7d3e55d0bc6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1227,6 +1227,21 @@ struct iwl_bus { unsigned int irq; }; +struct iwl_trans; + +/** + * struct iwl_trans_ops - transport specific operations + + * @rx_init: inits the rx memory, allocate it if needed + */ +struct iwl_trans_ops { + int (*rx_init)(struct iwl_priv *priv); +}; + +struct iwl_trans { + const struct iwl_trans_ops *ops; +}; + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1295,6 +1310,7 @@ struct iwl_priv { struct mutex mutex; struct iwl_bus bus; /* bus specific data */ + struct iwl_trans trans; /* microcode/device supports multiple contexts */ u8 valid_contexts; diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 3b5844b60e7..2c26b42bd15 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -67,6 +67,7 @@ #include "iwl-agn.h" #include "iwl-core.h" #include "iwl-io.h" +#include "iwl-trans.h" /* PCI registers */ #define PCI_CFG_RETRY_TIMEOUT 0x041 diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 3efa7066e98..065d2c02655 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -179,46 +179,6 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q spin_unlock_irqrestore(&q->lock, flags); } -int iwl_rx_queue_alloc(struct iwl_priv *priv) -{ - struct iwl_rx_queue *rxq = &priv->rxq; - struct device *dev = priv->bus.dev; - int i; - - spin_lock_init(&rxq->lock); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); - - /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ - rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, - GFP_KERNEL); - if (!rxq->bd) - goto err_bd; - - rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status), - &rxq->rb_stts_dma, GFP_KERNEL); - if (!rxq->rb_stts) - goto err_rb; - - /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) - list_add_tail(&rxq->pool[i].list, &rxq->rx_used); - - /* Set us so that we have processed and used all buffers, but have - * not restocked the Rx queue with fresh buffers */ - rxq->read = rxq->write = 0; - rxq->write_actual = 0; - rxq->free_count = 0; - rxq->need_update = 0; - return 0; - -err_rb: - dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->bd_dma); -err_bd: - return -ENOMEM; -} - /****************************************************************************** * * Generic RX handler implementations diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c new file mode 100644 index 00000000000..ccf73ff6395 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -0,0 +1,155 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + #include "iwl-dev.h" +#include "iwl-trans.h" + +static int iwl_trans_rx_alloc(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct device *dev = priv->bus.dev; + + memset(&priv->rxq, 0, sizeof(priv->rxq)); + + spin_lock_init(&rxq->lock); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + + if (WARN_ON(rxq->bd || rxq->rb_stts)) + return -EINVAL; + + /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ + /*Every descriptor is an __le32, hence its */ + rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, + GFP_KERNEL); + if (!rxq->bd) + goto err_bd; + memset(rxq->bd, 0, 4 * RX_QUEUE_SIZE); + + /*Allocate the driver's pointer to receive buffer status */ + rxq->rb_stts = dma_alloc_coherent(dev, sizeof(*rxq->rb_stts), + &rxq->rb_stts_dma, GFP_KERNEL); + if (!rxq->rb_stts) + goto err_rb_stts; + memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); + + return 0; + +err_rb_stts: + dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma); + memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); + rxq->bd = NULL; +err_bd: + return -ENOMEM; +} + +static int iwl_trans_rx_init(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + int i, err; + unsigned long flags; + + if (!rxq->bd) { + err = iwl_trans_rx_alloc(priv); + if (err) + return err; + } + + spin_lock_irqsave(&rxq->lock, flags); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { + /* In the reset function, these buffers may have been allocated + * to an SKB, so we need to unmap and free potential storage */ + if (rxq->pool[i].page != NULL) { + dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + DMA_FROM_DEVICE); + __iwl_free_pages(priv, rxq->pool[i].page); + rxq->pool[i].page = NULL; + } + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + } + + for (i = 0; i < RX_QUEUE_SIZE; i++) + rxq->queue[i] = NULL; + + /* Set us so that we have processed and used all buffers, but have + * not restocked the Rx queue with fresh buffers */ + rxq->read = rxq->write = 0; + rxq->write_actual = 0; + rxq->free_count = 0; + spin_unlock_irqrestore(&rxq->lock, flags); + + return 0; +} + +static const struct iwl_trans_ops trans_ops = { + .rx_init = iwl_trans_rx_init, +}; + +void iwl_trans_register(struct iwl_trans *trans) +{ + trans->ops = &trans_ops; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h new file mode 100644 index 00000000000..bec494c5a97 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +void iwl_trans_register(struct iwl_trans *trans); -- cgit v1.2.3-70-g09d2 From a0f6b0a211fbdfbae603ffa434f0d9e691e55ab9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 21 Jun 2011 14:25:45 +0300 Subject: iwlagn: add rx_free to transport layer The transport layer ness to release all rx ressources. This function is an API for it. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 27 ----------- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 2 + drivers/net/wireless/iwlwifi/iwl-trans.c | 78 ++++++++++++++++++++++-------- 5 files changed, 62 insertions(+), 49 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3d971142786..a2c5c6b6cd3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -910,33 +910,6 @@ void iwlagn_rx_replenish_now(struct iwl_priv *priv) iwlagn_rx_queue_restock(priv); } -/* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have its SKB set to NULL - * This free routine walks the list of POOL entries and if SKB is set to - * non NULL it is unmapped and freed - */ -void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - int i; - for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { - if (rxq->pool[i].page != NULL) { - dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - DMA_FROM_DEVICE); - __iwl_free_pages(priv, rxq->pool[i].page); - rxq->pool[i].page = NULL; - } - } - - dma_free_coherent(priv->bus.dev, 4 * RX_QUEUE_SIZE, - rxq->bd, rxq->bd_dma); - dma_free_coherent(priv->bus.dev, - sizeof(struct iwl_rb_status), - rxq->rb_stts, rxq->rb_stts_dma); - rxq->bd = NULL; - rxq->rb_stts = NULL; -} - int iwlagn_rxq_stop(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b0657187158..f9127e7f36c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3718,8 +3718,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_dealloc_ucode(priv); - if (priv->rxq.bd) - iwlagn_rx_queue_free(priv, &priv->rxq); + priv->trans.ops->rx_free(priv); iwlagn_hw_txq_ctx_free(priv); iwl_eeprom_free(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 7273297a6f4..877a6944dec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -193,7 +193,6 @@ void iwlagn_rx_queue_restock(struct iwl_priv *priv); void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority); void iwlagn_rx_replenish(struct iwl_priv *priv); void iwlagn_rx_replenish_now(struct iwl_priv *priv); -void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); int iwlagn_rxq_stop(struct iwl_priv *priv); int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); void iwl_setup_rx_handlers(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7d3e55d0bc6..04b19a43139 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1233,9 +1233,11 @@ struct iwl_trans; * struct iwl_trans_ops - transport specific operations * @rx_init: inits the rx memory, allocate it if needed + *@rx_free: frees the rx memory */ struct iwl_trans_ops { int (*rx_init)(struct iwl_priv *priv); + void (*rx_free)(struct iwl_priv *priv); }; struct iwl_trans { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index ccf73ff6395..1f5834b8a63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -60,7 +60,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ - #include "iwl-dev.h" +#include "iwl-dev.h" #include "iwl-trans.h" static int iwl_trans_rx_alloc(struct iwl_priv *priv) @@ -78,12 +78,11 @@ static int iwl_trans_rx_alloc(struct iwl_priv *priv) return -EINVAL; /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ - /*Every descriptor is an __le32, hence its */ - rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, - GFP_KERNEL); + rxq->bd = dma_alloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, + &rxq->bd_dma, GFP_KERNEL); if (!rxq->bd) goto err_bd; - memset(rxq->bd, 0, 4 * RX_QUEUE_SIZE); + memset(rxq->bd, 0, sizeof(__le32) * RX_QUEUE_SIZE); /*Allocate the driver's pointer to receive buffer status */ rxq->rb_stts = dma_alloc_coherent(dev, sizeof(*rxq->rb_stts), @@ -95,28 +94,18 @@ static int iwl_trans_rx_alloc(struct iwl_priv *priv) return 0; err_rb_stts: - dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma); + dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, + rxq->bd, rxq->bd_dma); memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); rxq->bd = NULL; err_bd: return -ENOMEM; } -static int iwl_trans_rx_init(struct iwl_priv *priv) +static void iwl_trans_rxq_free_rx_bufs(struct iwl_priv *priv) { struct iwl_rx_queue *rxq = &priv->rxq; - int i, err; - unsigned long flags; - - if (!rxq->bd) { - err = iwl_trans_rx_alloc(priv); - if (err) - return err; - } - - spin_lock_irqsave(&rxq->lock, flags); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); + int i; /* Fill the rx_used queue with _all_ of the Rx buffers */ for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { @@ -131,6 +120,25 @@ static int iwl_trans_rx_init(struct iwl_priv *priv) } list_add_tail(&rxq->pool[i].list, &rxq->rx_used); } +} + +static int iwl_trans_rx_init(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + int i, err; + unsigned long flags; + + if (!rxq->bd) { + err = iwl_trans_rx_alloc(priv); + if (err) + return err; + } + + spin_lock_irqsave(&rxq->lock, flags); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + + iwl_trans_rxq_free_rx_bufs(priv); for (i = 0; i < RX_QUEUE_SIZE; i++) rxq->queue[i] = NULL; @@ -145,8 +153,40 @@ static int iwl_trans_rx_init(struct iwl_priv *priv) return 0; } +static void iwl_trans_rx_free(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + unsigned long flags; + + /*if rxq->bd is NULL, it means that nothing has been allocated, + * exit now */ + if (!rxq->bd) { + IWL_DEBUG_INFO(priv, "Free NULL rx context\n"); + return; + } + + spin_lock_irqsave(&rxq->lock, flags); + iwl_trans_rxq_free_rx_bufs(priv); + spin_unlock_irqrestore(&rxq->lock, flags); + + dma_free_coherent(priv->bus.dev, sizeof(__le32) * RX_QUEUE_SIZE, + rxq->bd, rxq->bd_dma); + memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); + rxq->bd = NULL; + + if (rxq->rb_stts) + dma_free_coherent(priv->bus.dev, + sizeof(struct iwl_rb_status), + rxq->rb_stts, rxq->rb_stts_dma); + else + IWL_DEBUG_INFO(priv, "Free rxq->rb_stts which is NULL\n"); + memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); + rxq->rb_stts = NULL; +} + static const struct iwl_trans_ops trans_ops = { .rx_init = iwl_trans_rx_init, + .rx_free = iwl_trans_rx_free, }; void iwl_trans_register(struct iwl_trans *trans) -- cgit v1.2.3-70-g09d2 From 02aca585f58a331288026cf78fd4f4ca404cbe12 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 28 Jun 2011 08:58:41 -0700 Subject: iwlagn: move the tx allocation funcs to the transport layer These functions allocate all the Tx context. Only the simple tx_init is exported as API. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 9 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 90 ------------ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 - drivers/net/wireless/iwlwifi/iwl-core.c | 14 -- drivers/net/wireless/iwlwifi/iwl-core.h | 7 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +- drivers/net/wireless/iwlwifi/iwl-trans.c | 228 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-tx.c | 139 +----------------- 8 files changed, 236 insertions(+), 257 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a2c5c6b6cd3..ea83aa5bf29 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -699,7 +699,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) { unsigned long flags; struct iwl_rx_queue *rxq = &priv->rxq; - int ret; /* nic_init */ spin_lock_irqsave(&priv->lock, flags); @@ -729,12 +728,8 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); /* Allocate or reset and init all Tx and Command queues */ - if (!priv->txq) { - ret = iwlagn_txq_ctx_alloc(priv); - if (ret) - return ret; - } else - iwlagn_txq_ctx_reset(priv); + if (priv->trans.ops->tx_init(priv)) + return -ENOMEM; if (priv->cfg->base_params->shadow_reg_enable) { /* enable shadow regs in HW */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index d0ac090399e..c05a8d9fbd2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -877,96 +877,6 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv) iwl_free_txq_mem(priv); } -/** - * iwlagn_txq_ctx_alloc - allocate TX queue context - * Allocate all Tx DMA structures and initialize them - * - * @param priv - * @return error code - */ -int iwlagn_txq_ctx_alloc(struct iwl_priv *priv) -{ - int ret; - int txq_id, slots_num; - unsigned long flags; - - /* Free all tx/cmd queues and keep-warm buffer */ - iwlagn_hw_txq_ctx_free(priv); - - ret = iwlagn_alloc_dma_ptr(priv, &priv->scd_bc_tbls, - priv->hw_params.scd_bc_tbls_size); - if (ret) { - IWL_ERR(priv, "Scheduler BC Table allocation failed\n"); - goto error_bc_tbls; - } - /* Alloc keep-warm buffer */ - ret = iwlagn_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE); - if (ret) { - IWL_ERR(priv, "Keep Warm allocation failed\n"); - goto error_kw; - } - - /* allocate tx queue structure */ - ret = iwl_alloc_txq_mem(priv); - if (ret) - goto error; - - spin_lock_irqsave(&priv->lock, flags); - - /* Turn off all Tx DMA fifos */ - iwlagn_txq_set_sched(priv, 0); - - /* Tell NIC where to find the "keep warm" buffer */ - iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == priv->cmd_queue) ? - TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, - txq_id); - if (ret) { - IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); - goto error; - } - } - - return ret; - - error: - iwlagn_hw_txq_ctx_free(priv); - iwlagn_free_dma_ptr(priv, &priv->kw); - error_kw: - iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls); - error_bc_tbls: - return ret; -} - -void iwlagn_txq_ctx_reset(struct iwl_priv *priv) -{ - int txq_id, slots_num; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - /* Turn off all Tx DMA fifos */ - iwlagn_txq_set_sched(priv, 0); - - /* Tell NIC where to find the "keep warm" buffer */ - iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Alloc and init all Tx queues, including the command queue (#4) */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = txq_id == priv->cmd_queue ? - TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); - } -} - /** * iwlagn_txq_ctx_stop - Stop all Tx DMA channels */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 877a6944dec..5d0c911a320 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -218,8 +218,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv); -int iwlagn_txq_ctx_alloc(struct iwl_priv *priv); -void iwlagn_txq_ctx_reset(struct iwl_priv *priv); void iwlagn_txq_ctx_stop(struct iwl_priv *priv); static inline u32 iwl_tx_status_to_mac80211(u32 status) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c5fa232b5eb..b63a7d60ebe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1372,20 +1372,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, } -int iwl_alloc_txq_mem(struct iwl_priv *priv) -{ - if (!priv->txq) - priv->txq = kzalloc( - sizeof(struct iwl_tx_queue) * - priv->cfg->base_params->num_of_queues, - GFP_KERNEL); - if (!priv->txq) { - IWL_ERR(priv, "Not enough memory for txq\n"); - return -ENOMEM; - } - return 0; -} - void iwl_free_txq_mem(struct iwl_priv *priv) { kfree(priv->txq); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 13d819b94ea..91e7279597c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -337,7 +337,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p); -int iwl_alloc_txq_mem(struct iwl_priv *priv); void iwl_free_txq_mem(struct iwl_priv *priv); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -396,11 +395,9 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); * TX ******************************************************/ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); -int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, - int slots_num, u32 txq_id); -void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, - int slots_num, u32 txq_id); void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); +int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, + int count, int slots_num, u32 id); void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id); void iwl_setup_watchdog(struct iwl_priv *priv); /***************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 04b19a43139..4d17619dd29 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1233,11 +1233,13 @@ struct iwl_trans; * struct iwl_trans_ops - transport specific operations * @rx_init: inits the rx memory, allocate it if needed - *@rx_free: frees the rx memory + * @rx_free: frees the rx memory + * @tx_init:inits the tx memory, allocate if needed */ struct iwl_trans_ops { int (*rx_init)(struct iwl_priv *priv); void (*rx_free)(struct iwl_priv *priv); + int (*tx_init)(struct iwl_priv *priv); }; struct iwl_trans { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 1f5834b8a63..7b7b97d8c2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -62,6 +62,10 @@ *****************************************************************************/ #include "iwl-dev.h" #include "iwl-trans.h" +#include "iwl-core.h" +#include "iwl-helpers.h" +/*TODO remove uneeded includes when the transport layer tx_free will be here */ +#include "iwl-agn.h" static int iwl_trans_rx_alloc(struct iwl_priv *priv) { @@ -184,9 +188,233 @@ static void iwl_trans_rx_free(struct iwl_priv *priv) rxq->rb_stts = NULL; } +/* TODO:remove this code duplication */ +static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, + struct iwl_dma_ptr *ptr, size_t size) +{ + if (WARN_ON(ptr->addr)) + return -EINVAL; + + ptr->addr = dma_alloc_coherent(priv->bus.dev, size, + &ptr->dma, GFP_KERNEL); + if (!ptr->addr) + return -ENOMEM; + ptr->size = size; + return 0; +} + +static int iwl_trans_txq_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id) +{ + size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; + int i; + + if (WARN_ON(txq->meta || txq->cmd || txq->txb || txq->tfds)) + return -EINVAL; + + txq->meta = kzalloc(sizeof(txq->meta[0]) * slots_num, + GFP_KERNEL); + txq->cmd = kzalloc(sizeof(txq->cmd[0]) * slots_num, + GFP_KERNEL); + + if (!txq->meta || !txq->cmd) + goto error; + + for (i = 0; i < slots_num; i++) { + txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), + GFP_KERNEL); + if (!txq->cmd[i]) + goto error; + } + + /* Alloc driver data array and TFD circular buffer */ + /* Driver private data, only for Tx (not command) queues, + * not shared with device. */ + if (txq_id != priv->cmd_queue) { + txq->txb = kzalloc(sizeof(txq->txb[0]) * + TFD_QUEUE_SIZE_MAX, GFP_KERNEL); + if (!txq->txb) { + IWL_ERR(priv, "kmalloc for auxiliary BD " + "structures failed\n"); + goto error; + } + } else { + txq->txb = NULL; + } + + /* Circular buffer of transmit frame descriptors (TFDs), + * shared with device */ + txq->tfds = dma_alloc_coherent(priv->bus.dev, tfd_sz, &txq->q.dma_addr, + GFP_KERNEL); + if (!txq->tfds) { + IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz); + goto error; + } + txq->q.id = txq_id; + + return 0; +error: + kfree(txq->txb); + txq->txb = NULL; + /* since txq->cmd has been zeroed, + * all non allocated cmd[i] will be NULL */ + if (txq->cmd) + for (i = 0; i < slots_num; i++) + kfree(txq->cmd[i]); + kfree(txq->meta); + kfree(txq->cmd); + txq->meta = NULL; + txq->cmd = NULL; + + return -ENOMEM; + +} + +static int iwl_trans_txq_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id) +{ + int ret; + + txq->need_update = 0; + memset(txq->meta, 0, sizeof(txq->meta[0]) * slots_num); + + /* + * For the default queues 0-3, set up the swq_id + * already -- all others need to get one later + * (if they need one at all). + */ + if (txq_id < 4) + iwl_set_swq_id(txq, txq_id, txq_id); + + /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise + * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ + BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); + + /* Initialize queue's high/low-water marks, and head/tail indexes */ + ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, + txq_id); + if (ret) + return ret; + + /* + * Tell nic where to find circular buffer of Tx Frame Descriptors for + * given Tx queue, and enable the DMA channel used for that queue. + * Circular buffer (TFD queue in DRAM) physical base address */ + iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), + txq->q.dma_addr >> 8); + + return 0; +} + +/** + * iwl_trans_tx_alloc - allocate TX context + * Allocate all Tx DMA structures and initialize them + * + * @param priv + * @return error code + */ +static int iwl_trans_tx_alloc(struct iwl_priv *priv) +{ + int ret; + int txq_id, slots_num; + + /*It is not allowed to alloc twice, so warn when this happens. + * We cannot rely on the previous allocation, so free and fail */ + if (WARN_ON(priv->txq)) { + ret = -EINVAL; + goto error; + } + + ret = iwlagn_alloc_dma_ptr(priv, &priv->scd_bc_tbls, + priv->hw_params.scd_bc_tbls_size); + if (ret) { + IWL_ERR(priv, "Scheduler BC Table allocation failed\n"); + goto error; + } + + /* Alloc keep-warm buffer */ + ret = iwlagn_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE); + if (ret) { + IWL_ERR(priv, "Keep Warm allocation failed\n"); + goto error; + } + + priv->txq = kzalloc(sizeof(struct iwl_tx_queue) * + priv->cfg->base_params->num_of_queues, GFP_KERNEL); + if (!priv->txq) { + IWL_ERR(priv, "Not enough memory for txq\n"); + ret = ENOMEM; + goto error; + } + + /* Alloc and init all Tx queues, including the command queue (#4/#9) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = (txq_id == priv->cmd_queue) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + ret = iwl_trans_txq_alloc(priv, &priv->txq[txq_id], slots_num, + txq_id); + if (ret) { + IWL_ERR(priv, "Tx %d queue alloc failed\n", txq_id); + goto error; + } + } + + return 0; + +error: + iwlagn_hw_txq_ctx_free(priv); + + return ret; +} +static int iwl_trans_tx_init(struct iwl_priv *priv) +{ + int ret; + int txq_id, slots_num; + unsigned long flags; + bool alloc = false; + + if (!priv->txq) { + ret = iwl_trans_tx_alloc(priv); + if (ret) + goto error; + alloc = true; + } + + spin_lock_irqsave(&priv->lock, flags); + + /* Turn off all Tx DMA fifos */ + iwl_write_prph(priv, IWLAGN_SCD_TXFACT, 0); + + /* Tell NIC where to find the "keep warm" buffer */ + iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Alloc and init all Tx queues, including the command queue (#4/#9) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = (txq_id == priv->cmd_queue) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + ret = iwl_trans_txq_init(priv, &priv->txq[txq_id], slots_num, + txq_id); + if (ret) { + IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); + goto error; + } + } + + return 0; +error: + /*Upon error, free only if we allocated something */ + if (alloc) + iwlagn_hw_txq_ctx_free(priv); + return ret; +} + static const struct iwl_trans_ops trans_ops = { .rx_init = iwl_trans_rx_init, .rx_free = iwl_trans_rx_free, + + .tx_init = iwl_trans_tx_init, }; void iwl_trans_register(struct iwl_trans *trans) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index e72d2279fc5..db5abaa2ff7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -220,24 +220,6 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, return 0; } -/* - * Tell nic where to find circular buffer of Tx Frame Descriptors for - * given Tx queue, and enable the DMA channel used for that queue. - * - * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA - * channels supported in hardware. - */ -static int iwlagn_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) -{ - int txq_id = txq->q.id; - - /* Circular buffer (TFD queue in DRAM) physical base address */ - iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), - txq->q.dma_addr >> 8); - - return 0; -} - /** * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's */ @@ -392,11 +374,10 @@ int iwl_queue_space(const struct iwl_queue *q) return s; } - /** * iwl_queue_init - Initialize queue's high/low-water and read/write indexes */ -static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, +int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, int count, int slots_num, u32 id) { q->n_bd = count; @@ -426,124 +407,6 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, return 0; } -/** - * iwl_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue - */ -static int iwl_tx_queue_alloc(struct iwl_priv *priv, - struct iwl_tx_queue *txq, u32 id) -{ - struct device *dev = priv->bus.dev; - size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; - - /* Driver private data, only for Tx (not command) queues, - * not shared with device. */ - if (id != priv->cmd_queue) { - txq->txb = kzalloc(sizeof(txq->txb[0]) * - TFD_QUEUE_SIZE_MAX, GFP_KERNEL); - if (!txq->txb) { - IWL_ERR(priv, "kmalloc for auxiliary BD " - "structures failed\n"); - goto error; - } - } else { - txq->txb = NULL; - } - - /* Circular buffer of transmit frame descriptors (TFDs), - * shared with device */ - txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, - GFP_KERNEL); - if (!txq->tfds) { - IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz); - goto error; - } - txq->q.id = id; - - return 0; - - error: - kfree(txq->txb); - txq->txb = NULL; - - return -ENOMEM; -} - -/** - * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue - */ -int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, - int slots_num, u32 txq_id) -{ - int i, len; - int ret; - - txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * slots_num, - GFP_KERNEL); - txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * slots_num, - GFP_KERNEL); - - if (!txq->meta || !txq->cmd) - goto out_free_arrays; - - len = sizeof(struct iwl_device_cmd); - for (i = 0; i < slots_num; i++) { - txq->cmd[i] = kmalloc(len, GFP_KERNEL); - if (!txq->cmd[i]) - goto err; - } - - /* Alloc driver data array and TFD circular buffer */ - ret = iwl_tx_queue_alloc(priv, txq, txq_id); - if (ret) - goto err; - - txq->need_update = 0; - - /* - * For the default queues 0-3, set up the swq_id - * already -- all others need to get one later - * (if they need one at all). - */ - if (txq_id < 4) - iwl_set_swq_id(txq, txq_id, txq_id); - - /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise - * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ - BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); - - /* Initialize queue's high/low-water marks, and head/tail indexes */ - ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); - if (ret) - return ret; - - /* Tell device where to find queue */ - iwlagn_tx_queue_init(priv, txq); - - return 0; -err: - for (i = 0; i < slots_num; i++) - kfree(txq->cmd[i]); -out_free_arrays: - kfree(txq->meta); - kfree(txq->cmd); - - return -ENOMEM; -} - -void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, - int slots_num, u32 txq_id) -{ - memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * slots_num); - - txq->need_update = 0; - - /* Initialize queue's high/low-water marks, and head/tail indexes */ - iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); - - /* Tell device where to find queue */ - iwlagn_tx_queue_init(priv, txq); -} - /*************** HOST COMMAND QUEUE FUNCTIONS *****/ /** -- cgit v1.2.3-70-g09d2 From f86af7ba82e3449e6ee957e0407cb6c683fa37db Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 28 Jun 2011 08:01:12 -0700 Subject: iwlagn: scd memory boundary Assign memory boundary for SCD context, tx status and translation table Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 8 +++++--- drivers/net/wireless/iwlwifi/iwl-prph.h | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index de8277e3225..2043c8b3139 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -386,11 +386,13 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR); - a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_DATA_OFFSET; - for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_BITMAP_OFFSET; + a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND; + /* reset conext data memory */ + for (; a < priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND; a += 4) iwl_write_targ_mem(priv, a, 0); - for (; a < priv->scd_base_addr + IWLAGN_SCD_TRANSLATE_TBL_OFFSET; + /* reset tx status memory */ + for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND; a += 4) iwl_write_targ_mem(priv, a, 0); for (; a < priv->scd_base_addr + diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index f00d188b2cf..1cc0ed1f488 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -168,6 +168,7 @@ * the scheduler (especially for queue #4/#9, the command queue, otherwise * the driver can't issue commands!): */ +#define SCD_MEM_LOWER_BOUND (0x0000) /** * Max Tx window size is the max number of contiguous TFDs that the scheduler @@ -197,15 +198,23 @@ #define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) #define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) -#define IWLAGN_SCD_CONTEXT_DATA_OFFSET (0x600) -#define IWLAGN_SCD_TX_STTS_BITMAP_OFFSET (0x7B1) -#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET (0x7E0) +/* Context Data */ +#define IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600) +#define IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0) + +/* Tx status */ +#define IWLAGN_SCD_TX_STTS_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0) +#define IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0) + +/* Translation Data */ +#define IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0) +#define IWLAGN_SCD_TRANS_TBL_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x808) #define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\ - (IWLAGN_SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) + (IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8)) #define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ - ((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc) + ((IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) #define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv) \ (((1<<(priv)->hw_params.max_txq_num) - 1) &\ -- cgit v1.2.3-70-g09d2 From e55b517c4d853a5168ebb4cdd58933b17c593827 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 28 Jun 2011 11:46:28 -0700 Subject: iwlagn: call bt_coex directlly Call the 2-wire and advanced bt-coex function directly to avoid mistake Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f9127e7f36c..ffb0b192270 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -260,7 +260,7 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work) /* dont send host command if rf-kill is on */ if (!iwl_is_ready_rf(priv)) return; - priv->cfg->ops->hcmd->send_bt_config(priv); + iwlagn_send_advance_bt_config(priv); } static void iwl_bg_bt_full_concurrency(struct work_struct *work) @@ -292,7 +292,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) iwlagn_commit_rxon(priv, ctx); } - priv->cfg->ops->hcmd->send_bt_config(priv); + iwlagn_send_advance_bt_config(priv); out: mutex_unlock(&priv->mutex); } @@ -2017,7 +2017,7 @@ int iwl_alive_start(struct iwl_priv *priv) priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; - priv->cfg->ops->hcmd->send_bt_config(priv); + iwlagn_send_advance_bt_config(priv); priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; iwlagn_send_prio_tbl(priv); @@ -2030,7 +2030,13 @@ int iwl_alive_start(struct iwl_priv *priv) BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; + } else { + /* + * default is 2-wire BT coexexistence support + */ + iwl_send_bt_config(priv); } + if (priv->hw_params.calib_rt_cfg) iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); @@ -2058,14 +2064,6 @@ int iwl_alive_start(struct iwl_priv *priv) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } - if (!priv->cfg->bt_params || (priv->cfg->bt_params && - !priv->cfg->bt_params->advanced_bt_coexist)) { - /* - * default is 2-wire BT coexexistence support - */ - priv->cfg->ops->hcmd->send_bt_config(priv); - } - iwl_reset_run_time_calib(priv); set_bit(STATUS_READY, &priv->status); -- cgit v1.2.3-70-g09d2 From e3f10cea039b235c1de12648ea87b752990c11bf Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Jul 2011 07:59:26 -0700 Subject: iwlagn: remove hcmd ops All "agn" devices use the same hcmd functions, no need to call indirectly. remove hcmd_ops Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 16 +--------------- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 11 ++++------- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 19 +++++++------------ drivers/net/wireless/iwlwifi/iwl-agn.c | 23 ++++++++--------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-core.h | 9 --------- 11 files changed, 23 insertions(+), 73 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e57fad9f1f0..8c5a829c411 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -197,7 +197,6 @@ static struct iwl_lib_ops iwl1000_lib = { static const struct iwl_ops iwl1000_ops = { .lib = &iwl1000_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 76a3e42a4ff..75d63e6ee7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -198,25 +198,21 @@ static struct iwl_lib_ops iwl2000_lib = { static const struct iwl_ops iwl2000_ops = { .lib = &iwl2000_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl2030_ops = { .lib = &iwl2000_lib, - .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl105_ops = { .lib = &iwl2000_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl135_ops = { .lib = &iwl2000_lib, - .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 269dfdb9fe1..5ebf5d225b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -379,13 +379,11 @@ static struct iwl_lib_ops iwl5150_lib = { static const struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl5150_ops = { .lib = &iwl5150_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f1c1db76b9d..94ad57cf3ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -328,27 +328,23 @@ static struct iwl_nic_ops iwl6150_nic_ops = { static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl6050_ops = { .lib = &iwl6000_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .nic = &iwl6050_nic_ops, }; static const struct iwl_ops iwl6150_ops = { .lib = &iwl6000_lib, - .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .nic = &iwl6150_nic_ops, }; static const struct iwl_ops iwl6030_ops = { .lib = &iwl6030_lib, - .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index ba7ed9157c9..ce7d4b56d9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -205,7 +205,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, return max_rssi - agc - IWLAGN_RSSI_OFFSET; } -static int iwlagn_set_pan_params(struct iwl_priv *priv) +int iwlagn_set_pan_params(struct iwl_priv *priv) { struct iwl_wipan_params_cmd cmd; struct iwl_rxon_context *ctx_bss, *ctx_pan; @@ -297,20 +297,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) return ret; } -struct iwl_hcmd_ops iwlagn_hcmd = { - .set_rxon_chain = iwlagn_set_rxon_chain, - .set_tx_ant = iwlagn_send_tx_ant_config, - .send_bt_config = iwl_send_bt_config, - .set_pan_params = iwlagn_set_pan_params, -}; - -struct iwl_hcmd_ops iwlagn_bt_hcmd = { - .set_rxon_chain = iwlagn_set_rxon_chain, - .set_tx_ant = iwlagn_send_tx_ant_config, - .send_bt_config = iwlagn_send_advance_bt_config, - .set_pan_params = iwlagn_set_pan_params, -}; - struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { .build_addsta_hcmd = iwlagn_build_addsta_hcmd, .gain_computation = iwlagn_gain_computation, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index ea83aa5bf29..90d366e15d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1366,17 +1366,14 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) /* set scan bit here for PAN params */ set_bit(STATUS_SCAN_HW, &priv->status); - if (priv->cfg->ops->hcmd->set_pan_params) { - ret = priv->cfg->ops->hcmd->set_pan_params(priv); - if (ret) - return ret; - } + ret = iwlagn_set_pan_params(priv); + if (ret) + return ret; ret = iwl_send_cmd_sync(priv, &cmd); if (ret) { clear_bit(STATUS_SCAN_HW, &priv->status); - if (priv->cfg->ops->hcmd->set_pan_params) - priv->cfg->ops->hcmd->set_pan_params(priv); + iwlagn_set_pan_params(priv); } return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 8fa43d42781..c6bb73a66d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -436,11 +436,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (ret) return ret; - if (priv->cfg->ops->hcmd->set_pan_params) { - ret = priv->cfg->ops->hcmd->set_pan_params(priv); - if (ret) - return ret; - } + ret = iwlagn_set_pan_params(priv); + if (ret) + return ret; if (new_assoc) return iwlagn_rxon_connect(priv, ctx); @@ -483,9 +481,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) * set up the SM PS mode to OFF if an HT channel is * configured. */ - if (priv->cfg->ops->hcmd->set_rxon_chain) - for_each_context(priv, ctx) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + for_each_context(priv, ctx) + iwlagn_set_rxon_chain(priv, ctx); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { @@ -741,8 +738,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, iwl_set_rxon_ht(priv, &priv->current_ht_config); } - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlagn_set_rxon_chain(priv, ctx); if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; @@ -821,6 +817,5 @@ void iwlagn_post_scan(struct iwl_priv *priv) if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) iwlagn_commit_rxon(priv, ctx); - if (priv->cfg->ops->hcmd->set_pan_params) - priv->cfg->ops->hcmd->set_pan_params(priv); + iwlagn_set_pan_params(priv); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ffb0b192270..7e6c463abbd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -90,12 +90,10 @@ void iwl_update_chain_flags(struct iwl_priv *priv) { struct iwl_rxon_context *ctx; - if (priv->cfg->ops->hcmd->set_rxon_chain) { - for_each_context(priv, ctx) { - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - if (ctx->active.rx_chain != ctx->staging.rx_chain) - iwlagn_commit_rxon(priv, ctx); - } + for_each_context(priv, ctx) { + iwlagn_set_rxon_chain(priv, ctx); + if (ctx->active.rx_chain != ctx->staging.rx_chain) + iwlagn_commit_rxon(priv, ctx); } } @@ -287,8 +285,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) * to avoid 3-wire collisions */ for_each_context(priv, ctx) { - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlagn_set_rxon_chain(priv, ctx); iwlagn_commit_rxon(priv, ctx); } @@ -2045,8 +2042,7 @@ int iwl_alive_start(struct iwl_priv *priv) priv->active_rate = IWL_RATES_MASK; /* Configure Tx antenna selection based on H/W config */ - if (priv->cfg->ops->hcmd->set_tx_ant) - priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant); + iwlagn_send_tx_ant_config(priv, priv->cfg->valid_tx_ant); if (iwl_is_associated_ctx(ctx)) { struct iwl_rxon_cmd *active_rxon = @@ -2060,8 +2056,7 @@ int iwl_alive_start(struct iwl_priv *priv) for_each_context(priv, tmp) iwl_connection_init_rx_config(priv, tmp); - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlagn_set_rxon_chain(priv, ctx); } iwl_reset_run_time_calib(priv); @@ -3286,9 +3281,7 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->rx_statistics_jiffies = jiffies; /* Choose which receivers/antennas to use */ - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); + iwlagn_set_rxon_chain(priv, &priv->contexts[IWL_RXON_CTX_BSS]); iwl_init_scan_params(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5d0c911a320..4351151e2a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -256,6 +256,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, /* hcmd */ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); int iwlagn_send_beacon_cmd(struct iwl_priv *priv); +int iwlagn_set_pan_params(struct iwl_priv *priv); /* bt coex */ void iwlagn_send_advance_bt_config(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b63a7d60ebe..f91e306c249 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -585,8 +585,7 @@ static void _iwl_set_rxon_ht(struct iwl_priv *priv, rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; } - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlagn_set_rxon_chain(priv, ctx); IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", @@ -1216,8 +1215,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { iwl_connection_init_rx_config(priv, ctx); - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlagn_set_rxon_chain(priv, ctx); return iwlagn_commit_rxon(priv, ctx); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 91e7279597c..6c21de9f5b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -80,14 +80,6 @@ struct iwl_cmd; #define IWL_CMD(x) case x: return #x -struct iwl_hcmd_ops { - void (*set_rxon_chain)(struct iwl_priv *priv, - struct iwl_rxon_context *ctx); - int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); - void (*send_bt_config)(struct iwl_priv *priv); - int (*set_pan_params)(struct iwl_priv *priv); -}; - struct iwl_hcmd_utils_ops { u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); void (*gain_computation)(struct iwl_priv *priv, @@ -146,7 +138,6 @@ struct iwl_nic_ops { struct iwl_ops { const struct iwl_lib_ops *lib; - const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; const struct iwl_nic_ops *nic; }; -- cgit v1.2.3-70-g09d2 From 252e735d64880b011f6cdeb41ebcac2eaeb58fd3 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 28 Jun 2011 13:13:59 -0700 Subject: iwlagn: remove the indirection for the rx write pointer Not needed since the driver split. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-rx.c | 7 +++---- 6 files changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 8c5a829c411..cf1449df4f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -138,7 +138,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); if (priv->cfg->rx_with_siso_diversity) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 75d63e6ee7f..a401113c065 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -136,7 +136,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); if (priv->cfg->rx_with_siso_diversity) diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 5ebf5d225b8..c55cec853f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -169,7 +169,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); @@ -214,7 +213,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 94ad57cf3ea..965d010794b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -157,7 +157,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); if (priv->cfg->rx_with_siso_diversity) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4d17619dd29..f4501f83615 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -665,7 +665,6 @@ struct iwl_hw_params { u16 max_rxq_size; u16 max_rxq_log; u32 rx_page_order; - u32 rx_wrt_ptr_reg; u8 max_stations; u8 ht40_channel; u8 max_beacon_itrvl; /* in 1024 ms */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 065d2c02655..87148bb3f62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -134,7 +134,6 @@ int iwl_rx_queue_space(const struct iwl_rx_queue *q) void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) { unsigned long flags; - u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg; u32 reg; spin_lock_irqsave(&q->lock, flags); @@ -146,7 +145,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q /* shadow register enabled */ /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual); + iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual); } else { /* If power-saving is in use, make sure device is awake */ if (test_bit(STATUS_POWER_PMI, &priv->status)) { @@ -162,14 +161,14 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q } q->write_actual = (q->write & ~0x7); - iwl_write_direct32(priv, rx_wrt_ptr_reg, + iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual); /* Else device is assumed to be awake */ } else { /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write_direct32(priv, rx_wrt_ptr_reg, + iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual); } } -- cgit v1.2.3-70-g09d2 From 31fcb99d9958bdf04e84224e202f69e6cdac893b Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 30 Jun 2011 22:52:13 +0000 Subject: net: sh_eth: remove __flush_purge_region It is a function of SuperH architecture. There is no good to use the function on a driver generally. So, the driver uses dma_map_single() instead of __flush_purge_region. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 96a629f1678..3da168a859c 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "sh_eth.h" @@ -864,6 +863,8 @@ static int sh_eth_txfree(struct net_device *ndev) break; /* Free the original skb. */ if (mdp->tx_skbuff[entry]) { + dma_unmap_single(&ndev->dev, txdesc->addr, + txdesc->buffer_length, DMA_TO_DEVICE); dev_kfree_skb_irq(mdp->tx_skbuff[entry]); mdp->tx_skbuff[entry] = NULL; freeNum++; @@ -1487,13 +1488,12 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) entry = mdp->cur_tx % TX_RING_SIZE; mdp->tx_skbuff[entry] = skb; txdesc = &mdp->tx_ring[entry]; - txdesc->addr = virt_to_phys(skb->data); /* soft swap. */ if (!mdp->cd->hw_swap) sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)), skb->len + 2); - /* write back */ - __flush_purge_region(skb->data, skb->len); + txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, + DMA_TO_DEVICE); if (skb->len < ETHERSMALL) txdesc->buffer_length = ETHERSMALL; else -- cgit v1.2.3-70-g09d2 From 4924f44b97a034dbf44c14b709b0b0907ee23f04 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Jul 2011 17:57:10 -0700 Subject: b44: use dev_kfree_skb() in b44_tx() b44_tx() is run from softirq handler, it can use dev_kfree_skb() instead of dev_kfree_skb_irq() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/b44.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index cced4fd31fe..98c977ed9ad 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -610,7 +610,7 @@ static void b44_tx(struct b44 *bp) skb->len, DMA_TO_DEVICE); rp->skb = NULL; - dev_kfree_skb_irq(skb); + dev_kfree_skb(skb); } bp->tx_cons = cons; -- cgit v1.2.3-70-g09d2 From 3e714ad3c2a07ee120044b72222cc20c14959efb Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:47:04 +0000 Subject: net: e1000e: Use is_multicast_ether_addr helper Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/e1000e/lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index bd72b8167df..65580b40594 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -220,7 +220,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) } /* if multicast bit is set, the alternate address will not be used */ - if (alt_mac_addr[0] & 0x01) { + if (is_multicast_ether_addr(alt_mac_addr)) { e_dbg("Ignoring Alternate Mac Address with MC bit set\n"); goto out; } -- cgit v1.2.3-70-g09d2 From 29a40f0676c9388a83396306957f11b359c4be1c Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:48:13 +0000 Subject: net: de4x5: Use helpers from linux/etherdevice.h Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/tulip/de4x5.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index d8db2b664ac..959b41021a6 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1868,14 +1868,13 @@ de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len) i = DE4X5_PKT_STAT_SZ; } } - if (buf[0] & 0x01) { /* Multicast/Broadcast */ - if ((*(s32 *)&buf[0] == -1) && (*(s16 *)&buf[4] == -1)) { + if (is_multicast_ether_addr(buf)) { + if (is_broadcast_ether_addr(buf)) { lp->pktStats.broadcast++; } else { lp->pktStats.multicast++; } - } else if ((*(s32 *)&buf[0] == *(s32 *)&dev->dev_addr[0]) && - (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) { + } else if (compare_ether_addr(buf, dev->dev_addr) == 0) { lp->pktStats.unicast++; } -- cgit v1.2.3-70-g09d2 From 58d14d4fbaeb0cede14c59e8a2648b4791c0afe2 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:50:15 +0000 Subject: net: igb: Use is_multicast_ether_addr helper Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/igb/e1000_mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index ce8255fc3c5..c822904d8a0 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "e1000_mac.h" @@ -217,7 +218,7 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw) } /* if multicast bit is set, the alternate address will not be used */ - if (alt_mac_addr[0] & 0x01) { + if (is_multicast_ether_addr(alt_mac_addr)) { hw_dbg("Ignoring Alternate Mac Address with MC bit set\n"); goto out; } -- cgit v1.2.3-70-g09d2 From 8bc3e1d8a16e6ef501af1c4d3abd7a90b4db1c0f Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:52:03 +0000 Subject: net: iseries_veth: Use is_unicast_ether_addr helper Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/iseries_veth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 242bf524273..53dd39e9130 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1182,7 +1182,7 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev) struct veth_port *port = netdev_priv(dev); HvLpIndexMap lpmask; - if (! (frame[0] & 0x01)) { + if (is_unicast_ether_addr(frame)) { /* unicast packet */ HvLpIndex rlp = frame[5]; -- cgit v1.2.3-70-g09d2 From abfc89c7b5347b869d1c48ddae027caf91a2300d Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:54:54 +0000 Subject: net: rionet: Use is_multicast_ether_addr Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/rionet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 77c5092a6a4..bcdc54f2fe5 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -190,7 +190,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_BUSY; } - if (eth->h_dest[0] & 0x01) { + if (is_multicast_ether_addr(eth->h_dest)) { for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size); i++) if (rionet_active[i]) -- cgit v1.2.3-70-g09d2 From 2effca33194749cc3d5c2fdae52dcd8a7d6556e5 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:55:53 +0000 Subject: net: depca: Use helpers from linux/etherdevice.h Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/depca.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/depca.c b/drivers/net/depca.c index a7ccaa67c7d..f2015a85197 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -1073,13 +1073,13 @@ static int depca_rx(struct net_device *dev) i = DEPCA_PKT_STAT_SZ; } } - if (buf[0] & 0x01) { /* Multicast/Broadcast */ - if ((*(s16 *) & buf[0] == -1) && (*(s16 *) & buf[2] == -1) && (*(s16 *) & buf[4] == -1)) { + if (is_multicast_ether_addr(buf)) { + if (is_broadcast_ether_addr(buf)) { lp->pktStats.broadcast++; } else { lp->pktStats.multicast++; } - } else if ((*(s16 *) & buf[0] == *(s16 *) & dev->dev_addr[0]) && (*(s16 *) & buf[2] == *(s16 *) & dev->dev_addr[2]) && (*(s16 *) & buf[4] == *(s16 *) & dev->dev_addr[4])) { + } else if (compare_ether_addr(buf, dev->dev_addr) == 0) { lp->pktStats.unicast++; } -- cgit v1.2.3-70-g09d2 From d8ce2fc1adc38fb8c71bbf44b87a982bbee5cda0 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:56:22 +0000 Subject: net: ewrk3: Use helpers from linux/etherdevice.h Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/ewrk3.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index b5f6173130f..d1e229f9e54 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -1008,15 +1008,13 @@ static int ewrk3_rx(struct net_device *dev) } } p = skb->data; /* Look at the dest addr */ - if (p[0] & 0x01) { /* Multicast/Broadcast */ - if ((*(s16 *) & p[0] == -1) && (*(s16 *) & p[2] == -1) && (*(s16 *) & p[4] == -1)) { + if (is_multicast_ether_addr(p)) { + if (is_broadcast_ether_addr(p)) { lp->pktStats.broadcast++; } else { lp->pktStats.multicast++; } - } else if ((*(s16 *) & p[0] == *(s16 *) & dev->dev_addr[0]) && - (*(s16 *) & p[2] == *(s16 *) & dev->dev_addr[2]) && - (*(s16 *) & p[4] == *(s16 *) & dev->dev_addr[4])) { + } else if (compare_ether_addr(p, dev->dev_addr) == 0) { lp->pktStats.unicast++; } lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */ -- cgit v1.2.3-70-g09d2 From f8d4aa29762fe1ae78ec3164f8f612f7b06d58ea Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 3 Jul 2011 23:58:04 +0000 Subject: net: vxge: Use is_multicast_ether_addr helper Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 1c92af39299..15d878b4547 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -684,8 +684,7 @@ static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac) new_mac_entry->state = mac->state; vpath->mac_addr_cnt++; - /* Is this a multicast address */ - if (0x01 & mac->macaddr[0]) + if (is_multicast_ether_addr(mac->macaddr)) vpath->mcast_addr_cnt++; return TRUE; @@ -699,7 +698,7 @@ vxge_add_mac_addr(struct vxgedev *vdev, struct macInfo *mac) struct vxge_vpath *vpath; enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode; - if (0x01 & mac->macaddr[0]) /* multicast address */ + if (is_multicast_ether_addr(mac->macaddr)) duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE; else duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE; @@ -1078,8 +1077,7 @@ static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac) kfree((struct vxge_mac_addrs *)entry); vpath->mac_addr_cnt--; - /* Is this a multicast address */ - if (0x01 & mac->macaddr[0]) + if (is_multicast_ether_addr(mac->macaddr)) vpath->mcast_addr_cnt--; return TRUE; } @@ -1201,8 +1199,7 @@ static void vxge_set_multicast(struct net_device *dev) mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); - /* Is this a multicast address */ - if (0x01 & mac_info.macaddr[0]) { + if (is_multicast_ether_addr(mac_info.macaddr)) { for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) { @@ -1244,8 +1241,7 @@ _set_all_mcast: mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); - /* Is this a multicast address */ - if (0x01 & mac_info.macaddr[0]) + if (is_multicast_ether_addr(mac_info.macaddr)) break; } -- cgit v1.2.3-70-g09d2 From d4d2d288972233fc054f3b3341c2a15865fba7c6 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 4 Jul 2011 00:00:22 +0000 Subject: net/wireless: ipw2x00: Use helpers from linux/etherdevice.h Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/wireless/ipw2x00/libipw_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index e5ad76cd77d..32a9966c3bf 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -442,7 +442,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, * 802.11, but makes it easier to use different keys with * stations that do not support WEP key mapping). */ - if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key) + if (is_unicast_ether_addr(hdr->addr1) || local->bcrx_sta_key) (void)hostap_handle_sta_crypto(local, hdr, &crypt, &sta); #endif @@ -772,7 +772,7 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, #ifdef NOT_YET if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) { - if (dst[0] & 0x01) { + if (is_multicast_ether_addr(dst)) { /* copy multicast frame both to the higher layers and * to the wireless media */ ieee->ap->bridged_multicast++; -- cgit v1.2.3-70-g09d2 From b8d6d0824d064ad447e6aacbce90f3a340d93d65 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:06:27 +0000 Subject: bnx2x: PFC fixes Set the source MAC address for PFC packets and update its status during PMF migration. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 2 + drivers/net/bnx2x/bnx2x_link.c | 87 ++++++++++++++++++++++++------------------ drivers/net/bnx2x/bnx2x_reg.h | 12 ++++++ 3 files changed, 64 insertions(+), 37 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index df5355818c3..d6a7aa95d96 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -1196,6 +1196,8 @@ struct drv_port_mb { #define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 #define LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE 0x10000000 + #define LINK_STATUS_PFC_ENABLED 0x20000000 + u32 port_stx; u32 stat_nig_timer; diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 836363645da..57ba8110aa5 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1344,28 +1344,21 @@ static void bnx2x_update_pfc_xmac(struct link_params *params, REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val); REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val); - udelay(30); -} + /* Set MAC address for source TX Pause/PFC frames */ + REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO, + ((params->mac_addr[2] << 24) | + (params->mac_addr[3] << 16) | + (params->mac_addr[4] << 8) | + (params->mac_addr[5]))); + REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI, + ((params->mac_addr[0] << 8) | + (params->mac_addr[1]))); -static void bnx2x_bmac2_get_pfc_stat(struct link_params *params, - u32 pfc_frames_sent[2], - u32 pfc_frames_received[2]) -{ - /* Read pfc statistic */ - struct bnx2x *bp = params->bp; - u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : - NIG_REG_INGRESS_BMAC0_MEM; - - DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n"); - - REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP, - pfc_frames_sent, 2); + udelay(30); +} - REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP, - pfc_frames_received, 2); -} static void bnx2x_emac_get_pfc_stat(struct link_params *params, u32 pfc_frames_sent[2], u32 pfc_frames_received[2]) @@ -1397,28 +1390,23 @@ static void bnx2x_emac_get_pfc_stat(struct link_params *params, pfc_frames_sent[0] = val_xon + val_xoff; } +/* Read pfc statistic*/ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, u32 pfc_frames_sent[2], u32 pfc_frames_received[2]) { /* Read pfc statistic */ struct bnx2x *bp = params->bp; - u32 val = 0; + DP(NETIF_MSG_LINK, "pfc statistic\n"); if (!vars->link_up) return; - val = REG_RD(bp, MISC_REG_RESET_REG_2); - if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) - == 0) { - DP(NETIF_MSG_LINK, "About to read stats from EMAC\n"); + if (MAC_TYPE_EMAC == vars->mac_type) { + DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n"); bnx2x_emac_get_pfc_stat(params, pfc_frames_sent, pfc_frames_received); - } else { - DP(NETIF_MSG_LINK, "About to read stats from BMAC\n"); - bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent, - pfc_frames_received); } } /******************************************************************/ @@ -1561,6 +1549,16 @@ static void bnx2x_umac_enable(struct link_params *params, REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); udelay(50); + /* Set MAC address for source TX Pause/PFC frames (under SW reset) */ + REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0, + ((params->mac_addr[2] << 24) | + (params->mac_addr[3] << 16) | + (params->mac_addr[4] << 8) | + (params->mac_addr[5]))); + REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1, + ((params->mac_addr[0] << 8) | + (params->mac_addr[1]))); + /* Enable RX and TX */ val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN; val |= UMAC_COMMAND_CONFIG_REG_TX_ENA | @@ -2358,6 +2356,15 @@ int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp, return 0; } +static void bnx2x_update_mng(struct link_params *params, u32 link_status) +{ + struct bnx2x *bp = params->bp; + + REG_WR(bp, params->shmem_base + + offsetof(struct shmem_region, + port_mb[params->port].link_status), link_status); +} + static void bnx2x_update_pfc_nig(struct link_params *params, struct link_vars *vars, struct bnx2x_nig_brb_pfc_port_params *nig_params) @@ -2467,6 +2474,14 @@ int bnx2x_update_pfc(struct link_params *params, struct bnx2x *bp = params->bp; int bnx2x_status = 0; u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC); + + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) + vars->link_status |= LINK_STATUS_PFC_ENABLED; + else + vars->link_status &= ~LINK_STATUS_PFC_ENABLED; + + bnx2x_update_mng(params, vars->link_status); + /* update NIG params */ bnx2x_update_pfc_nig(params, vars, pfc_params); @@ -2695,16 +2710,6 @@ static int bnx2x_bmac_enable(struct link_params *params, return rc; } - -static void bnx2x_update_mng(struct link_params *params, u32 link_status) -{ - struct bnx2x *bp = params->bp; - - REG_WR(bp, params->shmem_base + - offsetof(struct shmem_region, - port_mb[params->port].link_status), link_status); -} - static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) { u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : @@ -4453,6 +4458,14 @@ void bnx2x_link_status_update(struct link_params *params, vars->aeu_int_mask = REG_RD(bp, sync_offset); + /* Sync PFC status */ + if (vars->link_status & LINK_STATUS_PFC_ENABLED) + params->feature_config_flags |= + FEATURE_CONFIG_PFC_ENABLED; + else + params->feature_config_flags &= + ~FEATURE_CONFIG_PFC_ENABLED; + DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", vars->link_status, vars->phy_link_up, vars->aeu_int_mask); DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 53da4ef1992..064b4452664 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -4771,6 +4771,12 @@ #define UMAC_COMMAND_CONFIG_REG_SW_RESET (0x1<<13) #define UMAC_COMMAND_CONFIG_REG_TX_ENA (0x1<<0) #define UMAC_REG_COMMAND_CONFIG 0x8 +/* [RW 32] Register Bit 0 refers to Bit 16 of the MAC address; Bit 1 refers + * to bit 17 of the MAC address etc. */ +#define UMAC_REG_MAC_ADDR0 0xc +/* [RW 16] Register Bit 0 refers to Bit 0 of the MAC address; Register Bit 1 + * refers to Bit 1 of the MAC address etc. Bits 16 to 31 are reserved. */ +#define UMAC_REG_MAC_ADDR1 0x10 /* [RW 14] Defines a 14-Bit maximum frame length used by the MAC receive * logic to check frames. */ #define UMAC_REG_MAXFR 0x14 @@ -5300,6 +5306,12 @@ #define XMAC_PFC_CTRL_HI_REG_TX_PFC_EN (0x1<<5) #define XMAC_REG_CLEAR_RX_LSS_STATUS 0x60 #define XMAC_REG_CTRL 0 +/* [RW 16] Upper 48 bits of ctrl_sa register. Used as the SA in PAUSE/PFC + * packets transmitted by the MAC */ +#define XMAC_REG_CTRL_SA_HI 0x2c +/* [RW 32] Lower 48 bits of ctrl_sa register. Used as the SA in PAUSE/PFC + * packets transmitted by the MAC */ +#define XMAC_REG_CTRL_SA_LO 0x28 #define XMAC_REG_PAUSE_CTRL 0x68 #define XMAC_REG_PFC_CTRL 0x70 #define XMAC_REG_PFC_CTRL_HI 0x74 -- cgit v1.2.3-70-g09d2 From 52c4d6c4b543574930667bfc2a4aed8af0713519 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:06:34 +0000 Subject: bnx2x: Change BCM54616S to BCM54618SE Change 1G copper PHY BCM54616S to BCM54618SE since we only have HW with latter one of the two. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 4 +-- drivers/net/bnx2x/bnx2x_link.c | 78 +++++++++++++++++++++++++++--------------- drivers/net/bnx2x/bnx2x_reg.h | 10 +++++- 3 files changed, 62 insertions(+), 30 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index d6a7aa95d96..e6f816df88b 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -696,7 +696,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00 - #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54616 0x00000e00 + #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54618SE 0x00000e00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8722 0x00000f00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00 @@ -751,7 +751,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823 0x00000b00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54640 0x00000c00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833 0x00000d00 - #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616 0x00000e00 + #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE 0x00000e00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722 0x00000f00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT_WC 0x0000fc00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 57ba8110aa5..011548a84ef 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -3530,7 +3530,7 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, vars->flow_ctrl = params->req_fc_auto_adv; else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { ret = 1; - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) { + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) { bnx2x_cl22_read(bp, phy, 0x4, &ld_pause); bnx2x_cl22_read(bp, phy, @@ -5549,7 +5549,7 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, u16 cnt, ctrl; /* Wait for soft reset to get cleared up to 1 sec */ for (cnt = 0; cnt < 1000; cnt++) { - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) bnx2x_cl22_read(bp, phy, MDIO_PMA_REG_CTRL, &ctrl); else @@ -9800,9 +9800,9 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, } /******************************************************************/ -/* 54616S PHY SECTION */ +/* 54618SE PHY SECTION */ /******************************************************************/ -static int bnx2x_54616s_config_init(struct bnx2x_phy *phy, +static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { @@ -9811,7 +9811,7 @@ static int bnx2x_54616s_config_init(struct bnx2x_phy *phy, u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp; u32 cfg_pin; - DP(NETIF_MSG_LINK, "54616S cfg init\n"); + DP(NETIF_MSG_LINK, "54618SE cfg init\n"); usleep_range(1000, 1000); /* This works with E3 only, no need to check the chip @@ -9973,11 +9973,11 @@ static int bnx2x_54616s_config_init(struct bnx2x_phy *phy, return 0; } -static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy, - struct link_params *params, u8 mode) +static void bnx2x_54618se_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) { struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "54616S set link led (mode=%x)\n", mode); + DP(NETIF_MSG_LINK, "54618SE set link led (mode=%x)\n", mode); switch (mode) { case LED_MODE_FRONT_PANEL_OFF: case LED_MODE_OFF: @@ -9989,8 +9989,8 @@ static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy, return; } -static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u32 cfg_pin; @@ -10009,9 +10009,9 @@ static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy, bnx2x_set_cfg_pin(bp, cfg_pin, 0); } -static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 val; @@ -10022,7 +10022,7 @@ static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy, bnx2x_cl22_read(bp, phy, 0x19, &legacy_status); - DP(NETIF_MSG_LINK, "54616S read_status: 0x%x\n", legacy_status); + DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status); /* Read status to clear the PHY interrupt. */ bnx2x_cl22_read(bp, phy, @@ -10074,21 +10074,45 @@ static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy, vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED; - DP(NETIF_MSG_LINK, "BCM54616S: link speed is %d\n", + DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n", vars->line_speed); + + /* Report whether EEE is resolved. */ + bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val); + if (val == MDIO_REG_GPHY_ID_54618SE) { + if (vars->link_status & + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) + val = 0; + else { + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_CL45_ADDR_REG, + MDIO_AN_DEVAD); + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_CL45_DATA_REG, + MDIO_REG_GPHY_EEE_RESOLVED); + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_CL45_ADDR_REG, + (0x1 << 14) | MDIO_AN_DEVAD); + bnx2x_cl22_read(bp, phy, + MDIO_REG_GPHY_CL45_DATA_REG, + &val); + } + DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val); + } + bnx2x_ext_phy_resolve_fc(phy, params, vars); } return link_up; } -static void bnx2x_54616s_config_loopback(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 val; u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0; - DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54616s\n"); + DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n"); /* Enable master/slave manual mmode and set to master */ /* mii write 9 [bits set 11 12] */ @@ -10705,8 +10729,8 @@ static struct bnx2x_phy phy_84833 = { .phy_specific_func = (phy_specific_func_t)NULL }; -static struct bnx2x_phy phy_54616s = { - .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616, +static struct bnx2x_phy phy_54618se = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE, .addr = 0xff, .def_md_devad = 0, .flags = FLAGS_INIT_XGXS_FIRST, @@ -10729,13 +10753,13 @@ static struct bnx2x_phy phy_54616s = { .speed_cap_mask = 0, /* req_duplex = */0, /* rsrv = */0, - .config_init = (config_init_t)bnx2x_54616s_config_init, - .read_status = (read_status_t)bnx2x_54616s_read_status, - .link_reset = (link_reset_t)bnx2x_54616s_link_reset, - .config_loopback = (config_loopback_t)bnx2x_54616s_config_loopback, + .config_init = (config_init_t)bnx2x_54618se_config_init, + .read_status = (read_status_t)bnx2x_54618se_read_status, + .link_reset = (link_reset_t)bnx2x_54618se_link_reset, + .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback, .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)bnx2x_54616s_set_link_led, + .set_link_led = (set_link_led_t)bnx2x_54618se_set_link_led, .phy_specific_func = (phy_specific_func_t)NULL }; /*****************************************************************/ @@ -10978,8 +11002,8 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: *phy = phy_84833; break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616: - *phy = phy_54616s; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE: + *phy = phy_54618se; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: *phy = phy_7101; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 064b4452664..1684e1bce5a 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6919,7 +6919,15 @@ Theotherbitsarereservedandshouldbezero*/ #define DIGITAL5_ACTUAL_SPEED_TX_MASK 0x003f -/* 54616s */ +/* 54618se */ +#define MDIO_REG_GPHY_PHYID_LSB 0x3 +#define MDIO_REG_GPHY_ID_54618SE 0x5cd5 +#define MDIO_REG_GPHY_CL45_ADDR_REG 0xd +#define MDIO_REG_GPHY_CL45_DATA_REG 0xe +#define MDIO_REG_GPHY_EEE_ADV 0x3c +#define MDIO_REG_GPHY_EEE_1G (0x1 << 2) +#define MDIO_REG_GPHY_EEE_100 (0x1 << 1) +#define MDIO_REG_GPHY_EEE_RESOLVED 0x803e #define MDIO_REG_INTR_STATUS 0x1a #define MDIO_REG_INTR_MASK 0x1b #define MDIO_REG_INTR_MASK_LINK_STATUS (0x1 << 1) -- cgit v1.2.3-70-g09d2 From a34bc969a19b3a2364c03c101abb3b4d467089c0 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:06:41 +0000 Subject: bnx2x: Add CL37 BAM for Warpcore Add CL37 BAM support according to configuration. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 14 +++++++++++++- drivers/net/bnx2x/bnx2x_reg.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 011548a84ef..270a2f7f2c7 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -3564,7 +3564,7 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u16 val16 = 0, lane; + u16 val16 = 0, lane, bam37 = 0; struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); /* Check adding advertisement for 1G KX */ @@ -3616,6 +3616,18 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); + /* Enable CL37 BAM */ + if (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].default_cfg)) & + PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37); + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1); + DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); + } + /* Advertise pause */ bnx2x_ext_phy_set_pause(params, phy, vars); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 1684e1bce5a..c97ce37f62d 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6889,6 +6889,7 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_WC_REG_DIGITAL5_MISC6 0x8345 #define MDIO_WC_REG_DIGITAL5_MISC7 0x8349 #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED 0x834e +#define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL 0x8350 #define MDIO_WC_REG_CL49_USERB0_CTRL 0x8368 #define MDIO_WC_REG_TX66_CONTROL 0x83b0 #define MDIO_WC_REG_RX66_CONTROL 0x83c0 -- cgit v1.2.3-70-g09d2 From 985848f80ffc61a29d9a72fec46ddce3c9643636 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:06:48 +0000 Subject: bnx2x: Reset PHY due to fan failure for 578xx Add hardware PHY reset action for BCM578xx when fan failure occur. The new bnx2x_warpcore_hw_reset warps bnx2x_warpcore_power_module to fit the .hw_reset function template of the phy structure. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 80 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 270a2f7f2c7..a04fa13ad1c 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -7904,6 +7904,9 @@ static void bnx2x_warpcore_power_module(struct link_params *params, dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & PORT_HW_CFG_E3_PWR_DIS_MASK) >> PORT_HW_CFG_E3_PWR_DIS_SHIFT; + + if (pin_cfg == PIN_CFG_NA) + return; DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", power, pin_cfg); /* @@ -7913,6 +7916,12 @@ static void bnx2x_warpcore_power_module(struct link_params *params, bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); } +static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + bnx2x_warpcore_power_module(params, phy, 0); +} + static void bnx2x_power_sfp_module(struct link_params *params, struct bnx2x_phy *phy, u8 power) @@ -9294,9 +9303,9 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, } -static int bnx2x_84833_common_init_phy(struct bnx2x *bp, - u32 shmem_base_path[], - u32 chip_id) +static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp, + u32 shmem_base_path[], + u32 chip_id) { u32 reset_pin[2]; u32 idx; @@ -9329,6 +9338,41 @@ static int bnx2x_84833_common_init_phy(struct bnx2x *bp, reset_gpios = (u8)(reset_pin[0] | reset_pin[1]); } + return reset_gpios; +} + +static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 reset_gpios; + u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base + + offsetof(struct shmem2_region, + other_shmem_base_addr)); + + u32 shmem_base_path[2]; + shmem_base_path[0] = params->shmem_base; + shmem_base_path[1] = other_shmem_base_addr; + + reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, + params->chip_id); + + bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW); + udelay(10); + DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n", + reset_gpios); + + return 0; +} + +static int bnx2x_84833_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 chip_id) +{ + u8 reset_gpios; + + reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id); + bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW); udelay(10); bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH); @@ -9362,17 +9406,11 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); } else { + /* MDIO reset */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x8000); - } - - bnx2x_wait_reset_complete(bp, phy, params); - /* Wait for GPHY to come out of reset */ - msleep(50); - - /* Bring PHY out of super isolate mode */ - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { + /* Bring PHY out of super isolate mode */ bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); @@ -9380,9 +9418,13 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); - bnx2x_wait_reset_complete(bp, phy, params); } + bnx2x_wait_reset_complete(bp, phy, params); + + /* Wait for GPHY to come out of reset */ + msleep(50); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) bnx2x_84833_pair_swap_cfg(phy, params, vars); @@ -10448,7 +10490,7 @@ static struct bnx2x_phy phy_warpcore = { .link_reset = (link_reset_t)bnx2x_warpcore_link_reset, .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback, .format_fw_ver = (format_fw_ver_t)NULL, - .hw_reset = (hw_reset_t)NULL, + .hw_reset = (hw_reset_t)bnx2x_warpcore_hw_reset, .set_link_led = (set_link_led_t)NULL, .phy_specific_func = (phy_specific_func_t)NULL }; @@ -10736,7 +10778,7 @@ static struct bnx2x_phy phy_84833 = { .link_reset = (link_reset_t)bnx2x_848x3_link_reset, .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, - .hw_reset = (hw_reset_t)NULL, + .hw_reset = (hw_reset_t)bnx2x_84833_hw_reset_phy, .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, .phy_specific_func = (phy_specific_func_t)NULL }; @@ -12122,7 +12164,15 @@ u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, void bnx2x_hw_reset_phy(struct link_params *params) { u8 phy_index; - for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; + struct bnx2x *bp = params->bp; + bnx2x_update_mng(params, 0); + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); + + for (phy_index = INT_PHY; phy_index < MAX_PHYS; phy_index++) { if (params->phy[phy_index].hw_reset) { params->phy[phy_index].hw_reset( -- cgit v1.2.3-70-g09d2 From 85242eea68f5039458afad0e4030828496bb4034 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:06:53 +0000 Subject: bnx2x: Fix false link indication at link partner when DAC is used When driver is unloaded, disable PMD in addition to TX laser, provided that the management firmware will be able to enable it back. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 1 + drivers/net/bnx2x/bnx2x_link.c | 35 +++++++++++++++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_link.h | 1 + drivers/net/bnx2x/bnx2x_main.c | 4 ++++ drivers/net/bnx2x/bnx2x_reg.h | 1 + 5 files changed, 42 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index e6f816df88b..52c190f6529 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -1236,6 +1236,7 @@ struct drv_func_mb { #define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006 #define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 #define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 + #define REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED 0x00070014 #define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 #define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index a04fa13ad1c..144cfae3966 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -7195,6 +7195,30 @@ static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, /******************************************************************/ /* SFP+ module Section */ /******************************************************************/ +static void bnx2x_set_disable_pmd_transmit(struct link_params *params, + struct bnx2x_phy *phy, + u8 pmd_dis) +{ + struct bnx2x *bp = params->bp; + /* + * Disable transmitter only for bootcodes which can enable it afterwards + * (for D3 link) + */ + if (pmd_dis) { + if (params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED) + DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n"); + else { + DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n"); + return; + } + } else + DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_DISABLE, pmd_dis); +} + static u8 bnx2x_get_gpio_port(struct link_params *params) { u8 gpio_port; @@ -8598,6 +8622,9 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); + /* Enable/Disable PHY transmitter output */ + bnx2x_set_disable_pmd_transmit(params, phy, 0); + /* Make MOD_ABS give interrupt on change */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, &val); @@ -8972,6 +8999,10 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; + + /* Enable/Disable PHY transmitter output */ + bnx2x_set_disable_pmd_transmit(params, phy, 1); + /* Disable Transmitter */ bnx2x_sfp_set_transmitter(params, phy, 0); /* Clear LASI */ @@ -11895,6 +11926,10 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp, if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], port_of_path)) return -EINVAL; + /* Disable PHY transmitter output */ + bnx2x_cl45_write(bp, phy_blk[port], + MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_DISABLE, 1); } return 0; diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 6f299c2fd3e..ba4d1f76283 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -250,6 +250,7 @@ struct link_params { #define FEATURE_CONFIG_PFC_ENABLED (1<<1) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) #define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) +#define FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED (1<<10) /* Will be populated during common init */ struct bnx2x_phy phy[MAX_PHYS]; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index b6f82ebc30a..98604350a81 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -8349,6 +8349,10 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ? FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0; + bp->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED) ? + FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED : 0; + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc); bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index c97ce37f62d..3c7702e449c 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6618,6 +6618,7 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_CTRL 0x0 #define MDIO_PMA_REG_STATUS 0x1 #define MDIO_PMA_REG_10G_CTRL2 0x7 +#define MDIO_PMA_REG_TX_DISABLE 0x0009 #define MDIO_PMA_REG_RX_SD 0xa /*bcm*/ #define MDIO_PMA_REG_BCM_CTRL 0x0096 -- cgit v1.2.3-70-g09d2 From 0520e63acb387a265c2a6abbf51c44c67149cf37 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:06:59 +0000 Subject: bnx2x: Fix BCM84833 initialization Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 8 +++++++- drivers/net/bnx2x/bnx2x_link.c | 45 +++++++++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 52c190f6529..0692d75756d 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -538,7 +538,13 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u32 fcoe_wwn_node_name_upper; u32 fcoe_wwn_node_name_lower; - u32 Reserved1[50]; /* 0x1C0 */ + u32 Reserved1[49]; /* 0x1C0 */ + + /* Enable RJ45 magjack pair swapping on 10GBase-T PHY (0=default), + 84833 only */ + u32 xgbt_phy_cfg; /* 0x284 */ + #define PORT_HW_CFG_RJ45_PAIR_SWAP_MASK 0x000000FF + #define PORT_HW_CFG_RJ45_PAIR_SWAP_SHIFT 0 u32 default_cfg; /* 0x288 */ #define PORT_HW_CFG_GPIO0_CONFIG_MASK 0x00000003 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 144cfae3966..d6684b38a26 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -9182,11 +9182,14 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, an_1000_val); - /* set 10 speed advertisement */ + /* set 100 speed advertisement */ if (((phy->req_line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { + (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) && + (phy->supported & + (SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full)))) { an_10_100_val |= (1<<7); /* Enable autoneg and restart autoneg for legacy speeds */ autoneg_val |= (1<<9 | 1<<12); @@ -9197,9 +9200,12 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, } /* set 10 speed advertisement */ if (((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) && + (phy->supported & + (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full)))) { an_10_100_val |= (1<<5); autoneg_val |= (1<<9 | 1<<12); if (phy->req_duplex == DUPLEX_FULL) @@ -9208,7 +9214,10 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, } /* Only 10/100 are allowed to work in FORCE mode */ - if (phy->req_line_speed == SPEED_100) { + if ((phy->req_line_speed == SPEED_100) && + (phy->supported & + (SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full))) { autoneg_val |= (1<<13); /* Enabled AUTO-MDIX when autoneg is disabled */ bnx2x_cl45_write(bp, phy, @@ -9216,7 +9225,10 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, (1<<15 | 1<<9 | 7<<0)); DP(NETIF_MSG_LINK, "Setting 100M force\n"); } - if (phy->req_line_speed == SPEED_10) { + if ((phy->req_line_speed == SPEED_10) && + (phy->supported & + (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full))) { /* Enabled AUTO-MDIX when autoneg is disabled */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, @@ -9284,11 +9296,22 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, struct link_vars *vars) { u32 idx; + u32 pair_swap; u16 val; - u16 data = 0x01b1; + u16 data; struct bnx2x *bp = params->bp; /* Do pair swap */ + /* Check for configuration. */ + pair_swap = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].xgbt_phy_cfg)) & + PORT_HW_CFG_RJ45_PAIR_SWAP_MASK; + + if (pair_swap == 0) + return 0; + + data = (u16)pair_swap; /* Write CMD_OPEN_OVERRIDE to STATUS reg */ bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, @@ -10787,9 +10810,7 @@ static struct bnx2x_phy phy_84833 = { .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, - .supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | + .supported = (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | -- cgit v1.2.3-70-g09d2 From a89a1d4a738668ccb2270ac218cddd30f0bef2a0 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:07:05 +0000 Subject: bnx2x: Add autogrEEEn support Add autogrEEEn support on BCM84833 and 54618se, which allows to reduce power consumption. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 115 ++++++++++++++++++++++++++++++++++++----- drivers/net/bnx2x/bnx2x_link.h | 1 + drivers/net/bnx2x/bnx2x_reg.h | 7 +++ 3 files changed, 111 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index d6684b38a26..03a2085bd51 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -9437,6 +9437,7 @@ static int bnx2x_84833_common_init_phy(struct bnx2x *bp, return 0; } +#define PHY84833_CONSTANT_LATENCY 1193 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -9445,7 +9446,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, u8 port, initialize = 1; u16 val; u16 temp; - u32 actual_phy_selection, cms_enable; + u32 actual_phy_selection, cms_enable, idx; int rc = 0; msleep(1); @@ -9537,24 +9538,86 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", params->multi_phy_config, val); + /* AutogrEEEn */ + if (params->feature_config_flags & + FEATURE_CONFIG_AUTOGREEEN_ENABLED) { + /* Ensure that f/w is ready */ + for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) { + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG2, &val); + if (val == PHY84833_CMD_OPEN_FOR_CMDS) + break; + usleep_range(1000, 1000); + } + if (idx >= PHY84833_HDSHK_WAIT) { + DP(NETIF_MSG_LINK, "AutogrEEEn: FW not ready.\n"); + return -EINVAL; + } + + /* Select EEE mode */ + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG3, + 0x2); + + /* Set Idle and Latency */ + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG4, + PHY84833_CONSTANT_LATENCY + 1); + + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_DATA3_REG, + PHY84833_CONSTANT_LATENCY + 1); + + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_DATA4_REG, + PHY84833_CONSTANT_LATENCY); + + /* Send EEE instruction to command register */ + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG0, + PHY84833_DIAG_CMD_SET_EEE_MODE); + + /* Ensure that the command has completed */ + for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) { + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG2, &val); + if ((val == PHY84833_CMD_COMPLETE_PASS) || + (val == PHY84833_CMD_COMPLETE_ERROR)) + break; + usleep_range(1000, 1000); + } + if ((idx >= PHY84833_HDSHK_WAIT) || + (val == PHY84833_CMD_COMPLETE_ERROR)) { + DP(NETIF_MSG_LINK, "AutogrEEEn: command failed.\n"); + return -EINVAL; + } + + /* Reset command handler */ + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_84833_TOP_CFG_SCRATCH_REG2, + PHY84833_CMD_CLEAR_COMPLETE); + } + if (initialize) rc = bnx2x_848xx_cmn_config_init(phy, params, vars); else bnx2x_save_848xx_spirom_version(phy, params); - cms_enable = REG_RD(bp, params->shmem_base + + /* 84833 PHY has a better feature and doesn't need to support this. */ + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { + cms_enable = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info.port_hw_config[params->port].default_cfg)) & PORT_HW_CFG_ENABLE_CMS_MASK; - bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, - MDIO_CTL_REG_84823_USER_CTRL_REG, &val); - if (cms_enable) - val |= MDIO_CTL_REG_84823_USER_CTRL_CMS; - else - val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS; - bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, - MDIO_CTL_REG_84823_USER_CTRL_REG, val); - + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_USER_CTRL_REG, &val); + if (cms_enable) + val |= MDIO_CTL_REG_84823_USER_CTRL_CMS; + else + val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS; + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_USER_CTRL_REG, val); + } return rc; } @@ -10068,6 +10131,30 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Setting 10M force\n"); } + /* Check if we should turn on Auto-GrEEEn */ + bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp); + if (temp == MDIO_REG_GPHY_ID_54618SE) { + if (params->feature_config_flags & + FEATURE_CONFIG_AUTOGREEEN_ENABLED) { + temp = 6; + DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n"); + } else { + temp = 0; + DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n"); + } + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD); + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_CL45_DATA_REG, + MDIO_REG_GPHY_EEE_ADV); + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_CL45_ADDR_REG, + (0x1 << 14) | MDIO_AN_DEVAD); + bnx2x_cl22_write(bp, phy, + MDIO_REG_GPHY_CL45_DATA_REG, + temp); + } + bnx2x_cl22_write(bp, phy, 0x04, an_10_100_val | fc_val); @@ -11597,12 +11684,16 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, bnx2x_set_led(params, vars, LED_MODE_OFF, 0); if (reset_ext_phy) { + bnx2x_set_mdio_clk(bp, params->chip_id, port); for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { - if (params->phy[phy_index].link_reset) + if (params->phy[phy_index].link_reset) { + bnx2x_set_aer_mmd(params, + ¶ms->phy[phy_index]); params->phy[phy_index].link_reset( ¶ms->phy[phy_index], params); + } if (params->phy[phy_index].flags & FLAGS_REARM_LATCH_SIGNAL) clear_latch_ind = 1; diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index ba4d1f76283..6a7708d5da3 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -250,6 +250,7 @@ struct link_params { #define FEATURE_CONFIG_PFC_ENABLED (1<<1) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) #define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) +#define FEATURE_CONFIG_AUTOGREEEN_ENABLED (1<<9) #define FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED (1<<10) /* Will be populated during common init */ struct bnx2x_phy phy[MAX_PHYS]; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 3c7702e449c..005c05af090 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6792,6 +6792,8 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_84833_TOP_CFG_SCRATCH_REG2 0x4007 #define MDIO_84833_TOP_CFG_SCRATCH_REG3 0x4008 #define MDIO_84833_TOP_CFG_SCRATCH_REG4 0x4009 +#define MDIO_84833_TOP_CFG_DATA3_REG 0x4011 +#define MDIO_84833_TOP_CFG_DATA4_REG 0x4012 /* Mailbox command set used by 84833. */ #define PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE 0x2 @@ -6806,6 +6808,11 @@ Theotherbitsarereservedandshouldbezero*/ #define PHY84833_CMD_CLEAR_COMPLETE 0x0080 #define PHY84833_CMD_OPEN_OVERRIDE 0xa5a5 + +/* 84833 F/W Feature Commands */ +#define PHY84833_DIAG_CMD_GET_EEE_MODE 0x27 +#define PHY84833_DIAG_CMD_SET_EEE_MODE 0x28 + /* Warpcore clause 45 addressing */ #define MDIO_WC_DEVAD 0x3 #define MDIO_WC_REG_IEEE0BLK_MIICNTL 0x0 -- cgit v1.2.3-70-g09d2 From 7d09926d1decb658d4e24f70216b6b0b74168026 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 5 Jul 2011 01:07:16 +0000 Subject: bnx2x: Fix warning message during 57712/8727 initialization Clear warning message "MDC/MDIO access timeout" during first driver load by setting MDIO clock. This warning has no significant meaning, since it occurs prior to the first PHY initialization. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 03a2085bd51..bcd8f003862 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -11684,16 +11684,12 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, bnx2x_set_led(params, vars, LED_MODE_OFF, 0); if (reset_ext_phy) { - bnx2x_set_mdio_clk(bp, params->chip_id, port); for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { - if (params->phy[phy_index].link_reset) { - bnx2x_set_aer_mmd(params, - ¶ms->phy[phy_index]); + if (params->phy[phy_index].link_reset) params->phy[phy_index].link_reset( ¶ms->phy[phy_index], params); - } if (params->phy[phy_index].flags & FLAGS_REARM_LATCH_SIGNAL) clear_latch_ind = 1; -- cgit v1.2.3-70-g09d2 From b992c68228a3ccdf73ea4f57519e1663839a9cbe Mon Sep 17 00:00:00 2001 From: Oz Krakowski Date: Sun, 26 Jun 2011 10:36:02 +0300 Subject: wl12xx: fix Tx security sequence number handling Do not reset the security sequence number when issuing a join command or interface is removed. Instead, reset the counter only during the unjoin command. Added the notion of counter wrap-around to the LSB number in wl1271_tx_complete_packet. Added post recovery padding to adjust for potential security number progress during the recovery process by the firmware and avoid potential interop issues in encrypted networks. Signed-off-by: Oz Krakowski Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 4 ---- drivers/net/wireless/wl12xx/debugfs.c | 2 +- drivers/net/wireless/wl12xx/main.c | 18 ++++++++++++++++-- drivers/net/wireless/wl12xx/tx.c | 22 ++++++++++++++++++---- drivers/net/wireless/wl12xx/tx.h | 2 +- drivers/net/wireless/wl12xx/wl12xx.h | 14 +++++++++++--- 6 files changed, 47 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index c9a1fa52327..a712a0f7b37 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -400,10 +400,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; - /* reset TX security counters */ - wl->tx_security_last_seq = 0; - wl->tx_security_seq = 0; - wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x", join->basic_rate_set, join->supported_rate_set); diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index da212701830..3f6314143ef 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -349,7 +349,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]); DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]); DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]); - DRIVER_STATE_PRINT_INT(tx_security_last_seq); + DRIVER_STATE_PRINT_INT(tx_security_last_seq_lsb); DRIVER_STATE_PRINT_INT(rx_counter); DRIVER_STATE_PRINT_INT(session_counter); DRIVER_STATE_PRINT_INT(state); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index a3734bdf511..b896f5956d9 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1227,6 +1227,15 @@ static void wl1271_recovery_work(struct work_struct *work) wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); + /* + * Advance security sequence number to overcome potential progress + * in the firmware during recovery. This doens't hurt if the network is + * not encrypted. + */ + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) || + test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) + wl->tx_security_seq += WL1271_TX_SQN_POST_RECOVERY_PADDING; + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) ieee80211_connection_loss(wl->vif); @@ -1980,8 +1989,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, wl->tx_allocated_blocks = 0; wl->tx_results_count = 0; wl->tx_packets_count = 0; - wl->tx_security_last_seq = 0; - wl->tx_security_seq = 0; wl->time_offset = 0; wl->session_counter = 0; wl->rate_set = CONF_TX_RATE_MASK_BASIC; @@ -2154,6 +2161,10 @@ static int wl1271_unjoin(struct wl1271 *wl) clear_bit(WL1271_FLAG_JOINED, &wl->flags); memset(wl->bssid, 0, ETH_ALEN); + /* reset TX security counters on a clean disconnect */ + wl->tx_security_last_seq_lsb = 0; + wl->tx_security_seq = 0; + /* stop filtering packets based on bssid */ wl1271_configure_filters(wl, FIF_OTHER_BSS); @@ -4327,6 +4338,9 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->quirks = 0; wl->platform_quirks = 0; wl->sched_scanning = false; + wl->tx_security_seq = 0; + wl->tx_security_last_seq_lsb = 0; + setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer, (unsigned long) wl); wl->fwlog_size = 0; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 200590c0d9e..003f9e08691 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -704,10 +704,24 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, wl->stats.retry_count += result->ack_failures; - /* update security sequence number */ - wl->tx_security_seq += (result->lsb_security_sequence_number - - wl->tx_security_last_seq); - wl->tx_security_last_seq = result->lsb_security_sequence_number; + /* + * update sequence number only when relevant, i.e. only in + * sessions of TKIP, AES and GEM (not in open or WEP sessions) + */ + if (info->control.hw_key && + (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP || + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP || + info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) { + u8 fw_lsb = result->tx_security_sequence_number_lsb; + u8 cur_lsb = wl->tx_security_last_seq_lsb; + + /* + * update security sequence number, taking care of potential + * wrap-around + */ + wl->tx_security_seq += (fw_lsb - cur_lsb + 256) % 256; + wl->tx_security_last_seq_lsb = fw_lsb; + } /* remove private header from packet */ skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 832f9258d67..7ed3c01f365 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -150,7 +150,7 @@ struct wl1271_tx_hw_res_descr { (from 1st EDCA AIFS counter until TX Complete). */ __le32 medium_delay; /* LS-byte of last TKIP seq-num (saved per AC for recovery). */ - u8 lsb_security_sequence_number; + u8 tx_security_sequence_number_lsb; /* Retry count - number of transmissions without successful ACK.*/ u8 ack_failures; /* The rate that succeeded getting ACK diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index d7db6e77047..002d9c53e37 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -144,6 +144,7 @@ extern u32 wl12xx_debug_level; #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) +#define WL1271_TX_SQN_POST_RECOVERY_PADDING 0xff #define WL1271_CIPHER_SUITE_GEM 0x00147201 @@ -454,9 +455,16 @@ struct wl1271 { struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; int tx_frames_cnt; - /* Security sequence number counters */ - u8 tx_security_last_seq; - s64 tx_security_seq; + /* + * Security sequence number + * bits 0-15: lower 16 bits part of sequence number + * bits 16-47: higher 32 bits part of sequence number + * bits 48-63: not in use + */ + u64 tx_security_seq; + + /* 8 bits of the last sequence number in use */ + u8 tx_security_last_seq_lsb; /* FW Rx counter */ u32 rx_counter; -- cgit v1.2.3-70-g09d2 From 3618f30f307841dba19f22d9c602a5c59cab30c7 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 26 Jun 2011 10:36:03 +0300 Subject: wl12xx: AP mode - support FW TX inactivity triggers In AP mode we register for the MAX_TX_RETRY and INACTIVE_STA events. Both are reported to the upper layers as a TX failure in the offending stations. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 10 ++++----- drivers/net/wireless/wl12xx/acx.h | 4 ++-- drivers/net/wireless/wl12xx/boot.c | 4 +++- drivers/net/wireless/wl12xx/cmd.c | 2 +- drivers/net/wireless/wl12xx/conf.h | 10 ++++++++- drivers/net/wireless/wl12xx/event.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/event.h | 12 ++++++++++- drivers/net/wireless/wl12xx/init.c | 2 +- drivers/net/wireless/wl12xx/main.c | 9 +++++++- drivers/net/wireless/wl12xx/wl12xx.h | 1 - 10 files changed, 82 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 87caa94fd81..2f5207ae7cf 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1624,22 +1624,22 @@ out: return ret; } -int wl1271_acx_max_tx_retry(struct wl1271 *wl) +int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl) { - struct wl1271_acx_max_tx_retry *acx = NULL; + struct wl1271_acx_ap_max_tx_retry *acx = NULL; int ret; - wl1271_debug(DEBUG_ACX, "acx max tx retry"); + wl1271_debug(DEBUG_ACX, "acx ap max tx retry"); acx = kzalloc(sizeof(*acx), GFP_KERNEL); if (!acx) return -ENOMEM; - acx->max_tx_retry = cpu_to_le16(wl->conf.tx.ap_max_tx_retries); + acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries); ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx)); if (ret < 0) { - wl1271_warning("acx max tx retry failed: %d", ret); + wl1271_warning("acx ap max tx retry failed: %d", ret); goto out; } diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index d303265f163..d2eb86eccc0 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1168,7 +1168,7 @@ struct wl1271_acx_ps_rx_streaming { u8 timeout; } __packed; -struct wl1271_acx_max_tx_retry { +struct wl1271_acx_ap_max_tx_retry { struct acx_header header; /* @@ -1400,7 +1400,7 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, bool enable); int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable); -int wl1271_acx_max_tx_retry(struct wl1271 *wl); +int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl); int wl1271_acx_config_ps(struct wl1271 *wl); int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable); diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 101f7e0f632..5ebc64d8940 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -513,7 +513,9 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) PERIODIC_SCAN_COMPLETE_EVENT_ID; if (wl->bss_type == BSS_TYPE_AP_BSS) - wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID; + wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID | + INACTIVE_STA_EVENT_ID | + MAX_TX_RETRY_EVENT_ID; else wl->event_mask |= DUMMY_PACKET_EVENT_ID | BA_SESSION_RX_CONSTRAINT_EVENT_ID; diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index a712a0f7b37..11a2f220392 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -1080,7 +1080,7 @@ int wl1271_cmd_start_bss(struct wl1271 *wl) memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN); - cmd->aging_period = cpu_to_le16(WL1271_AP_DEF_INACTIV_SEC); + cmd->aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); cmd->bss_index = WL1271_AP_BSS_INDEX; cmd->global_hlid = WL1271_AP_GLOBAL_HLID; cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID; diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index b5a7b30afda..6080e01d92c 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -713,8 +713,16 @@ struct conf_tx_settings { /* * AP-mode - allow this number of TX retries to a station before an * event is triggered from FW. + * In AP-mode the hlids of unreachable stations are given in the + * "sta_tx_retry_exceeded" member in the event mailbox. */ - u16 ap_max_tx_retries; + u8 max_tx_retries; + + /* + * AP-mode - after this number of seconds a connected station is + * considered inactive. + */ + u16 ap_aging_period; /* * Configuration for TID parameters. diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index a16dee58a66..304aaa2ee01 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -214,6 +214,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) u32 vector; bool beacon_loss = false; bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + bool disconnect_sta = false; + unsigned long sta_bitmap = 0; wl1271_event_mbox_dump(mbox); @@ -295,6 +297,46 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_tx_dummy_packet(wl); } + /* + * "TX retries exceeded" has a different meaning according to mode. + * In AP mode the offending station is disconnected. + */ + if ((vector & MAX_TX_RETRY_EVENT_ID) && is_ap) { + wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID"); + sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded); + disconnect_sta = true; + } + + if ((vector & INACTIVE_STA_EVENT_ID) && is_ap) { + wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID"); + sta_bitmap |= le16_to_cpu(mbox->sta_aging_status); + disconnect_sta = true; + } + + if (is_ap && disconnect_sta) { + u32 num_packets = wl->conf.tx.max_tx_retries; + struct ieee80211_sta *sta; + const u8 *addr; + int h; + + for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS); + h < AP_MAX_LINKS; + h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) { + if (!wl1271_is_active_sta(wl, h)) + continue; + + addr = wl->links[h].addr; + + rcu_read_lock(); + sta = ieee80211_find_sta(wl->vif, addr); + if (sta) { + wl1271_debug(DEBUG_EVENT, "remove sta %d", h); + ieee80211_report_low_ack(sta, num_packets); + } + rcu_read_unlock(); + } + } + if (wl->vif && beacon_loss) ieee80211_connection_loss(wl->vif); diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index ce99adf4256..e524ad6fe4e 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h @@ -58,13 +58,16 @@ enum { CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), BSS_LOSE_EVENT_ID = BIT(18), REGAINED_BSS_EVENT_ID = BIT(19), - ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20), + MAX_TX_RETRY_EVENT_ID = BIT(20), /* STA: dummy paket for dynamic mem blocks */ DUMMY_PACKET_EVENT_ID = BIT(21), /* AP: STA remove complete */ STA_REMOVE_COMPLETE_EVENT_ID = BIT(21), SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), + /* STA: SG prediction */ SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), + /* AP: Inactive STA */ + INACTIVE_STA_EVENT_ID = BIT(23), SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25), DBG_EVENT_ID = BIT(26), @@ -119,7 +122,11 @@ struct event_mailbox { /* AP FW only */ u8 hlid_removed; + + /* a bitmap of hlids for stations that have been inactive too long */ __le16 sta_aging_status; + + /* a bitmap of hlids for stations which didn't respond to TX */ __le16 sta_tx_retry_exceeded; /* @@ -143,4 +150,7 @@ void wl1271_event_mbox_config(struct wl1271 *wl); int wl1271_event_handle(struct wl1271 *wl, u8 mbox); void wl1271_pspoll_work(struct work_struct *work); +/* Functions from main.c */ +bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid); + #endif diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index cf40ac93cea..ebfde942bec 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -447,7 +447,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl) if (ret < 0) return ret; - ret = wl1271_acx_max_tx_retry(wl); + ret = wl1271_acx_ap_max_tx_retry(wl); if (ret < 0) return ret; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index b896f5956d9..8b929fa0d3c 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -210,7 +210,8 @@ static struct conf_drv_settings default_conf = { .tx_op_limit = 1504, }, }, - .ap_max_tx_retries = 100, + .max_tx_retries = 100, + .ap_aging_period = 300, .tid_conf_count = 4, .tid_conf = { [CONF_TX_AC_BE] = { @@ -3526,6 +3527,12 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid) __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); } +bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid) +{ + int id = hlid - WL1271_AP_STA_HLID_START; + return test_bit(id, wl->ap_hlid_map); +} + static int wl1271_op_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 002d9c53e37..63be7f214bf 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -173,7 +173,6 @@ extern u32 wl12xx_debug_level; #define WL1271_PS_STA_MAX_BLOCKS (2 * 9) #define WL1271_AP_BSS_INDEX 0 -#define WL1271_AP_DEF_INACTIV_SEC 300 #define WL1271_AP_DEF_BEACON_EXP 20 #define ACX_TX_DESCRIPTORS 32 -- cgit v1.2.3-70-g09d2 From fae2fd767e9d380ed0d05e4a5d6b1673e2c2d3df Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 26 Jun 2011 10:36:04 +0300 Subject: wl12xx: use 802.11 header location after relocation to frame start When operating with TKIP encryption, the function wl1271_tx_fill_hdr() relocates the 802.11 header to the start of the frame, and leaves room for the security header. Some functions in the Tx path rely on the location of the header, namely, for purposes of roaming in STA mode and connecting new stations in AP mode. Call these functions only after the header is relocated. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 003f9e08691..5c618c5ceda 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -383,6 +383,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, if (ret < 0) return ret; + wl1271_tx_fill_hdr(wl, skb, extra, info, hlid); + if (wl->bss_type == BSS_TYPE_AP_BSS) { wl1271_tx_ap_update_inconnection_sta(wl, skb); wl1271_tx_regulate_link(wl, hlid); @@ -390,8 +392,6 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, wl1271_tx_update_filters(wl, skb); } - wl1271_tx_fill_hdr(wl, skb, extra, info, hlid); - /* * The length of each packet is stored in terms of * words. Thus, we must pad the skb data to make sure its -- cgit v1.2.3-70-g09d2 From 9e374a37b6fa2310b71d3c5657cd0c1e693120c6 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 24 Jun 2011 13:03:35 +0300 Subject: wl12xx: schedule TX packets according to FW occupancy When selecting packets for transmission, prefer the ACs that are least occupied in the FW. When packets for multiple ACs are present in the FW, it decides which to transmit according to WMM QoS parameters. With these changes, lower priority ACs should not be starved when higher priority traffic is present. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 5 ++- drivers/net/wireless/wl12xx/main.c | 30 +++++++++++----- drivers/net/wireless/wl12xx/tx.c | 68 +++++++++++++++++++++++------------ drivers/net/wireless/wl12xx/wl12xx.h | 2 +- 4 files changed, 72 insertions(+), 33 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 3f6314143ef..4d9c8cc076e 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -338,7 +338,10 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, #define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x") DRIVER_STATE_PRINT_INT(tx_blocks_available); - DRIVER_STATE_PRINT_INT(tx_allocated_blocks); + DRIVER_STATE_PRINT_INT(tx_allocated_blocks[0]); + DRIVER_STATE_PRINT_INT(tx_allocated_blocks[1]); + DRIVER_STATE_PRINT_INT(tx_allocated_blocks[2]); + DRIVER_STATE_PRINT_INT(tx_allocated_blocks[3]); DRIVER_STATE_PRINT_INT(tx_frames_cnt); DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]); DRIVER_STATE_PRINT_INT(tx_queue_count); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8b929fa0d3c..08eb81e698f 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -824,13 +824,24 @@ static void wl1271_irq_update_links_status(struct wl1271 *wl, } } +static u32 wl1271_tx_allocated_blocks(struct wl1271 *wl) +{ + int i; + u32 total_alloc_blocks = 0; + + for (i = 0; i < NUM_TX_QUEUES; i++) + total_alloc_blocks += wl->tx_allocated_blocks[i]; + + return total_alloc_blocks; +} + static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_full_status *full_status) { struct wl1271_fw_common_status *status = &full_status->common; struct timespec ts; u32 old_tx_blk_count = wl->tx_blocks_available; - u32 freed_blocks = 0; + u32 freed_blocks = 0, ac_freed_blocks; int i; if (wl->bss_type == BSS_TYPE_AP_BSS) { @@ -850,21 +861,23 @@ static void wl1271_fw_status(struct wl1271 *wl, /* update number of available TX blocks */ for (i = 0; i < NUM_TX_QUEUES; i++) { - freed_blocks += le32_to_cpu(status->tx_released_blks[i]) - - wl->tx_blocks_freed[i]; + ac_freed_blocks = le32_to_cpu(status->tx_released_blks[i]) - + wl->tx_blocks_freed[i]; + freed_blocks += ac_freed_blocks; + + wl->tx_allocated_blocks[i] -= ac_freed_blocks; wl->tx_blocks_freed[i] = le32_to_cpu(status->tx_released_blks[i]); } - wl->tx_allocated_blocks -= freed_blocks; - if (wl->bss_type == BSS_TYPE_AP_BSS) { /* Update num of allocated TX blocks per link and ps status */ wl1271_irq_update_links_status(wl, &full_status->ap); wl->tx_blocks_available += freed_blocks; } else { - int avail = full_status->sta.tx_total - wl->tx_allocated_blocks; + int avail = full_status->sta.tx_total - + wl1271_tx_allocated_blocks(wl); /* * The FW might change the total number of TX memblocks before @@ -1987,7 +2000,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, wl->psm_entry_retry = 0; wl->power_level = WL1271_DEFAULT_POWER_LEVEL; wl->tx_blocks_available = 0; - wl->tx_allocated_blocks = 0; wl->tx_results_count = 0; wl->tx_packets_count = 0; wl->time_offset = 0; @@ -2008,8 +2020,10 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, */ wl->flags = 0; - for (i = 0; i < NUM_TX_QUEUES; i++) + for (i = 0; i < NUM_TX_QUEUES; i++) { wl->tx_blocks_freed[i] = 0; + wl->tx_allocated_blocks[i] = 0; + } wl1271_debugfs_reset(wl); diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 5c618c5ceda..e6e5f54b8e4 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -168,7 +168,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; u32 len; u32 total_blocks; - int id, ret = -EBUSY; + int id, ret = -EBUSY, ac; u32 spare_blocks; if (unlikely(wl->quirks & WL12XX_QUIRK_USE_2_SPARE_BLOCKS)) @@ -206,7 +206,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, desc->id = id; wl->tx_blocks_available -= total_blocks; - wl->tx_allocated_blocks += total_blocks; + + ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); + wl->tx_allocated_blocks[ac] += total_blocks; if (wl->bss_type == BSS_TYPE_AP_BSS) wl->links[hlid].allocated_blks += total_blocks; @@ -453,21 +455,41 @@ void wl1271_handle_tx_low_watermark(struct wl1271 *wl) } } +static struct sk_buff_head *wl1271_select_queue(struct wl1271 *wl, + struct sk_buff_head *queues) +{ + int i, q = -1; + u32 min_blks = 0xffffffff; + + /* + * Find a non-empty ac where: + * 1. There are packets to transmit + * 2. The FW has the least allocated blocks + */ + for (i = 0; i < NUM_TX_QUEUES; i++) + if (!skb_queue_empty(&queues[i]) && + (wl->tx_allocated_blocks[i] < min_blks)) { + q = i; + min_blks = wl->tx_allocated_blocks[q]; + } + + if (q == -1) + return NULL; + + return &queues[q]; +} + static struct sk_buff *wl1271_sta_skb_dequeue(struct wl1271 *wl) { struct sk_buff *skb = NULL; unsigned long flags; + struct sk_buff_head *queue; - skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VO]); - if (skb) - goto out; - skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VI]); - if (skb) + queue = wl1271_select_queue(wl, wl->tx_queue); + if (!queue) goto out; - skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BE]); - if (skb) - goto out; - skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BK]); + + skb = skb_dequeue(queue); out: if (skb) { @@ -484,6 +506,7 @@ static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl) struct sk_buff *skb = NULL; unsigned long flags; int i, h, start_hlid; + struct sk_buff_head *queue; /* start from the link after the last one */ start_hlid = (wl->last_tx_hlid + 1) % AP_MAX_LINKS; @@ -492,21 +515,20 @@ static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl) for (i = 0; i < AP_MAX_LINKS; i++) { h = (start_hlid + i) % AP_MAX_LINKS; - skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VO]); - if (skb) - goto out; - skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VI]); - if (skb) - goto out; - skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BE]); - if (skb) - goto out; - skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BK]); + /* only consider connected stations */ + if (h >= WL1271_AP_STA_HLID_START && + !test_bit(h - WL1271_AP_STA_HLID_START, wl->ap_hlid_map)) + continue; + + queue = wl1271_select_queue(wl, wl->links[h].tx_queue); + if (!queue) + continue; + + skb = skb_dequeue(queue); if (skb) - goto out; + break; } -out: if (skb) { wl->last_tx_hlid = h; spin_lock_irqsave(&wl->wl_lock, flags); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 63be7f214bf..c6bf4b4e15d 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -424,7 +424,7 @@ struct wl1271 { /* Accounting for allocated / available TX blocks on HW */ u32 tx_blocks_freed[NUM_TX_QUEUES]; u32 tx_blocks_available; - u32 tx_allocated_blocks; + u32 tx_allocated_blocks[NUM_TX_QUEUES]; u32 tx_results_count; /* Transmitted TX packets counter for chipset interface */ -- cgit v1.2.3-70-g09d2 From 787b2dc44aa1ae2524f022659c6c6b2d3c979e04 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Fri, 24 Jun 2011 13:03:36 +0300 Subject: wl12xx: Increase low & high TX watermarks The current TX watermark settings cause the driver to stop queues too frequently. Among other things, this can have a negative impact on WMM prioritization, since mac80211 sorts pending packets by their ACs. Fix this by increasing the high watermark to 256 packets. Increase the low watermark to 32 to minimize periods with queues being stopped. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl12xx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index c6bf4b4e15d..000dfcd2255 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -639,8 +639,8 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); #define WL1271_DEFAULT_POWER_LEVEL 0 -#define WL1271_TX_QUEUE_LOW_WATERMARK 10 -#define WL1271_TX_QUEUE_HIGH_WATERMARK 25 +#define WL1271_TX_QUEUE_LOW_WATERMARK 32 +#define WL1271_TX_QUEUE_HIGH_WATERMARK 256 #define WL1271_DEFERRED_QUEUE_LIMIT 64 -- cgit v1.2.3-70-g09d2 From 708bb3cf58a9bc90f3171ba64f30601f690e5aaa Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 24 Jun 2011 13:03:37 +0300 Subject: wl12xx: implement Tx watermarks per AC Each AC is stopped when its queue is filled up to the high watermark, and restarted when its queue it lower than the low watermark. This ensures congested ACs are not able to starve other ACs. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 13 +++++++------ drivers/net/wireless/wl12xx/tx.c | 20 +++++++++++++------- drivers/net/wireless/wl12xx/tx.h | 16 ++++++++++++++++ drivers/net/wireless/wl12xx/wl12xx.h | 1 + 4 files changed, 37 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 08eb81e698f..d7a74597fd5 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1497,10 +1497,11 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1271 *wl = hw->priv; unsigned long flags; - int q; + int q, mapping; u8 hlid = 0; - q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); + mapping = skb_get_queue_mapping(skb); + q = wl1271_tx_get_queue(mapping); if (wl->bss_type == BSS_TYPE_AP_BSS) hlid = wl1271_tx_get_hlid(skb); @@ -1513,10 +1514,10 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * The workqueue is slow to process the tx_queue and we need stop * the queue here, otherwise the queue will get too long. */ - if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) { - wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); - ieee80211_stop_queues(wl->hw); - set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); + if (skb_queue_len(&wl->tx_queue[q]) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { + wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q); + ieee80211_stop_queue(wl->hw, mapping); + set_bit(q, &wl->stopped_queues_map); } /* queue the packet */ diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index e6e5f54b8e4..75984dc81a8 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -444,14 +444,19 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) void wl1271_handle_tx_low_watermark(struct wl1271 *wl) { unsigned long flags; + int i; - if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && - wl->tx_queue_count <= WL1271_TX_QUEUE_LOW_WATERMARK) { - /* firmware buffer has space, restart queues */ - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_wake_queues(wl->hw); - clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); + for (i = 0; i < NUM_TX_QUEUES; i++) { + if (test_bit(i, &wl->stopped_queues_map) && + skb_queue_len(&wl->tx_queue[i]) <= + WL1271_TX_QUEUE_LOW_WATERMARK) { + /* firmware buffer has space, restart queues */ + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_wake_queue(wl->hw, + wl1271_tx_get_mac80211_queue(i)); + clear_bit(i, &wl->stopped_queues_map); + spin_unlock_irqrestore(&wl->wl_lock, flags); + } } } @@ -863,6 +868,7 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) } wl->tx_queue_count = 0; + wl->stopped_queues_map = 0; /* * Make sure the driver is at a consistent state, in case this diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 7ed3c01f365..6b7bf3150ec 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -182,6 +182,22 @@ static inline int wl1271_tx_get_queue(int queue) } } +static inline int wl1271_tx_get_mac80211_queue(int queue) +{ + switch (queue) { + case CONF_TX_AC_VO: + return 0; + case CONF_TX_AC_VI: + return 1; + case CONF_TX_AC_BE: + return 2; + case CONF_TX_AC_BK: + return 3; + default: + return 2; + } +} + void wl1271_tx_work(struct work_struct *work); void wl1271_tx_work_locked(struct wl1271 *wl); void wl1271_tx_complete(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 000dfcd2255..94bfc0a25d5 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -439,6 +439,7 @@ struct wl1271 { /* Frames scheduled for transmission, not handled yet */ struct sk_buff_head tx_queue[NUM_TX_QUEUES]; int tx_queue_count; + long stopped_queues_map; /* Frames received, not handled yet by mac80211 */ struct sk_buff_head deferred_rx_queue; -- cgit v1.2.3-70-g09d2 From b5d6e5f66304bddc2b5bc7222e993dfeb629ef0c Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Sun, 26 Jun 2011 18:00:11 +0300 Subject: wl12xx: one SDIO initialization is enough Skip manual device power on in case runtime PM is enabled for our device. This eliminates a secondary & redundant SDIO init sequence. Signed-off-by: Ohad Ben-Cohen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 4dc4573b686..5cf18c2c23f 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -166,13 +166,13 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) ret = pm_runtime_get_sync(&func->dev); if (ret) goto out; + } else { + /* Runtime PM is disabled: power up the card manually */ + ret = mmc_power_restore_host(func->card->host); + if (ret < 0) + goto out; } - /* Runtime PM might be disabled, so power up the card manually */ - ret = mmc_power_restore_host(func->card->host); - if (ret < 0) - goto out; - sdio_claim_host(func); sdio_enable_func(func); @@ -188,7 +188,7 @@ static int wl1271_sdio_power_off(struct wl1271 *wl) sdio_disable_func(func); sdio_release_host(func); - /* Runtime PM might be disabled, so power off the card manually */ + /* Power off the card manually, even if runtime PM is enabled. */ ret = mmc_power_save_host(func->card->host); if (ret < 0) return ret; -- cgit v1.2.3-70-g09d2 From e85d1629c69f99e91598039e5c05f1608ad19c9f Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 27 Jun 2011 13:06:43 +0300 Subject: wl12xx: configure suspend/resume only if associated/started Configure the device (to wowlan) only if the sta/ap is associated/started. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index d7a74597fd5..357dc9d9994 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1610,10 +1610,13 @@ static struct notifier_block wl1271_dev_notifier = { #ifdef CONFIG_PM static int wl1271_configure_suspend_sta(struct wl1271 *wl) { - int ret; + int ret = 0; mutex_lock(&wl->mutex); + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + goto out_unlock; + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out_unlock; @@ -1658,10 +1661,13 @@ out: static int wl1271_configure_suspend_ap(struct wl1271 *wl) { - int ret; + int ret = 0; mutex_lock(&wl->mutex); + if (!test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) + goto out_unlock; + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out_unlock; -- cgit v1.2.3-70-g09d2 From 2aa01597eb29304fe7d863f15300c7b960b587ca Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 27 Jun 2011 13:06:44 +0300 Subject: wl12xx: add stop_scan command define wl1271_scan_stop() to cancel an ongoing hw scan. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/scan.c | 27 +++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/scan.h | 1 + 2 files changed, 28 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 5e5c66dd06d..edfe01c321c 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -321,6 +321,33 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, return 0; } +int wl1271_scan_stop(struct wl1271 *wl) +{ + struct wl1271_cmd_header *cmd = NULL; + int ret = 0; + + if (WARN_ON(wl->scan.state == WL1271_SCAN_STATE_IDLE)) + return -EINVAL; + + wl1271_debug(DEBUG_CMD, "cmd scan stop"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + ret = wl1271_cmd_send(wl, CMD_STOP_SCAN, cmd, + sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("cmd stop_scan failed"); + goto out; + } +out: + kfree(cmd); + return ret; +} + static int wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h index ca81de20ebe..d882e4da71b 100644 --- a/drivers/net/wireless/wl12xx/scan.h +++ b/drivers/net/wireless/wl12xx/scan.h @@ -28,6 +28,7 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, struct cfg80211_scan_request *req); +int wl1271_scan_stop(struct wl1271 *wl); int wl1271_scan_build_probe_req(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u8 band); -- cgit v1.2.3-70-g09d2 From 73ecce31fe04a2d6c87192cc752b5bd733a8c94a Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 27 Jun 2011 13:06:45 +0300 Subject: wl12xx: implement cancel_hw_scan() callback After implementing cancel_hw_scan(), there is no more need to flush scan_complete_work on suspend. scan_complete_work enqueues a new scan_work, that might lead to the following warning (if the device was already suspended): WARNING: at drivers/mmc/core/core.c:169 mmc_wait_for_req+0x1ac/0x2c8() Backtrace: [] (dump_backtrace+0x0/0x110) [] (dump_stack+0x0/0x1c) [] (warn_slowpath_common+0x0/0x6c) [] (warn_slowpath_null+0x0/0x2c) [] (mmc_wait_for_req+0x0/0x2c8) [] (mmc_io_rw_extended+0x0/0x1e4) [] (sdio_io_rw_ext_helper+0x0/0x1ac) [] (sdio_memcpy_fromio+0x0/0x2c) [] (wl1271_sdio_raw_read+0x0/0x1bc [wl12xx_sdio]) [] (wl1271_cmd_wait_for_event_or_timeout+0x0/0x19c [wl12xx]) [] (wl1271_cmd_wait_for_event+0x0/0x30 [wl12xx]) [] (wl1271_cmd_disconnect+0x0/0x14c [wl12xx]) [] (wl1271_unjoin+0x0/0x48 [wl12xx]) [] (wl1271_op_config+0x0/0x490 [wl12xx]) [] (ieee80211_hw_config+0x0/0x14c [mac80211]) [] (ieee80211_recalc_idle+0x0/0x4c [mac80211]) [] (__ieee80211_scan_completed+0x0/0x1ac [mac80211]) [] (ieee80211_scan_work+0x0/0x484 [mac80211]) [] (worker_thread+0x0/0x1e8) [] (kthread+0x0/0x90) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 40 +++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 357dc9d9994..26a92a5a225 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1735,7 +1735,6 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, } /* flush any remaining work */ wl1271_debug(DEBUG_MAC80211, "flushing remaining works"); - flush_delayed_work(&wl->scan_complete_work); /* * disable and re-enable interrupts in order to flush @@ -2786,6 +2785,44 @@ out: return ret; } +static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct wl1271 *wl = hw->priv; + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan"); + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) + goto out; + + if (wl->scan.state == WL1271_SCAN_STATE_IDLE) + goto out; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + if (wl->scan.state != WL1271_SCAN_STATE_DONE) { + ret = wl1271_scan_stop(wl); + if (ret < 0) + goto out_sleep; + } + wl->scan.state = WL1271_SCAN_STATE_IDLE; + memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); + wl->scan.req = NULL; + ieee80211_scan_completed(wl->hw, true); + +out_sleep: + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); + + cancel_delayed_work_sync(&wl->scan_complete_work); +} + static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, @@ -3969,6 +4006,7 @@ static const struct ieee80211_ops wl1271_ops = { .tx = wl1271_op_tx, .set_key = wl1271_op_set_key, .hw_scan = wl1271_op_hw_scan, + .cancel_hw_scan = wl1271_op_cancel_hw_scan, .sched_scan_start = wl1271_op_sched_scan_start, .sched_scan_stop = wl1271_op_sched_scan_stop, .bss_info_changed = wl1271_op_bss_info_changed, -- cgit v1.2.3-70-g09d2 From 6cfa5cffde202cabbf0d64c9225ce89f7f7a0d0f Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 27 Jun 2011 22:06:33 +0300 Subject: wl12xx: initialize max_power levels for 11a channels Set the maximum FW supported power levels for 11a channels. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 68 +++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 26a92a5a225..b381e6979b5 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3912,40 +3912,40 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = { /* 5 GHz band channels for WL1273 */ static struct ieee80211_channel wl1271_channels_5ghz[] = { - { .hw_value = 7, .center_freq = 5035}, - { .hw_value = 8, .center_freq = 5040}, - { .hw_value = 9, .center_freq = 5045}, - { .hw_value = 11, .center_freq = 5055}, - { .hw_value = 12, .center_freq = 5060}, - { .hw_value = 16, .center_freq = 5080}, - { .hw_value = 34, .center_freq = 5170}, - { .hw_value = 36, .center_freq = 5180}, - { .hw_value = 38, .center_freq = 5190}, - { .hw_value = 40, .center_freq = 5200}, - { .hw_value = 42, .center_freq = 5210}, - { .hw_value = 44, .center_freq = 5220}, - { .hw_value = 46, .center_freq = 5230}, - { .hw_value = 48, .center_freq = 5240}, - { .hw_value = 52, .center_freq = 5260}, - { .hw_value = 56, .center_freq = 5280}, - { .hw_value = 60, .center_freq = 5300}, - { .hw_value = 64, .center_freq = 5320}, - { .hw_value = 100, .center_freq = 5500}, - { .hw_value = 104, .center_freq = 5520}, - { .hw_value = 108, .center_freq = 5540}, - { .hw_value = 112, .center_freq = 5560}, - { .hw_value = 116, .center_freq = 5580}, - { .hw_value = 120, .center_freq = 5600}, - { .hw_value = 124, .center_freq = 5620}, - { .hw_value = 128, .center_freq = 5640}, - { .hw_value = 132, .center_freq = 5660}, - { .hw_value = 136, .center_freq = 5680}, - { .hw_value = 140, .center_freq = 5700}, - { .hw_value = 149, .center_freq = 5745}, - { .hw_value = 153, .center_freq = 5765}, - { .hw_value = 157, .center_freq = 5785}, - { .hw_value = 161, .center_freq = 5805}, - { .hw_value = 165, .center_freq = 5825}, + { .hw_value = 7, .center_freq = 5035, .max_power = 25 }, + { .hw_value = 8, .center_freq = 5040, .max_power = 25 }, + { .hw_value = 9, .center_freq = 5045, .max_power = 25 }, + { .hw_value = 11, .center_freq = 5055, .max_power = 25 }, + { .hw_value = 12, .center_freq = 5060, .max_power = 25 }, + { .hw_value = 16, .center_freq = 5080, .max_power = 25 }, + { .hw_value = 34, .center_freq = 5170, .max_power = 25 }, + { .hw_value = 36, .center_freq = 5180, .max_power = 25 }, + { .hw_value = 38, .center_freq = 5190, .max_power = 25 }, + { .hw_value = 40, .center_freq = 5200, .max_power = 25 }, + { .hw_value = 42, .center_freq = 5210, .max_power = 25 }, + { .hw_value = 44, .center_freq = 5220, .max_power = 25 }, + { .hw_value = 46, .center_freq = 5230, .max_power = 25 }, + { .hw_value = 48, .center_freq = 5240, .max_power = 25 }, + { .hw_value = 52, .center_freq = 5260, .max_power = 25 }, + { .hw_value = 56, .center_freq = 5280, .max_power = 25 }, + { .hw_value = 60, .center_freq = 5300, .max_power = 25 }, + { .hw_value = 64, .center_freq = 5320, .max_power = 25 }, + { .hw_value = 100, .center_freq = 5500, .max_power = 25 }, + { .hw_value = 104, .center_freq = 5520, .max_power = 25 }, + { .hw_value = 108, .center_freq = 5540, .max_power = 25 }, + { .hw_value = 112, .center_freq = 5560, .max_power = 25 }, + { .hw_value = 116, .center_freq = 5580, .max_power = 25 }, + { .hw_value = 120, .center_freq = 5600, .max_power = 25 }, + { .hw_value = 124, .center_freq = 5620, .max_power = 25 }, + { .hw_value = 128, .center_freq = 5640, .max_power = 25 }, + { .hw_value = 132, .center_freq = 5660, .max_power = 25 }, + { .hw_value = 136, .center_freq = 5680, .max_power = 25 }, + { .hw_value = 140, .center_freq = 5700, .max_power = 25 }, + { .hw_value = 149, .center_freq = 5745, .max_power = 25 }, + { .hw_value = 153, .center_freq = 5765, .max_power = 25 }, + { .hw_value = 157, .center_freq = 5785, .max_power = 25 }, + { .hw_value = 161, .center_freq = 5805, .max_power = 25 }, + { .hw_value = 165, .center_freq = 5825, .max_power = 25 }, }; /* mapping to indexes for wl1271_rates_5ghz */ -- cgit v1.2.3-70-g09d2 From 097f882153f0ec13617074fa3bdb683b8215e20c Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 27 Jun 2011 22:06:34 +0300 Subject: wl12xx: always initialize AP-mode max power level Sometimes we only get the Tx power level via op->config when the FW is off. Record the received power level when this happens and use it to initialize the firmware during boot. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 2 +- drivers/net/wireless/wl12xx/init.c | 5 +++++ drivers/net/wireless/wl12xx/main.c | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 2f5207ae7cf..7e33f1f4f3d 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -90,7 +90,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power) struct acx_current_tx_power *acx; int ret; - wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr"); + wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr %d", power); if (power < 0 || power > 25) return -EINVAL; diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index ebfde942bec..c3e9a2e4410 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -455,6 +455,11 @@ static int wl1271_ap_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + /* initialize Tx power */ + ret = wl1271_acx_tx_power(wl, wl->power_level); + if (ret < 0) + return ret; + return 0; } diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index b381e6979b5..526b1ac2dd8 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2278,6 +2278,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) wl->channel = channel; } + if ((changed & IEEE80211_CONF_CHANGE_POWER)) + wl->power_level = conf->power_level; + goto out; } -- cgit v1.2.3-70-g09d2 From 85ee5122abbc1b5c5f3622e46942291a2f6f1261 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 30 Jun 2011 20:27:47 +0200 Subject: carl9170: import 1.9.4 firmware headers This patch imports all shared header changes from carl9170fw.git. * update copyright boilerplate * add some more strategic __aligned(4). * WoWLAN Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 2 ++ drivers/net/wireless/ath/carl9170/fwcmd.h | 19 ++++++++++++++++++- drivers/net/wireless/ath/carl9170/fwdesc.h | 18 ++++++++++++++++-- drivers/net/wireless/ath/carl9170/hw.h | 15 +++++++++++++-- drivers/net/wireless/ath/carl9170/version.h | 6 +++--- drivers/net/wireless/ath/carl9170/wlan.h | 25 +++++++++++-------------- 6 files changed, 63 insertions(+), 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 4da01a9f568..d96d03ff120 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -67,6 +67,8 @@ #define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1) +static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 }; + enum carl9170_rf_init_mode { CARL9170_RFI_NONE, CARL9170_RFI_WARM, diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h index 30449d21b76..0a6dec529b5 100644 --- a/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -4,7 +4,7 @@ * Firmware command interface definitions * * Copyright 2008, Johannes Berg - * Copyright 2009, 2010, Christian Lamparter + * Copyright 2009-2011 Christian Lamparter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,6 +54,7 @@ enum carl9170_cmd_oids { CARL9170_CMD_BCN_CTRL = 0x05, CARL9170_CMD_READ_TSF = 0x06, CARL9170_CMD_RX_FILTER = 0x07, + CARL9170_CMD_WOL = 0x08, /* CAM */ CARL9170_CMD_EKEY = 0x10, @@ -180,6 +181,21 @@ struct carl9170_bcn_ctrl_cmd { #define CARL9170_BCN_CTRL_DRAIN 0 #define CARL9170_BCN_CTRL_CAB_TRIGGER 1 +struct carl9170_wol_cmd { + __le32 flags; + u8 mac[6]; + u8 bssid[6]; + __le32 null_interval; + __le32 free_for_use2; + __le32 mask; + u8 pattern[32]; +} __packed; + +#define CARL9170_WOL_CMD_SIZE 60 + +#define CARL9170_WOL_DISCONNECT 1 +#define CARL9170_WOL_MAGIC_PKT 2 + struct carl9170_cmd_head { union { struct { @@ -203,6 +219,7 @@ struct carl9170_cmd { struct carl9170_write_reg wreg; struct carl9170_rf_init rf_init; struct carl9170_psm psm; + struct carl9170_wol_cmd wol; struct carl9170_bcn_ctrl_cmd bcn_ctrl; struct carl9170_rx_filter_cmd rx_filter; u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h index 921066822dd..7ba62bb7705 100644 --- a/drivers/net/wireless/ath/carl9170/fwdesc.h +++ b/drivers/net/wireless/ath/carl9170/fwdesc.h @@ -3,7 +3,7 @@ * * Firmware descriptor format * - * Copyright 2009, 2010, Christian Lamparter + * Copyright 2009-2011 Christian Lamparter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,6 +72,9 @@ enum carl9170fw_feature_list { /* Wake up on WLAN */ CARL9170FW_WOL, + /* Firmware supports PSM in the 5GHZ Band */ + CARL9170FW_FIXED_5GHZ_PSM, + /* KEEP LAST */ __CARL9170FW_FEATURE_NUM }; @@ -82,6 +85,7 @@ enum carl9170fw_feature_list { #define DBG_MAGIC "DBG\0" #define CHK_MAGIC "CHK\0" #define TXSQ_MAGIC "TXSQ" +#define WOL_MAGIC "WOL\0" #define LAST_MAGIC "LAST" #define CARL9170FW_SET_DAY(d) (((d) - 1) % 31) @@ -104,7 +108,7 @@ struct carl9170fw_desc_head { (sizeof(struct carl9170fw_desc_head)) #define CARL9170FW_OTUS_DESC_MIN_VER 6 -#define CARL9170FW_OTUS_DESC_CUR_VER 6 +#define CARL9170FW_OTUS_DESC_CUR_VER 7 struct carl9170fw_otus_desc { struct carl9170fw_desc_head head; __le32 feature_set; @@ -186,6 +190,16 @@ struct carl9170fw_txsq_desc { #define CARL9170FW_TXSQ_DESC_SIZE \ (sizeof(struct carl9170fw_txsq_desc)) +#define CARL9170FW_WOL_DESC_MIN_VER 1 +#define CARL9170FW_WOL_DESC_CUR_VER 1 +struct carl9170fw_wol_desc { + struct carl9170fw_desc_head head; + + __le32 supported_triggers; /* CARL9170_WOL_ */ +} __packed; +#define CARL9170FW_WOL_DESC_SIZE \ + (sizeof(struct carl9170fw_wol_desc)) + #define CARL9170FW_LAST_DESC_MIN_VER 1 #define CARL9170FW_LAST_DESC_CUR_VER 2 struct carl9170fw_last_desc { diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h index 4e30762dd90..261f8935107 100644 --- a/drivers/net/wireless/ath/carl9170/hw.h +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -4,7 +4,7 @@ * Register map, hardware-specific definitions * * Copyright 2008, Johannes Berg - * Copyright 2009, 2010, Christian Lamparter + * Copyright 2009-2011 Christian Lamparter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -357,7 +357,18 @@ #define AR9170_MAC_REG_DMA_WLAN_STATUS (AR9170_MAC_REG_BASE + 0xd38) #define AR9170_MAC_REG_DMA_STATUS (AR9170_MAC_REG_BASE + 0xd3c) - +#define AR9170_MAC_REG_DMA_TXQ_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd40) +#define AR9170_MAC_REG_DMA_TXQ0_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd40) +#define AR9170_MAC_REG_DMA_TXQ1_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd44) +#define AR9170_MAC_REG_DMA_TXQ2_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd48) +#define AR9170_MAC_REG_DMA_TXQ3_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd4c) +#define AR9170_MAC_REG_DMA_TXQ4_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd50) +#define AR9170_MAC_REG_DMA_TXQ0Q1_LEN (AR9170_MAC_REG_BASE + 0xd54) +#define AR9170_MAC_REG_DMA_TXQ2Q3_LEN (AR9170_MAC_REG_BASE + 0xd58) +#define AR9170_MAC_REG_DMA_TXQ4_LEN (AR9170_MAC_REG_BASE + 0xd5c) + +#define AR9170_MAC_REG_DMA_TXQX_LAST_ADDR (AR9170_MAC_REG_BASE + 0xd74) +#define AR9170_MAC_REG_DMA_TXQX_FAIL_ADDR (AR9170_MAC_REG_BASE + 0xd78) #define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xd7c) #define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f #define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0 diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h index 15095c03516..64703778cfe 100644 --- a/drivers/net/wireless/ath/carl9170/version.h +++ b/drivers/net/wireless/ath/carl9170/version.h @@ -1,7 +1,7 @@ #ifndef __CARL9170_SHARED_VERSION_H #define __CARL9170_SHARED_VERSION_H #define CARL9170FW_VERSION_YEAR 11 -#define CARL9170FW_VERSION_MONTH 1 -#define CARL9170FW_VERSION_DAY 22 -#define CARL9170FW_VERSION_GIT "1.9.2" +#define CARL9170FW_VERSION_MONTH 6 +#define CARL9170FW_VERSION_DAY 30 +#define CARL9170FW_VERSION_GIT "1.9.4" #endif /* __CARL9170_SHARED_VERSION_H */ diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h index 9e1324b67e0..ea17995b32f 100644 --- a/drivers/net/wireless/ath/carl9170/wlan.h +++ b/drivers/net/wireless/ath/carl9170/wlan.h @@ -4,7 +4,7 @@ * RX/TX meta descriptor format * * Copyright 2008, Johannes Berg - * Copyright 2009, 2010, Christian Lamparter + * Copyright 2009-2011 Christian Lamparter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -278,7 +278,7 @@ struct ar9170_tx_frame { struct carl9170_tx_superframe { struct carl9170_tx_superdesc s; struct ar9170_tx_frame f; -} __packed; +} __packed __aligned(4); #endif /* __CARL9170FW__ */ @@ -328,7 +328,7 @@ struct _carl9170_tx_superframe { struct _carl9170_tx_superdesc s; struct _ar9170_tx_hwdesc f; u8 frame_data[0]; -} __packed; +} __packed __aligned(4); #define CARL9170_TX_SUPERDESC_LEN 24 #define AR9170_TX_HWDESC_LEN 8 @@ -404,16 +404,6 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) (t->DAidx & 0xc0) >> 6; } -enum ar9170_txq { - AR9170_TXQ_BE, - - AR9170_TXQ_VI, - AR9170_TXQ_VO, - AR9170_TXQ_BK, - - __AR9170_NUM_TXQ, -}; - /* * This is an workaround for several undocumented bugs. * Don't mess with the QoS/AC <-> HW Queue map, if you don't @@ -431,7 +421,14 @@ enum ar9170_txq { * result, this makes the device pretty much useless * for any serious 802.11n setup. */ -static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 2, 1, 0, 3 }; +enum ar9170_txq { + AR9170_TXQ_BK = 0, /* TXQ0 */ + AR9170_TXQ_BE, /* TXQ1 */ + AR9170_TXQ_VI, /* TXQ2 */ + AR9170_TXQ_VO, /* TXQ3 */ + + __AR9170_NUM_TXQ, +}; #define AR9170_TXQ_DEPTH 32 -- cgit v1.2.3-70-g09d2 From f3716fd7494ce5e2af3c6251275d989bfec98906 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 30 Jun 2011 20:31:34 +0200 Subject: carl9170: enable IEEE80211_HW_NEED_DTIM_PERIOD Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 54d093c2ab4..06b9d49a9a7 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1577,6 +1577,7 @@ void *carl9170_alloc(size_t priv_size) IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SIGNAL_DBM; if (!modparam_noht) { -- cgit v1.2.3-70-g09d2 From 1205f5438f5a9a2dad3a29aa1c015e7bbd3b2b2b Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 30 Jun 2011 20:34:54 +0200 Subject: carl9170: allow PSM if the 5 GHz band is selected Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 - drivers/net/wireless/ath/carl9170/fw.c | 2 +- drivers/net/wireless/ath/carl9170/phy.c | 6 ------ 3 files changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index d96d03ff120..f9a4655ea0b 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -442,7 +442,6 @@ struct ar9170 { enum carl9170_ps_off_override_reasons { PS_OFF_VIF = BIT(0), PS_OFF_BCN = BIT(1), - PS_OFF_5GHZ = BIT(2), }; struct carl9170_ba_stats { diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 221957c5d37..39ddea5794f 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -237,7 +237,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) ar->disable_offload = true; } - if (SUPP(CARL9170FW_PSM)) + if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM)) ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS; if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) { diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index b6ae0e179c8..da1ab962ee4 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1783,12 +1783,6 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, } } - /* FIXME: PSM does not work in 5GHz Band */ - if (channel->band == IEEE80211_BAND_5GHZ) - ar->ps.off_override |= PS_OFF_5GHZ; - else - ar->ps.off_override &= ~PS_OFF_5GHZ; - ar->channel = channel; ar->ht_settings = new_ht; return 0; -- cgit v1.2.3-70-g09d2 From faeef8acb18f80abb826f314cfac381c6fcf7a34 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 30 Jun 2011 16:28:50 -0500 Subject: drivers/net/wireless/rtlwifi/rtl8192de/phy.c: fix udelay() usage ERROR: "__bad_udelay" [drivers/net/wireless/rtlwifi/rtl8192de/rtl8192de.ko] undefined! Signed-off-by: Andrew Morton Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 97fb6ca39d7..53f62215005 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -1684,7 +1684,7 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME)); - udelay(IQK_DELAY_TIME * 1000); + mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); @@ -1755,7 +1755,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME)); - udelay(IQK_DELAY_TIME * 1000 * 10); + mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); @@ -1808,7 +1808,7 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Delay %d ms for One shot, path B LOK & IQK.\n", IQK_DELAY_TIME)); - udelay(IQK_DELAY_TIME * 1000); + mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); @@ -1875,7 +1875,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Delay %d ms for One shot, path B LOK & IQK.\n", 10)); - udelay(IQK_DELAY_TIME * 1000 * 10); + mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); @@ -2206,7 +2206,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, * PHY_REG.txt , and radio_a, radio_b.txt */ RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n")); - udelay(IQK_DELAY_TIME * 1000 * 20); + mdelay(IQK_DELAY_TIME * 20); if (t == 0) { bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); -- cgit v1.2.3-70-g09d2 From 80b69593a8dff5266155f33f9c033f670ee55323 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 30 Jun 2011 16:44:47 -0500 Subject: rtlwifi: rtl8192de: Remove irq_enabled boolean Prepare rtl8192de for the removal of irq_enaqbled. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index e833bbf92c5..270571a1971 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1221,7 +1221,6 @@ void rtl92de_enable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); - rtlpci->irq_enabled = true; } void rtl92de_disable_interrupt(struct ieee80211_hw *hw) @@ -1231,7 +1230,6 @@ void rtl92de_disable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); - rtlpci->irq_enabled = false; synchronize_irq(rtlpci->pdev->irq); } -- cgit v1.2.3-70-g09d2 From f2e795ffae1c4127277ce25727d5ac097f91238c Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 30 Jun 2011 16:46:14 -0500 Subject: rtlwifi: rtl8192{ce,cu,se} Remove irq_enabled This should be unnecessary if synchronize_irq is used. Signed-off-by: Mike McCormack Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 4 ---- drivers/net/wireless/rtlwifi/pci.h | 1 - drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 9 --------- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 3 --- 5 files changed, 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 532c7d38dae..5efd5783348 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -788,15 +788,11 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) { struct ieee80211_hw *hw = dev_id; struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); unsigned long flags; u32 inta = 0; u32 intb = 0; - if (rtlpci->irq_enabled == 0) - return IRQ_HANDLED; - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); /*read ISR: 4/8bytes */ diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index a50e5513256..c53c6204674 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -158,7 +158,6 @@ struct rtl_pci { bool first_init; bool being_init_adapter; bool init_ready; - bool irq_enabled; /*Tx */ struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT]; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index bc6ae9dcf94..9e2a9e34a69 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1183,7 +1183,6 @@ void rtl92ce_enable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); - rtlpci->irq_enabled = true; } void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) @@ -1193,7 +1192,6 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); - rtlpci->irq_enabled = false; synchronize_irq(rtlpci->pdev->irq); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 4e057df6f48..a90c09b4239 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -380,13 +380,11 @@ void rtl92c_enable_interrupt(struct ieee80211_hw *hw) 0xFFFFFFFF); rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); - rtlpci->irq_enabled = true; } else { rtl_write_dword(rtlpriv, REG_HIMR, rtlusb->irq_mask[0] & 0xFFFFFFFF); rtl_write_dword(rtlpriv, REG_HIMRE, rtlusb->irq_mask[1] & 0xFFFFFFFF); - rtlusb->irq_enabled = true; } } @@ -398,16 +396,9 @@ void rtl92c_init_interrupt(struct ieee80211_hw *hw) void rtl92c_disable_interrupt(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); - if (IS_HARDWARE_TYPE_8192CE(rtlhal)) - rtlpci->irq_enabled = false; - else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) - rtlusb->irq_enabled = false; } void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 13da7b3c020..b1d0213dc60 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1214,8 +1214,6 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]); /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */ rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F); - - rtlpci->irq_enabled = true; } void rtl92se_disable_interrupt(struct ieee80211_hw *hw) @@ -1226,7 +1224,6 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, INTA_MASK, 0); rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); - rtlpci->irq_enabled = false; synchronize_irq(rtlpci->pdev->irq); } -- cgit v1.2.3-70-g09d2 From 9928c7d1b1c5e3dcba04a10c7014c9f3319b1fbc Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 30 Jun 2011 16:47:11 -0500 Subject: rtlwifi: rtl8192de: Remove comparison of boolean with true Tests of a boolean against "true" are not needed as non-zero is sufficient.. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 10 +++++----- drivers/net/wireless/rtlwifi/rtl8192de/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 16 ++++++++-------- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 270571a1971..5c84131f62e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -449,7 +449,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_CORRECT_TSF: { u8 btype_ibss = ((u8 *) (val))[0]; - if (btype_ibss == true) + if (btype_ibss) _rtl92de_stop_tx_beacon(hw); _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3)); rtl_write_dword(rtlpriv, REG_TSFTR, @@ -457,7 +457,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_dword(rtlpriv, REG_TSFTR + 4, (u32) ((mac->tsf >> 32) & 0xffffffff)); _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0); - if (btype_ibss == true) + if (btype_ibss) _rtl92de_resume_tx_beacon(hw); break; @@ -1142,7 +1142,7 @@ void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (check_bssid == true) { + if (check_bssid) { reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); @@ -1785,7 +1785,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); rtlefuse->autoload_failflag = false; } - if (rtlefuse->autoload_failflag == true) { + if (rtlefuse->autoload_failflag) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("RTL819X Not boot from eeprom, check it !!")); return; @@ -2147,7 +2147,7 @@ bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) REG_MAC_PINMUX_CFG) & ~(BIT(3))); u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; - if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { + if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("GPIOChangeRF - HW Radio ON, RF ON\n")); e_rfpowerstate_toset = ERFON; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c index 719972c16fc..f1552f4df65 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -93,7 +93,7 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (pcipriv->ledctl.led_opendrain == true) + if (pcipriv->ledctl.led_opendrain) rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(1) | BIT(5) | BIT(6))); else diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index c326372220f..db27cebaac2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -87,7 +87,7 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, if (rtlefuse->eeprom_regulatory != 0) turbo_scanoff = true; - if (mac->act_scanning == true) { + if (mac->act_scanning) { tx_agc[RF90_PATH_A] = 0x3f3f3f3f; tx_agc[RF90_PATH_B] = 0x3f3f3f3f; if (turbo_scanoff) { @@ -416,9 +416,9 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); u8 u1btmp; - u8 direct = bmac0 == true ? BIT(3) | BIT(2) : BIT(3); - u8 mac_reg = bmac0 == true ? REG_MAC1 : REG_MAC0; - u8 mac_on_bit = bmac0 == true ? MAC1_ON : MAC0_ON; + u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3); + u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; + u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; bool bresult = true; /* true: need to enable BB/RF power */ rtlhal->during_mac0init_radiob = false; @@ -447,9 +447,9 @@ void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); u8 u1btmp; - u8 direct = bmac0 == true ? BIT(3) | BIT(2) : BIT(3); - u8 mac_reg = bmac0 == true ? REG_MAC1 : REG_MAC0; - u8 mac_on_bit = bmac0 == true ? MAC1_ON : MAC0_ON; + u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3); + u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; + u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; rtlhal->during_mac0init_radiob = false; rtlhal->during_mac1init_radioa = false; @@ -573,7 +573,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) udelay(1); switch (rfpath) { case RF90_PATH_A: - if (true_bpath == true) + if (true_bpath) rtstatus = rtl92d_phy_config_rf_with_headerfile( hw, radiob_txt, (enum radio_path)rfpath); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index bf1462f69b5..dc86fcb0b3a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -614,7 +614,7 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, (u8) GET_RX_DESC_RXMCS(pdesc)); rx_status->mactime = GET_RX_DESC_TSFL(pdesc); - if (phystatus == true) { + if (phystatus) { p_drvinfo = (struct rx_fwinfo_92d *)(skb->data + stats->rx_bufshift); _rtl92de_translate_rx_signal_stuff(hw, @@ -876,7 +876,7 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) { - if (istx == true) { + if (istx) { switch (desc_name) { case HW_DESC_OWN: wmb(); @@ -917,7 +917,7 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) { u32 ret = 0; - if (istx == true) { + if (istx) { switch (desc_name) { case HW_DESC_OWN: ret = GET_TX_DESC_OWN(p_desc); -- cgit v1.2.3-70-g09d2 From c2a7965f528244bc35f41ca64592132c7b3c2515 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 1 Jul 2011 15:28:22 +0200 Subject: carl9170: use carl9170 queue enums Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 06b9d49a9a7..d2b9f1256bc 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -345,11 +345,11 @@ static int carl9170_op_start(struct ieee80211_hw *hw) carl9170_zap_queues(ar); /* reset QoS defaults */ - CARL9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT */ - CARL9170_FILL_QUEUE(ar->edcf[1], 2, 7, 15, 94); /* VIDEO */ - CARL9170_FILL_QUEUE(ar->edcf[2], 2, 3, 7, 47); /* VOICE */ - CARL9170_FILL_QUEUE(ar->edcf[3], 7, 15, 1023, 0); /* BACKGROUND */ - CARL9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ + CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_VO], 2, 3, 7, 47); + CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_VI], 2, 7, 15, 94); + CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_BE], 3, 15, 1023, 0); + CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_BK], 7, 15, 1023, 0); + CARL9170_FILL_QUEUE(ar->edcf[AR9170_TXQ_SPECIAL], 2, 3, 7, 0); ar->current_factor = ar->current_density = -1; /* "The first key is unique." */ -- cgit v1.2.3-70-g09d2 From eb8b27ada953f8de182e628d71feff797707768a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 1 Jul 2011 08:50:48 -0500 Subject: rtlwifi: rtl8192de: Replace loops calling udelay with single mdelay There are a number of loops to implement delays. These are replaced with single calls to mdelay(). The need for a fix was noted by Andrew Morton . Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 53f62215005..3ac7af1c550 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -932,7 +932,7 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum rf_content content, enum radio_path rfpath) { - int i, j; + int i; u32 *radioa_array_table; u32 *radiob_array_table; u16 radioa_arraylen, radiob_arraylen; @@ -974,13 +974,10 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, mdelay(50); } else if (radioa_array_table[i] == 0xfd) { /* delay_ms(5); */ - for (j = 0; j < 100; j++) - udelay(MAX_STALL_TIME); + mdelay(5); } else if (radioa_array_table[i] == 0xfc) { /* delay_ms(1); */ - for (j = 0; j < 20; j++) - udelay(MAX_STALL_TIME); - + mdelay(1); } else if (radioa_array_table[i] == 0xfb) { udelay(50); } else if (radioa_array_table[i] == 0xfa) { @@ -1004,12 +1001,10 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, mdelay(50); } else if (radiob_array_table[i] == 0xfd) { /* delay_ms(5); */ - for (j = 0; j < 100; j++) - udelay(MAX_STALL_TIME); + mdelay(5); } else if (radiob_array_table[i] == 0xfc) { /* delay_ms(1); */ - for (j = 0; j < 20; j++) - udelay(MAX_STALL_TIME); + mdelay(1); } else if (radiob_array_table[i] == 0xfb) { udelay(50); } else if (radiob_array_table[i] == 0xfa) { @@ -1276,7 +1271,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 i, value8; + u8 value8; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); rtlhal->bandset = band; @@ -1321,8 +1316,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) rtl_write_byte(rtlpriv, (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1), value8); } - for (i = 0; i < 20; i++) - udelay(MAX_STALL_TIME); + mdelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n")); } -- cgit v1.2.3-70-g09d2 From 45a771385ceb644941b195f37ab98f7db39776bd Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 1 Jul 2011 08:56:11 -0500 Subject: rtlwifi: rtl8192de: Fix error exit from hw_init In routine rtl92de_hw_init(), there are two places where a failure is not handled correctly. Reported-by: Dan Carpenter Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 5c84131f62e..5a65bea4cb8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -932,8 +932,8 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Failed to download FW. Init HW " "without FW..\n")); - err = 1; rtlhal->fw_ready = false; + return 1; } else { rtlhal->fw_ready = true; } @@ -1044,6 +1044,11 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) if (((tmp_rega & BIT(11)) == BIT(11))) break; } + /* check that loop was successful. If not, exit now */ + if (i == 10000) { + rtlpci->init_ready = false; + return 1; + } } } rtlpci->init_ready = true; -- cgit v1.2.3-70-g09d2 From 73e6cdcf479ce3a8d33a726f0477473db35a4b2e Mon Sep 17 00:00:00 2001 From: Michael Büsch Date: Mon, 4 Jul 2011 19:51:11 +0200 Subject: b43: Add RX side DMA memory barrier This adds a memory barrier to ensure the writes to the ring memory are committed before the DMA ring pointer is updated. We do a similar thing on the TX side already. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/dma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index d02cf8300e3..7a09a467339 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1600,6 +1600,7 @@ void b43_dma_rx(struct b43_dmaring *ring) dma_rx(ring, &slot); update_max_used_slots(ring, ++used_slots); } + wmb(); ops->set_current_rxslot(ring, slot); ring->current_slot = slot; } -- cgit v1.2.3-70-g09d2 From 7329f0d58de01878d9ce4f0be7a76e136f223eef Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 5 Jul 2011 07:43:46 +0000 Subject: b44: Use pr__once and DRV_DESCRIPTION Convert a printk with a static to pr__once Add and use DRV_DESCRIPTION to reduce string duplication. Remove now unused version. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/b44.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 98c977ed9ad..6c4ef966ca5 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -39,6 +39,7 @@ #define DRV_MODULE_NAME "b44" #define DRV_MODULE_VERSION "2.0" +#define DRV_DESCRIPTION "Broadcom 44xx/47xx 10/100 PCI ethernet driver" #define B44_DEF_MSG_ENABLE \ (NETIF_MSG_DRV | \ @@ -91,11 +92,8 @@ #define B44_ETHIPV6UDP_HLEN 62 #define B44_ETHIPV4UDP_HLEN 42 -static char version[] __devinitdata = - DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION "\n"; - MODULE_AUTHOR("Felix Fietkau, Florian Schirmer, Pekka Pietikainen, David S. Miller"); -MODULE_DESCRIPTION("Broadcom 44xx/47xx 10/100 PCI ethernet driver"); +MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); @@ -2130,16 +2128,13 @@ static const struct net_device_ops b44_netdev_ops = { static int __devinit b44_init_one(struct ssb_device *sdev, const struct ssb_device_id *ent) { - static int b44_version_printed = 0; struct net_device *dev; struct b44 *bp; int err; instance++; - if (b44_version_printed++ == 0) - pr_info("%s", version); - + pr_info_once("%s version %s\n", DRV_DESCRIPTION, DRV_MODULE_VERSION); dev = alloc_etherdev(sizeof(*bp)); if (!dev) { @@ -2225,8 +2220,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev, if (b44_phy_reset(bp) < 0) bp->phy_addr = B44_PHY_ADDR_NO_PHY; - netdev_info(dev, "Broadcom 44xx/47xx 10/100BaseT Ethernet %pM\n", - dev->dev_addr); + netdev_info(dev, "%s %pM\n", DRV_DESCRIPTION, dev->dev_addr); return 0; -- cgit v1.2.3-70-g09d2 From 3600cdadb7ab9ee5f4e73ed01242c3e8b8e3282c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2011 23:49:03 -0700 Subject: veth: Kill unused code label and code block. Signed-off-by: David S. Miller --- drivers/net/veth.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 9eb92bfa92a..19e0b0c72f4 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -148,13 +148,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; -tx_drop: - kfree_skb(skb); - u64_stats_update_begin(&stats->syncp); - stats->tx_dropped++; - u64_stats_update_end(&stats->syncp); - return NETDEV_TX_OK; - rx_drop: u64_stats_update_begin(&rcv_stats->syncp); rcv_stats->rx_dropped++; -- cgit v1.2.3-70-g09d2 From 81b16ba2f1cc93a1ee1dda48be2ea2d91a0cb72e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 6 Jul 2011 01:51:04 -0700 Subject: veth: Kill unused tx_dropped Followup to commit f82528bc13a (Exclude duplicated checking for iface-up) : We no longer need percpu tx_dropped field. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/veth.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 19e0b0c72f4..7f78db7bd68 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -30,7 +30,6 @@ struct veth_net_stats { u64 rx_bytes; u64 tx_bytes; u64 rx_dropped; - u64 tx_dropped; struct u64_stats_sync syncp; }; @@ -168,7 +167,7 @@ static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev, for_each_possible_cpu(cpu) { struct veth_net_stats *stats = per_cpu_ptr(priv->stats, cpu); u64 rx_packets, rx_bytes, rx_dropped; - u64 tx_packets, tx_bytes, tx_dropped; + u64 tx_packets, tx_bytes; unsigned int start; do { @@ -178,14 +177,12 @@ static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev, rx_bytes = stats->rx_bytes; tx_bytes = stats->tx_bytes; rx_dropped = stats->rx_dropped; - tx_dropped = stats->tx_dropped; } while (u64_stats_fetch_retry_bh(&stats->syncp, start)); tot->rx_packets += rx_packets; tot->tx_packets += tx_packets; tot->rx_bytes += rx_bytes; tot->tx_bytes += tx_bytes; tot->rx_dropped += rx_dropped; - tot->tx_dropped += tx_dropped; } return tot; -- cgit v1.2.3-70-g09d2 From 68dd49ef907f92127aabb30b3368b80eb0ffb459 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 30 Jun 2011 10:42:47 -0500 Subject: iwlwifi: remove unnecessary read of PCI_CAP_ID_EXP The PCIE capability offset is saved during PCI bus walking. It will remove an unnecessary search in the PCI configuration space if this value is referenced instead of reacquiring it. Signed-off-by: Jon Mason Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 2c26b42bd15..74911348a2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -94,7 +94,7 @@ static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) u16 pci_lnk_ctl; struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - pos = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); + pos = pci_pcie_cap(pci_dev); pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); return pci_lnk_ctl; } -- cgit v1.2.3-70-g09d2 From 96a95c1abb8235ed26f5915511ce30fbb42de8dd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 6 Jul 2011 00:27:06 +0200 Subject: ipw2100: Fix command list for debugging There is a stray "undefined" string in the array, get rid of it. Signed-off-by: Jean Delvare Cc: "John W. Linville" Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 44307753587..3774dd03474 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -287,7 +287,7 @@ static const char *command_types[] = { "unused", /* HOST_INTERRUPT_COALESCING */ "undefined", "CARD_DISABLE_PHY_OFF", - "MSDU_TX_RATES" "undefined", + "MSDU_TX_RATES", "undefined", "SET_STATION_STAT_BITS", "CLEAR_STATIONS_STAT_BITS", -- cgit v1.2.3-70-g09d2 From f0c717e6b7ac032e89611fa7629a1fff57e7667a Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 5 Jul 2011 18:01:11 -0700 Subject: mwifiex: modify SDIO aggregation Tx/Rx buffer size The SDIO aggregation buffer size has been modified to an optimum value which gives good throughput results. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sdio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index c925376fcaa..524f78f4ee6 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h @@ -54,10 +54,10 @@ #define SDIO_MP_AGGR_DEF_PKT_LIMIT 8 -#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (4096) /* 4K */ +#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (8192) /* 8K */ /* Multi port RX aggregation buffer size */ -#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (4096) /* 4K */ +#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (16384) /* 16K */ /* Misc. Config Register : Auto Re-enable interrupts */ #define AUTO_RE_ENABLE_INT BIT(4) -- cgit v1.2.3-70-g09d2 From fa917ff739eace9e1e1c214bd067a7a0f7bc264b Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Thu, 7 Jul 2011 00:26:31 -0700 Subject: net: fix warning of versioncheck net-next-2.6/drivers/net/bnx2x/bnx2x_sp.c: 19 linux/version.h not needed. net-next-2.6/drivers/net/caif/caif_hsi.c: 9 linux/version.h not needed. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_sp.c | 1 - drivers/net/caif/caif_hsi.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index 5bdf09459a0..f6322a15ed4 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -16,7 +16,6 @@ * Written by: Vladislav Zolotarov * */ -#include #include #include #include diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 016108a3b1c..b41c2fced0a 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -6,7 +6,6 @@ * License terms: GNU General Public License (GPL) version 2. */ -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 6f7d32f41e5123cb3bbe8c8ce2df912d7a1e1537 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Jul 2011 19:00:05 +0000 Subject: skge: cleanup pci id table The PCI table was using mix of defines for device id and hard coded hex values. This patch change it to all hex values. It also adds comments based on the names provided in the vendor driver table. There is NO CHANGE to the actual resulting table. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/skge.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/skge.c b/drivers/net/skge.c index f4be5c78ebf..4042d87a266 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -83,17 +83,16 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); static DEFINE_PCI_DEVICE_TABLE(skge_id_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) }, - { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, - { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, - { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T) }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, /* DGE-530T */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ - { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, - { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, - { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015 }, + { PCI_DEVICE(PCI_VENDOR_ID_3COM, 0x1700) }, /* 3Com 3C940 */ + { PCI_DEVICE(PCI_VENDOR_ID_3COM, 0x80EB) }, /* 3Com 3C940B */ + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x4320) }, /* SK-98xx V2.0 */ + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, /* D-Link DGE-530T (rev.B) */ + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4c00) }, /* D-Link DGE-530T */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, /* Marvell Yukon 88E8001/8003/8010 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ + { PCI_DEVICE(PCI_VENDOR_ID_CNET, 0x434E) }, /* CNet PowerG-2000 */ + { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, 0x1064) }, /* Linksys EG1064 v2 */ + { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015 }, /* Linksys EG1032 v2 */ { 0 } }; MODULE_DEVICE_TABLE(pci, skge_id_table); -- cgit v1.2.3-70-g09d2 From c074304c2bcf4b45e2b7ff86011beaa035ee52fd Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Jul 2011 19:00:06 +0000 Subject: add pci-id for DGE-530T See also: https://bugzilla.kernel.org/show_bug.cgi?id=38862 Reported-by: jameshenderson@ruggedcom.com Signed-off-by: David S. Miller --- drivers/net/skge.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 4042d87a266..e53e6a4e08a 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -88,6 +88,7 @@ static DEFINE_PCI_DEVICE_TABLE(skge_id_table) = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x4320) }, /* SK-98xx V2.0 */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, /* D-Link DGE-530T (rev.B) */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4c00) }, /* D-Link DGE-530T */ + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302) }, /* D-Link DGE-530T Rev C1 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, /* Marvell Yukon 88E8001/8003/8010 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ { PCI_DEVICE(PCI_VENDOR_ID_CNET, 0x434E) }, /* CNet PowerG-2000 */ -- cgit v1.2.3-70-g09d2 From 57d6fa37f56ca594a1becaf5b8774382ddb7d720 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Jul 2011 19:00:07 +0000 Subject: skge: make support for old Genesis chips optional The GENESIS boards are really old PCI-X boards that are rare. Marvell has dropped support for this hardware and there is no reason for most users to have to have this code. Rather than riddling code with ifdef's make one macro and let the compiler do the dead code elimination. This saves about 15% of the text size. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/Kconfig | 9 ++++++ drivers/net/skge.c | 79 +++++++++++++++++++++++++++++++---------------------- 2 files changed, 56 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4d68a264df9..b1e67d68349 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2303,6 +2303,15 @@ config SKGE_DEBUG If unsure, say N. +config SKGE_GENESIS + bool "Support for older SysKonnect Genesis boards" + depends on SKGE + help + This enables support for the older and uncommon SysKonnect Genesis + chips, which support MII via an external transceiver, instead of + an internal one. Disabling this option will save some memory + by making code smaller. If unsure say Y. + config SKY2 tristate "SysKonnect Yukon2 support" depends on PCI diff --git a/drivers/net/skge.c b/drivers/net/skge.c index e53e6a4e08a..4495e249149 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -85,6 +85,9 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); static DEFINE_PCI_DEVICE_TABLE(skge_id_table) = { { PCI_DEVICE(PCI_VENDOR_ID_3COM, 0x1700) }, /* 3Com 3C940 */ { PCI_DEVICE(PCI_VENDOR_ID_3COM, 0x80EB) }, /* 3Com 3C940B */ +#ifdef CONFIG_SKGE_GENESIS + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x4300) }, /* SK-9xx */ +#endif { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x4320) }, /* SK-98xx V2.0 */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, /* D-Link DGE-530T (rev.B) */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4c00) }, /* D-Link DGE-530T */ @@ -119,6 +122,15 @@ static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; static const u32 napimask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F }; static const u32 portmask[] = { IS_PORT_1, IS_PORT_2 }; +static inline bool is_genesis(const struct skge_hw *hw) +{ +#ifdef CONFIG_SKGE_GENESIS + return hw->chip_id == CHIP_ID_GENESIS; +#else + return false; +#endif +} + static int skge_get_regs_len(struct net_device *dev) { return 0x4000; @@ -146,7 +158,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, /* Wake on Lan only supported on Yukon chips with rev 1 or above */ static u32 wol_supported(const struct skge_hw *hw) { - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) return 0; if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) @@ -270,7 +282,7 @@ static u32 skge_supported_modes(const struct skge_hw *hw) SUPPORTED_Autoneg | SUPPORTED_TP); - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) supported &= ~(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | @@ -433,7 +445,7 @@ static void skge_get_ethtool_stats(struct net_device *dev, { struct skge_port *skge = netdev_priv(dev); - if (skge->hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(skge->hw)) genesis_get_stats(skge, data); else yukon_get_stats(skge, data); @@ -448,7 +460,7 @@ static struct net_device_stats *skge_get_stats(struct net_device *dev) struct skge_port *skge = netdev_priv(dev); u64 data[ARRAY_SIZE(skge_stats)]; - if (skge->hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(skge->hw)) genesis_get_stats(skge, data); else yukon_get_stats(skge, data); @@ -589,7 +601,7 @@ static int skge_set_pauseparam(struct net_device *dev, /* Chip internal frequency for clock calculations */ static inline u32 hwkhz(const struct skge_hw *hw) { - return (hw->chip_id == CHIP_ID_GENESIS) ? 53125 : 78125; + return is_genesis(hw) ? 53125 : 78125; } /* Chip HZ to microseconds */ @@ -674,7 +686,7 @@ static void skge_led(struct skge_port *skge, enum led_mode mode) int port = skge->port; spin_lock_bh(&hw->phy_lock); - if (hw->chip_id == CHIP_ID_GENESIS) { + if (is_genesis(hw)) { switch (mode) { case LED_MODE_OFF: if (hw->phy_type == SK_PHY_BCOM) @@ -1053,7 +1065,6 @@ static void skge_link_down(struct skge_port *skge) netif_info(skge, link, skge->netdev, "Link is down\n"); } - static void xm_link_down(struct skge_hw *hw, int port) { struct net_device *dev = hw->dev[port]; @@ -1172,7 +1183,6 @@ static void genesis_reset(struct skge_hw *hw, int port) xm_write32(hw, port, XM_MODE, reg | XM_MD_FRF); } - /* Convert mode to MII values */ static const u16 phy_pause_map[] = { [FLOW_MODE_NONE] = 0, @@ -2405,7 +2415,7 @@ static void skge_phy_reset(struct skge_port *skge) netif_carrier_off(skge->netdev); spin_lock_bh(&hw->phy_lock); - if (hw->chip_id == CHIP_ID_GENESIS) { + if (is_genesis(hw)) { genesis_reset(hw, port); genesis_mac_init(hw, port); } else { @@ -2436,7 +2446,8 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: { u16 val = 0; spin_lock_bh(&hw->phy_lock); - if (hw->chip_id == CHIP_ID_GENESIS) + + if (is_genesis(hw)) err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val); else err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val); @@ -2447,7 +2458,7 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCSMIIREG: spin_lock_bh(&hw->phy_lock); - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f, data->val_in); else @@ -2559,7 +2570,7 @@ static int skge_up(struct net_device *dev) /* Initialize MAC */ spin_lock_bh(&hw->phy_lock); - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) genesis_mac_init(hw, port); else yukon_mac_init(hw, port); @@ -2621,7 +2632,7 @@ static int skge_down(struct net_device *dev) netif_tx_disable(dev); - if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC) + if (is_genesis(hw) && hw->phy_type == SK_PHY_XMAC) del_timer_sync(&skge->link_timer); napi_disable(&skge->napi); @@ -2633,7 +2644,7 @@ static int skge_down(struct net_device *dev) spin_unlock_irq(&hw->hw_lock); skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) genesis_stop(skge); else yukon_stop(skge); @@ -2661,7 +2672,7 @@ static int skge_down(struct net_device *dev) skge_rx_stop(hw, port); - if (hw->chip_id == CHIP_ID_GENESIS) { + if (is_genesis(hw)) { skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); } else { @@ -2957,7 +2968,7 @@ static void yukon_set_multicast(struct net_device *dev) static inline u16 phy_length(const struct skge_hw *hw, u32 status) { - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) return status >> XMR_FS_LEN_SHIFT; else return status >> GMR_FS_LEN_SHIFT; @@ -2965,7 +2976,7 @@ static inline u16 phy_length(const struct skge_hw *hw, u32 status) static inline int bad_phy_status(const struct skge_hw *hw, u32 status) { - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) return (status & (XMR_FS_ERR | XMR_FS_2L_VLAN)) != 0; else return (status & GMR_FS_ANY_ERR) || @@ -2975,9 +2986,8 @@ static inline int bad_phy_status(const struct skge_hw *hw, u32 status) static void skge_set_multicast(struct net_device *dev) { struct skge_port *skge = netdev_priv(dev); - struct skge_hw *hw = skge->hw; - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(skge->hw)) genesis_set_multicast(dev); else yukon_set_multicast(dev); @@ -3057,7 +3067,7 @@ error: "rx err, slot %td control 0x%x status 0x%x\n", e - skge->rx_ring.start, control, status); - if (skge->hw->chip_id == CHIP_ID_GENESIS) { + if (is_genesis(skge->hw)) { if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) dev->stats.rx_length_errors++; if (status & XMR_FS_FRA_ERR) @@ -3171,7 +3181,7 @@ static void skge_mac_parity(struct skge_hw *hw, int port) ++dev->stats.tx_heartbeat_errors; - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_PERR); else @@ -3183,7 +3193,7 @@ static void skge_mac_parity(struct skge_hw *hw, int port) static void skge_mac_intr(struct skge_hw *hw, int port) { - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) genesis_mac_intr(hw, port); else yukon_mac_intr(hw, port); @@ -3195,7 +3205,7 @@ static void skge_error_irq(struct skge_hw *hw) struct pci_dev *pdev = hw->pdev; u32 hwstatus = skge_read32(hw, B0_HWE_ISRC); - if (hw->chip_id == CHIP_ID_GENESIS) { + if (is_genesis(hw)) { /* clear xmac errors */ if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT); @@ -3278,7 +3288,7 @@ static void skge_extirq(unsigned long arg) struct skge_port *skge = netdev_priv(dev); spin_lock(&hw->phy_lock); - if (hw->chip_id != CHIP_ID_GENESIS) + if (!is_genesis(hw)) yukon_phy_intr(skge); else if (hw->phy_type == SK_PHY_BCOM) bcom_phy_intr(skge); @@ -3397,7 +3407,7 @@ static int skge_set_mac_address(struct net_device *dev, void *p) memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN); memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN); - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) xm_outaddr(hw, port, XM_SA, dev->dev_addr); else { gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); @@ -3473,6 +3483,7 @@ static int skge_reset(struct skge_hw *hw) switch (hw->chip_id) { case CHIP_ID_GENESIS: +#ifdef CONFIG_SKGE_GENESIS switch (hw->phy_type) { case SK_PHY_XMAC: hw->phy_addr = PHY_ADDR_XMAC; @@ -3486,6 +3497,10 @@ static int skge_reset(struct skge_hw *hw) return -EOPNOTSUPP; } break; +#else + dev_err(&hw->pdev->dev, "Genesis chip detected but not configured\n"); + return -EOPNOTSUPP; +#endif case CHIP_ID_YUKON: case CHIP_ID_YUKON_LITE: @@ -3508,7 +3523,7 @@ static int skge_reset(struct skge_hw *hw) /* read the adapters RAM size */ t8 = skge_read8(hw, B2_E_0); - if (hw->chip_id == CHIP_ID_GENESIS) { + if (is_genesis(hw)) { if (t8 == 3) { /* special case: 4 x 64k x 36, offset = 0x80000 */ hw->ram_size = 0x100000; @@ -3523,10 +3538,10 @@ static int skge_reset(struct skge_hw *hw) hw->intr_mask = IS_HW_ERR; /* Use PHY IRQ for all but fiber based Genesis board */ - if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)) + if (!(is_genesis(hw) && hw->phy_type == SK_PHY_XMAC)) hw->intr_mask |= IS_EXT_REG; - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) genesis_init(hw); else { /* switch power to VCC (WA for VAUX problem) */ @@ -3591,7 +3606,7 @@ static int skge_reset(struct skge_hw *hw) skge_write32(hw, B0_IMSK, hw->intr_mask); for (i = 0; i < hw->ports; i++) { - if (hw->chip_id == CHIP_ID_GENESIS) + if (is_genesis(hw)) genesis_reset(hw, i); else yukon_reset(hw, i); @@ -3802,9 +3817,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, skge->port = port; /* Only used for Genesis XMAC */ - setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge); - - if (hw->chip_id != CHIP_ID_GENESIS) { + if (is_genesis(hw)) + setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge); + else { dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; dev->features |= dev->hw_features; -- cgit v1.2.3-70-g09d2 From 5a9d69179f294691bdfd1278f64212a9a7815b0e Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Jul 2011 19:00:08 +0000 Subject: skge: update version Update version number, and take "New" off the config information since old sk98lin has been gone for a couple years. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/Kconfig | 2 +- drivers/net/skge.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b1e67d68349..7cae8b619e5 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2272,7 +2272,7 @@ config SIS190 will be called sis190. This is recommended. config SKGE - tristate "New SysKonnect GigaEthernet support" + tristate "SysKonnect GigaEthernet support" depends on PCI select CRC32 ---help--- diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 4495e249149..98ec614c569 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -50,7 +50,7 @@ #include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "1.13" +#define DRV_VERSION "1.14" #define DEFAULT_TX_RING_SIZE 128 #define DEFAULT_RX_RING_SIZE 512 -- cgit v1.2.3-70-g09d2 From 380b153cf59a5610ca97319fdb9601b8c453ece0 Mon Sep 17 00:00:00 2001 From: Sebastian Poehn Date: Thu, 7 Jul 2011 04:30:29 -0700 Subject: gianfar v2: code cleanups This patch: # improves readability of some gianfar nfc code Signed-off-by: Sebastian Poehn Signed-off-by: David S. Miller --- drivers/net/gianfar.h | 1 + drivers/net/gianfar_ethtool.c | 52 +++++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 76f14d04447..27499c606a4 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -409,6 +409,7 @@ extern const char gfar_driver_version[]; #define RQFCR_HASHTBL_2 0x00060000 #define RQFCR_HASHTBL_3 0x00080000 #define RQFCR_HASH 0x00010000 +#define RQFCR_QUEUE 0x0000FC00 #define RQFCR_CLE 0x00000200 #define RQFCR_RJE 0x00000100 #define RQFCR_AND 0x00000080 diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 2ecdc9a785f..203369cc127 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "gianfar.h" @@ -883,7 +884,7 @@ static void gfar_set_attribute(u32 value, u32 mask, u32 flag, struct filer_table *tab) { switch (flag) { - /* 3bit */ + /* 3bit */ case RQFCR_PID_PRI: if (!(value | mask)) return; @@ -1051,17 +1052,17 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, vlan_mask = RQFPR_VLN; /* Separate the fields */ - id = rule->h_ext.vlan_tci & 0xFFF; - id_mask = rule->m_ext.vlan_tci & 0xFFF; - cfi = (rule->h_ext.vlan_tci >> 12) & 1; - cfi_mask = (rule->m_ext.vlan_tci >> 12) & 1; - prio = (rule->h_ext.vlan_tci >> 13) & 0x7; - prio_mask = (rule->m_ext.vlan_tci >> 13) & 0x7; - - if (cfi == 1 && cfi_mask == 1) { + id = rule->h_ext.vlan_tci & VLAN_VID_MASK; + id_mask = rule->m_ext.vlan_tci & VLAN_VID_MASK; + cfi = rule->h_ext.vlan_tci & VLAN_CFI_MASK; + cfi_mask = rule->m_ext.vlan_tci & VLAN_CFI_MASK; + prio = (rule->h_ext.vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; + prio_mask = (rule->m_ext.vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; + + if (cfi == VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { vlan |= RQFPR_CFI; vlan_mask |= RQFPR_CFI; - } else if (cfi == 0 && cfi_mask == 1) { + } else if (cfi != VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { vlan_mask |= RQFPR_CFI; } } @@ -1262,21 +1263,21 @@ static void gfar_cluster_filer(struct filer_table *tab) } } -/* Swaps the 0xFF80 masked bits of a1<>a2 and b1<>b2 */ -static void gfar_swap_ff80_bits(struct gfar_filer_entry *a1, +/* Swaps the masked bits of a1<>a2 and b1<>b2 */ +static void gfar_swap_bits(struct gfar_filer_entry *a1, struct gfar_filer_entry *a2, struct gfar_filer_entry *b1, - struct gfar_filer_entry *b2) + struct gfar_filer_entry *b2, u32 mask) { u32 temp[4]; - temp[0] = a1->ctrl & 0xFF80; - temp[1] = a2->ctrl & 0xFF80; - temp[2] = b1->ctrl & 0xFF80; - temp[3] = b2->ctrl & 0xFF80; + temp[0] = a1->ctrl & mask; + temp[1] = a2->ctrl & mask; + temp[2] = b1->ctrl & mask; + temp[3] = b2->ctrl & mask; - a1->ctrl &= ~0xFF80; - a2->ctrl &= ~0xFF80; - b1->ctrl &= ~0xFF80; - b2->ctrl &= ~0xFF80; + a1->ctrl &= ~mask; + a2->ctrl &= ~mask; + b1->ctrl &= ~mask; + b2->ctrl &= ~mask; a1->ctrl |= temp[1]; a2->ctrl |= temp[0]; @@ -1305,7 +1306,7 @@ static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, mask_table[and_index - 1].end = i - 1; and_index++; } - /* cluster starts will be separated because they should + /* cluster starts and ends will be separated because they should * hold their position */ if (tab->fe[i].ctrl & RQFCR_CLE) block_index++; @@ -1356,10 +1357,13 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, new_first = mask_table[start].start + 1; new_last = mask_table[i - 1].end; - gfar_swap_ff80_bits(&temp_table->fe[new_first], + gfar_swap_bits(&temp_table->fe[new_first], &temp_table->fe[old_first], &temp_table->fe[new_last], - &temp_table->fe[old_last]); + &temp_table->fe[old_last], + RQFCR_QUEUE | RQFCR_CLE | + RQFCR_RJE | RQFCR_AND + ); start = i; size = 0; -- cgit v1.2.3-70-g09d2 From 97bc3633bec7ed0fdfbda6b9cf86c51e4f58f8e2 Mon Sep 17 00:00:00 2001 From: Shirley Ma Date: Wed, 6 Jul 2011 12:26:11 +0000 Subject: macvtap: macvtapTX zero-copy support Only 128 bytes is copied, the rest of data is DMA mapped directly from userspace. Signed-off-by: Shirley Ma Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 132 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index ecee0fe65a9..ab96c319a24 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -60,6 +60,7 @@ static struct proto macvtap_proto = { */ static dev_t macvtap_major; #define MACVTAP_NUM_DEVS 65536 +#define GOODCOPY_LEN 128 static struct class *macvtap_class; static struct cdev macvtap_cdev; @@ -340,6 +341,7 @@ static int macvtap_open(struct inode *inode, struct file *file) { struct net *net = current->nsproxy->net_ns; struct net_device *dev = dev_get_by_index(net, iminor(inode)); + struct macvlan_dev *vlan = netdev_priv(dev); struct macvtap_queue *q; int err; @@ -369,6 +371,16 @@ static int macvtap_open(struct inode *inode, struct file *file) q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; q->vnet_hdr_sz = sizeof(struct virtio_net_hdr); + /* + * so far only KVM virtio_net uses macvtap, enable zero copy between + * guest kernel and host kernel when lower device supports zerocopy + */ + if (vlan) { + if ((vlan->lowerdev->features & NETIF_F_HIGHDMA) && + (vlan->lowerdev->features & NETIF_F_SG)) + sock_set_flag(&q->sk, SOCK_ZEROCOPY); + } + err = macvtap_set_queue(dev, file, q); if (err) sock_put(&q->sk); @@ -433,6 +445,80 @@ static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad, return skb; } +/* set skb frags from iovec, this can move to core network code for reuse */ +static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, + int offset, size_t count) +{ + int len = iov_length(from, count) - offset; + int copy = skb_headlen(skb); + int size, offset1 = 0; + int i = 0; + skb_frag_t *f; + + /* Skip over from offset */ + while (count && (offset >= from->iov_len)) { + offset -= from->iov_len; + ++from; + --count; + } + + /* copy up to skb headlen */ + while (count && (copy > 0)) { + size = min_t(unsigned int, copy, from->iov_len - offset); + if (copy_from_user(skb->data + offset1, from->iov_base + offset, + size)) + return -EFAULT; + if (copy > size) { + ++from; + --count; + } + copy -= size; + offset1 += size; + offset = 0; + } + + if (len == offset1) + return 0; + + while (count--) { + struct page *page[MAX_SKB_FRAGS]; + int num_pages; + unsigned long base; + + len = from->iov_len - offset1; + if (!len) { + offset1 = 0; + ++from; + continue; + } + base = (unsigned long)from->iov_base + offset1; + size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; + num_pages = get_user_pages_fast(base, size, 0, &page[i]); + if ((num_pages != size) || + (num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags)) + /* put_page is in skb free */ + return -EFAULT; + skb->data_len += len; + skb->len += len; + skb->truesize += len; + atomic_add(len, &skb->sk->sk_wmem_alloc); + while (len) { + f = &skb_shinfo(skb)->frags[i]; + f->page = page[i]; + f->page_offset = base & ~PAGE_MASK; + f->size = min_t(int, len, PAGE_SIZE - f->page_offset); + skb_shinfo(skb)->nr_frags++; + /* increase sk_wmem_alloc */ + base += f->size; + len -= f->size; + i++; + } + offset1 = 0; + ++from; + } + return 0; +} + /* * macvtap_skb_from_vnet_hdr and macvtap_skb_to_vnet_hdr should * be shared with the tun/tap driver. @@ -517,16 +603,18 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, /* Get packet from user space buffer */ -static ssize_t macvtap_get_user(struct macvtap_queue *q, - const struct iovec *iv, size_t count, - int noblock) +static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + const struct iovec *iv, unsigned long total_len, + size_t count, int noblock) { struct sk_buff *skb; struct macvlan_dev *vlan; - size_t len = count; + unsigned long len = total_len; int err; struct virtio_net_hdr vnet_hdr = { 0 }; int vnet_hdr_len = 0; + int copylen; + bool zerocopy = false; if (q->flags & IFF_VNET_HDR) { vnet_hdr_len = q->vnet_hdr_sz; @@ -554,12 +642,31 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, if (unlikely(len < ETH_HLEN)) goto err; - skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, len, vnet_hdr.hdr_len, - noblock, &err); + if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) + zerocopy = true; + + if (zerocopy) { + /* There are 256 bytes to be copied in skb, so there is enough + * room for skb expand head in case it is used. + * The rest buffer is mapped from userspace. + */ + copylen = vnet_hdr.hdr_len; + if (!copylen) + copylen = GOODCOPY_LEN; + } else + copylen = len; + + skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen, + vnet_hdr.hdr_len, noblock, &err); if (!skb) goto err; - err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, len); + if (zerocopy) { + err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); + skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; + } else + err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, + len); if (err) goto err_kfree; @@ -575,13 +682,16 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, rcu_read_lock_bh(); vlan = rcu_dereference_bh(q->vlan); + /* copy skb_ubuf_info for callback when skb has no error */ + if (zerocopy) + skb_shinfo(skb)->destructor_arg = m->msg_control; if (vlan) macvlan_start_xmit(skb, vlan->dev); else kfree_skb(skb); rcu_read_unlock_bh(); - return count; + return total_len; err_kfree: kfree_skb(skb); @@ -603,8 +713,8 @@ static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv, ssize_t result = -ENOLINK; struct macvtap_queue *q = file->private_data; - result = macvtap_get_user(q, iv, iov_length(iv, count), - file->f_flags & O_NONBLOCK); + result = macvtap_get_user(q, NULL, iv, iov_length(iv, count), count, + file->f_flags & O_NONBLOCK); return result; } @@ -817,7 +927,7 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len) { struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); - return macvtap_get_user(q, m->msg_iov, total_len, + return macvtap_get_user(q, m, m->msg_iov, total_len, m->msg_iovlen, m->msg_flags & MSG_DONTWAIT); } -- cgit v1.2.3-70-g09d2 From 3c878d4746ca12cc8022f9e02f055f175b847dbc Mon Sep 17 00:00:00 2001 From: Shmulik Ravid Date: Thu, 7 Jul 2011 05:11:30 -0700 Subject: bnx2x: Add dcbnl notification This patch adds a dcbnl notification to the bnx2x. The notification is sent to user mode clients following a change in the dcb negotiated parameters as resolved by the embedded DCBX stack. Signed-off-by: Shmulik Ravid Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_dcb.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index b51a759c103..45cf3ceef14 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -19,14 +19,14 @@ #include #include #include -#ifdef BCM_DCBNL -#include -#endif #include "bnx2x.h" #include "bnx2x_cmn.h" #include "bnx2x_dcb.h" +#ifdef BCM_DCBNL +#include +#endif /* forward declarations of dcbx related functions */ static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); @@ -702,6 +702,12 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) case BNX2X_DCBX_STATE_TX_RELEASED: DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n"); bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0); +#ifdef BCM_DCBNL + /** + * Send a notification for the new negotiated parameters + */ + dcbnl_cee_notify(bp->dev, RTM_GETDCB, DCB_CMD_CEE_GET, 0, 0); +#endif return; default: BNX2X_ERR("Unknown DCBX_STATE\n"); -- cgit v1.2.3-70-g09d2 From 68ac31918ec359a2bfb9f897bb62c2940652d2b8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 7 Jul 2011 06:13:32 -0700 Subject: sky2: use GFP_KERNEL allocations at device setup In process and sleep allowed context, favor GFP_KERNEL allocations over GFP_ATOMIC ones. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/sky2.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e14b86e27dc..c91513ed784 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1362,13 +1362,14 @@ static inline unsigned sky2_rx_pad(const struct sky2_hw *hw) * Allocate an skb for receiving. If the MTU is large enough * make the skb non-linear with a fragment list of pages. */ -static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) +static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2, gfp_t gfp) { struct sk_buff *skb; int i; - skb = netdev_alloc_skb(sky2->netdev, - sky2->rx_data_size + sky2_rx_pad(sky2->hw)); + skb = __netdev_alloc_skb(sky2->netdev, + sky2->rx_data_size + sky2_rx_pad(sky2->hw), + gfp); if (!skb) goto nomem; @@ -1386,7 +1387,7 @@ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) skb_reserve(skb, NET_IP_ALIGN); for (i = 0; i < sky2->rx_nfrags; i++) { - struct page *page = alloc_page(GFP_ATOMIC); + struct page *page = alloc_page(gfp); if (!page) goto free_partial; @@ -1416,7 +1417,7 @@ static int sky2_alloc_rx_skbs(struct sky2_port *sky2) for (i = 0; i < sky2->rx_pending; i++) { struct rx_ring_info *re = sky2->rx_ring + i; - re->skb = sky2_rx_alloc(sky2); + re->skb = sky2_rx_alloc(sky2, GFP_KERNEL); if (!re->skb) return -ENOMEM; @@ -2384,7 +2385,7 @@ static struct sk_buff *receive_new(struct sky2_port *sky2, struct rx_ring_info nre; unsigned hdr_space = sky2->rx_data_size; - nre.skb = sky2_rx_alloc(sky2); + nre.skb = sky2_rx_alloc(sky2, GFP_ATOMIC); if (unlikely(!nre.skb)) goto nobuf; -- cgit v1.2.3-70-g09d2 From 77a861c405da75d81e9e6e32c50eb7f9777777e8 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 6 Jul 2011 22:56:24 +0200 Subject: rt2x00: Serialize TX operations on a queue. The rt2x00 driver gets frequent occurrences of the following error message when operating under load: phy0 -> rt2x00queue_write_tx_frame: Error - Arrived at non-free entry in the non-full queue 2. This is caused by simultaneous attempts from mac80211 to send a frame via rt2x00, which are not properly serialized inside rt2x00queue_write_tx_frame, causing the second frame to fail sending with the above mentioned error message. Fix this by introducing a per-queue spinlock to serialize the TX operations on that queue. Reported-by: Andreas Hartmann Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 21 ++++++++++++++++----- drivers/net/wireless/rt2x00/rt2x00queue.h | 2 ++ 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index c7fc9def6bc..551cee1209c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -555,15 +555,21 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, bool local) { struct ieee80211_tx_info *tx_info; - struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); + struct queue_entry *entry; struct txentry_desc txdesc; struct skb_frame_desc *skbdesc; u8 rate_idx, rate_flags; + int ret = 0; + + spin_lock(&queue->tx_lock); + + entry = rt2x00queue_get_entry(queue, Q_INDEX); if (unlikely(rt2x00queue_full(queue))) { ERROR(queue->rt2x00dev, "Dropping frame due to full tx queue %d.\n", queue->qid); - return -ENOBUFS; + ret = -ENOBUFS; + goto out; } if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, @@ -572,7 +578,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, "Arrived at non-free entry in the non-full queue %d.\n" "Please file bug report to %s.\n", queue->qid, DRV_PROJECT); - return -EINVAL; + ret = -EINVAL; + goto out; } /* @@ -634,7 +641,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, if (unlikely(rt2x00queue_write_tx_data(entry, &txdesc))) { clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); entry->skb = NULL; - return -EIO; + ret = -EIO; + goto out; } set_bit(ENTRY_DATA_PENDING, &entry->flags); @@ -643,7 +651,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, rt2x00queue_write_tx_descriptor(entry, &txdesc); rt2x00queue_kick_tx_queue(queue, &txdesc); - return 0; +out: + spin_unlock(&queue->tx_lock); + return ret; } int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, @@ -1184,6 +1194,7 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, enum data_queue_qid qid) { mutex_init(&queue->status_lock); + spin_lock_init(&queue->tx_lock); spin_lock_init(&queue->index_lock); queue->rt2x00dev = rt2x00dev; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 590047499e3..f2100f4ddcf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -432,6 +432,7 @@ enum data_queue_flags { * @flags: Entry flags, see &enum queue_entry_flags. * @status_lock: The mutex for protecting the start/stop/flush * handling on this queue. + * @tx_lock: Spinlock to serialize tx operations on this queue. * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or * @index_crypt needs to be changed this lock should be grabbed to prevent * index corruption due to concurrency. @@ -458,6 +459,7 @@ struct data_queue { unsigned long flags; struct mutex status_lock; + spinlock_t tx_lock; spinlock_t index_lock; unsigned int count; -- cgit v1.2.3-70-g09d2 From 77b5621bac4a56b83b9081f48d4e7d1accdde400 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 6 Jul 2011 22:57:00 +0200 Subject: rt2x00: Don't use queue entry as parameter when creating TX descriptor. The functions that create the tx descriptor structure do not operate on a queue entry at all. Signal this fact in the code by not providing a queue entry as a parameter, but the rt2x00 device structure and the skb directly. This patch is a preparation for reducing the time a queue is locked for a tx operation. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00crypto.c | 6 ++-- drivers/net/wireless/rt2x00/rt2x00lib.h | 3 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 52 ++++++++++++++++-------------- 3 files changed, 33 insertions(+), 28 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 1bb9d46077f..1ca4c7ffc18 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c @@ -45,11 +45,11 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) } } -void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, +void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb, struct txentry_desc *txdesc) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key) diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 322cc4f3de5..15cdc7e57fc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -336,7 +336,8 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, */ #ifdef CONFIG_RT2X00_LIB_CRYPTO enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); -void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, +void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb, struct txentry_desc *txdesc); unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 551cee1209c..a70e7000b52 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -200,11 +200,12 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) skb_pull(skb, l2pad); } -static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, +static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb, struct txentry_desc *txdesc) { - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) @@ -212,7 +213,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); - if (!test_bit(REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->cap_flags)) + if (!test_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags)) return; /* @@ -237,12 +238,12 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, } -static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, +static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb, struct txentry_desc *txdesc, const struct rt2x00_rate *hwrate) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; unsigned int data_length; unsigned int duration; @@ -259,8 +260,8 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, txdesc->u.plcp.ifs = IFS_SIFS; /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ - data_length = entry->skb->len + 4; - data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb); + data_length = skb->len + 4; + data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb); /* * PLCP setup @@ -301,13 +302,14 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, } } -static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry, +static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb, struct txentry_desc *txdesc, const struct rt2x00_rate *hwrate) { - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; if (tx_info->control.sta) txdesc->u.ht.mpdu_density = @@ -380,12 +382,12 @@ static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry, txdesc->u.ht.txop = TXOP_HTTXOP; } -static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, +static void rt2x00queue_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb, struct txentry_desc *txdesc) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; struct ieee80211_rate *rate; const struct rt2x00_rate *hwrate = NULL; @@ -395,8 +397,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Header and frame information. */ - txdesc->length = entry->skb->len; - txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); + txdesc->length = skb->len; + txdesc->header_length = ieee80211_get_hdrlen_from_skb(skb); /* * Check whether this frame is to be acked. @@ -471,13 +473,15 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Apply TX descriptor handling by components */ - rt2x00crypto_create_tx_descriptor(entry, txdesc); - rt2x00queue_create_tx_descriptor_seq(entry, txdesc); + rt2x00crypto_create_tx_descriptor(rt2x00dev, skb, txdesc); + rt2x00queue_create_tx_descriptor_seq(rt2x00dev, skb, txdesc); if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) - rt2x00queue_create_tx_descriptor_ht(entry, txdesc, hwrate); + rt2x00queue_create_tx_descriptor_ht(rt2x00dev, skb, txdesc, + hwrate); else - rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); + rt2x00queue_create_tx_descriptor_plcp(rt2x00dev, skb, txdesc, + hwrate); } static int rt2x00queue_write_tx_data(struct queue_entry *entry, @@ -588,7 +592,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * for our information. */ entry->skb = skb; - rt2x00queue_create_tx_descriptor(entry, &txdesc); + rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc); /* * All information is retrieved from the skb->cb array, @@ -707,7 +711,7 @@ int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev, * after that we are free to use the skb->cb array * for our information. */ - rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); + rt2x00queue_create_tx_descriptor(rt2x00dev, intf->beacon->skb, &txdesc); /* * Fill in skb descriptor -- cgit v1.2.3-70-g09d2 From 128f8f773d77d41a7dbcaf5d36325a0f4e7955cd Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 6 Jul 2011 22:57:37 +0200 Subject: rt2x00: Reduce window of a queue's tx lock. Currently a lot of actions that can be done without the queue's tx lock being held are done inside the locked area. Move them out to have a leaner and meaner code that operates while the tx lock is being held. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 51 ++++++++++++++++--------------- 1 file changed, 26 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a70e7000b52..29edb9fbe6f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -565,33 +565,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, u8 rate_idx, rate_flags; int ret = 0; - spin_lock(&queue->tx_lock); - - entry = rt2x00queue_get_entry(queue, Q_INDEX); - - if (unlikely(rt2x00queue_full(queue))) { - ERROR(queue->rt2x00dev, - "Dropping frame due to full tx queue %d.\n", queue->qid); - ret = -ENOBUFS; - goto out; - } - - if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, - &entry->flags))) { - ERROR(queue->rt2x00dev, - "Arrived at non-free entry in the non-full queue %d.\n" - "Please file bug report to %s.\n", - queue->qid, DRV_PROJECT); - ret = -EINVAL; - goto out; - } - /* * Copy all TX descriptor information into txdesc, * after that we are free to use the skb->cb array * for our information. */ - entry->skb = skb; rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc); /* @@ -604,7 +582,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, rate_flags = tx_info->control.rates[0].flags; skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->entry = entry; skbdesc->tx_rate_idx = rate_idx; skbdesc->tx_rate_flags = rate_flags; @@ -633,9 +610,33 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * for PCI devices. */ if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) - rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length); + rt2x00queue_insert_l2pad(skb, txdesc.header_length); else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) - rt2x00queue_align_frame(entry->skb); + rt2x00queue_align_frame(skb); + + spin_lock(&queue->tx_lock); + + if (unlikely(rt2x00queue_full(queue))) { + ERROR(queue->rt2x00dev, + "Dropping frame due to full tx queue %d.\n", queue->qid); + ret = -ENOBUFS; + goto out; + } + + entry = rt2x00queue_get_entry(queue, Q_INDEX); + + if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, + &entry->flags))) { + ERROR(queue->rt2x00dev, + "Arrived at non-free entry in the non-full queue %d.\n" + "Please file bug report to %s.\n", + queue->qid, DRV_PROJECT); + ret = -EINVAL; + goto out; + } + + skbdesc->entry = entry; + entry->skb = skb; /* * It could be possible that the queue was corrupted and this -- cgit v1.2.3-70-g09d2 From 71e0b38c2914018b01f3f08b43ee9e3328197699 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 6 Jul 2011 22:58:55 +0200 Subject: rt2x00: Add device ID for RT539F device. Reported-by: Wim Vander Schelden Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 5513edfa952..fd994490f58 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1160,6 +1160,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { #endif #ifdef CONFIG_RT2800PCI_RT53XX { PCI_DEVICE(0x1814, 0x5390) }, + { PCI_DEVICE(0x1814, 0x539f) }, #endif { 0, } }; -- cgit v1.2.3-70-g09d2 From acb56120d2c386d6dd104a6515c1a15dabc1ef87 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 6 Jul 2011 22:59:19 +0200 Subject: rt2x00: Properly identify rt2800usb devices. Sitecom WLA4000 (USB ID 0x0df6:0x0060) is an RT3072 chipset. Sitecom WLA5000 (USB ID 0x0df6:0x0062) is an RT3572 chipset. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6e9229830a2..af230583d0a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1020,6 +1020,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0df6, 0x0048) }, { USB_DEVICE(0x0df6, 0x0051) }, { USB_DEVICE(0x0df6, 0x005f) }, + { USB_DEVICE(0x0df6, 0x0060) }, /* SMC */ { USB_DEVICE(0x083a, 0x6618) }, { USB_DEVICE(0x083a, 0x7511) }, @@ -1076,6 +1077,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x148f, 0x3572) }, /* Sitecom */ { USB_DEVICE(0x0df6, 0x0041) }, + { USB_DEVICE(0x0df6, 0x0062) }, /* Toshiba */ { USB_DEVICE(0x0930, 0x0a07) }, /* Zinwell */ @@ -1174,8 +1176,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0df6, 0x004a) }, { USB_DEVICE(0x0df6, 0x004d) }, { USB_DEVICE(0x0df6, 0x0053) }, - { USB_DEVICE(0x0df6, 0x0060) }, - { USB_DEVICE(0x0df6, 0x0062) }, /* SMC */ { USB_DEVICE(0x083a, 0xa512) }, { USB_DEVICE(0x083a, 0xc522) }, -- cgit v1.2.3-70-g09d2 From 5f0dd296a01c8173fcc05a8b262a1168ae90bc74 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 6 Jul 2011 23:00:21 +0200 Subject: rt2x00: Implement tx_frames_pending mac80211 callback function. Implementing this callback function will cause mac80211 refrain from going to powersave state when there are still untransmitted TX frames in the queues. This would exactly mimic the behaviour of the legacy vendor driver which also doesn't go in powersave mode if there are still TX frames that are not transmitted. This should make powersaving and rt2x00 a better couple. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 1 + drivers/net/wireless/rt2x00/rt2500pci.c | 1 + drivers/net/wireless/rt2x00/rt2500usb.c | 1 + drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00mac.c | 14 ++++++++++++++ drivers/net/wireless/rt2x00/rt61pci.c | 1 + drivers/net/wireless/rt2x00/rt73usb.c | 1 + 9 files changed, 22 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 937f9e8bf05..76bcc354797 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1723,6 +1723,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { .set_antenna = rt2x00mac_set_antenna, .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, + .tx_frames_pending = rt2x00mac_tx_frames_pending, }; static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d27d7b8ba3b..c288d951c03 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -2016,6 +2016,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { .set_antenna = rt2x00mac_set_antenna, .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, + .tx_frames_pending = rt2x00mac_tx_frames_pending, }; static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 15237c27548..53c5f878f61 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1827,6 +1827,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { .set_antenna = rt2x00mac_set_antenna, .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, + .tx_frames_pending = rt2x00mac_tx_frames_pending, }; static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index fd994490f58..5319ed921a8 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1031,6 +1031,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { .flush = rt2x00mac_flush, .get_survey = rt2800_get_survey, .get_ringparam = rt2x00mac_get_ringparam, + .tx_frames_pending = rt2x00mac_tx_frames_pending, }; static const struct rt2800_ops rt2800pci_rt2800_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index af230583d0a..59e77797c0f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -757,6 +757,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { .flush = rt2x00mac_flush, .get_survey = rt2800_get_survey, .get_ringparam = rt2x00mac_get_ringparam, + .tx_frames_pending = rt2x00mac_tx_frames_pending, }; static const struct rt2800_ops rt2800usb_rt2800_ops = { diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c446db69bd3..db435abbd57 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1276,6 +1276,7 @@ int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); +bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw); /* * Driver allocation handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 93bec140e59..8efab398352 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -818,3 +818,17 @@ void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, *rx_max = rt2x00dev->rx->limit; } EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam); + +bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct data_queue *queue; + + tx_queue_for_each(rt2x00dev, queue) { + if (!rt2x00queue_empty(queue)) + return true; + } + + return false; +} +EXPORT_SYMBOL_GPL(rt2x00mac_tx_frames_pending); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 9d35ec16a3a..53110b83bf6 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2982,6 +2982,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { .set_antenna = rt2x00mac_set_antenna, .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, + .tx_frames_pending = rt2x00mac_tx_frames_pending, }; static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ad20953cbf0..6a93939f44e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2314,6 +2314,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { .set_antenna = rt2x00mac_set_antenna, .get_antenna = rt2x00mac_get_antenna, .get_ringparam = rt2x00mac_get_ringparam, + .tx_frames_pending = rt2x00mac_tx_frames_pending, }; static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { -- cgit v1.2.3-70-g09d2 From f1a46384ad568f72c11edbe2a3ec284bf32f2dbd Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 7 Jul 2011 14:25:23 +0300 Subject: wl12xx: start/stop queues according to global per-AC counters Split tx_queue_count to count per-AC skb's queued, instead of relying on the skb-queue len. The skb queues used were only valid in STA-mode, as AP-mode uses per-link queues. This fixes a major regression in AP-mode, caused by the patch "wl12xx: implement Tx watermarks per AC". With that patch applied, we effectively had no regulation of Tx queues in AP-mode. Therefore a sustained high rate of Tx could cause exhaustion of the skb memory pool. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 8 ++++++-- drivers/net/wireless/wl12xx/main.c | 13 +++++++------ drivers/net/wireless/wl12xx/ps.c | 9 ++++++--- drivers/net/wireless/wl12xx/tx.c | 33 +++++++++++++++++++++------------ drivers/net/wireless/wl12xx/tx.h | 10 ++++++++++ drivers/net/wireless/wl12xx/wl12xx.h | 2 +- 6 files changed, 51 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 4d9c8cc076e..37934b5601c 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -30,6 +30,7 @@ #include "acx.h" #include "ps.h" #include "io.h" +#include "tx.h" /* ms */ #define WL1271_DEBUGFS_STATS_LIFETIME 1000 @@ -233,7 +234,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, char buf[20]; int res; - queue_len = wl->tx_queue_count; + queue_len = wl1271_tx_total_queue_count(wl); res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); return simple_read_from_buffer(userbuf, count, ppos, buf, res); @@ -344,7 +345,10 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, DRIVER_STATE_PRINT_INT(tx_allocated_blocks[3]); DRIVER_STATE_PRINT_INT(tx_frames_cnt); DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]); - DRIVER_STATE_PRINT_INT(tx_queue_count); + DRIVER_STATE_PRINT_INT(tx_queue_count[0]); + DRIVER_STATE_PRINT_INT(tx_queue_count[1]); + DRIVER_STATE_PRINT_INT(tx_queue_count[2]); + DRIVER_STATE_PRINT_INT(tx_queue_count[3]); DRIVER_STATE_PRINT_INT(tx_packets_count); DRIVER_STATE_PRINT_INT(tx_results_count); DRIVER_STATE_PRINT_LHEX(flags); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 526b1ac2dd8..e58c22d21e3 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -992,7 +992,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie) /* Check if any tx blocks were freed */ spin_lock_irqsave(&wl->wl_lock, flags); if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && - wl->tx_queue_count) { + wl1271_tx_total_queue_count(wl) > 0) { spin_unlock_irqrestore(&wl->wl_lock, flags); /* * In order to avoid starvation of the TX path, @@ -1040,7 +1040,7 @@ out: /* In case TX was not handled here, queue TX work */ clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && - wl->tx_queue_count) + wl1271_tx_total_queue_count(wl) > 0) ieee80211_queue_work(wl->hw, &wl->tx_work); spin_unlock_irqrestore(&wl->wl_lock, flags); @@ -1508,13 +1508,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) spin_lock_irqsave(&wl->wl_lock, flags); - wl->tx_queue_count++; + wl->tx_queue_count[q]++; /* * The workqueue is slow to process the tx_queue and we need stop * the queue here, otherwise the queue will get too long. */ - if (skb_queue_len(&wl->tx_queue[q]) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { + if (wl->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK) { wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q); ieee80211_stop_queue(wl->hw, mapping); set_bit(q, &wl->stopped_queues_map); @@ -1543,10 +1543,11 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) int wl1271_tx_dummy_packet(struct wl1271 *wl) { unsigned long flags; + int q = wl1271_tx_get_queue(skb_get_queue_mapping(wl->dummy_packet)); spin_lock_irqsave(&wl->wl_lock, flags); set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags); - wl->tx_queue_count++; + wl->tx_queue_count[q]++; spin_unlock_irqrestore(&wl->wl_lock, flags); /* The FW is low on RX memory blocks, so send the dummy packet asap */ @@ -3752,7 +3753,7 @@ static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) goto out; /* packets are considered pending if in the TX queue or the FW */ - ret = (wl->tx_queue_count > 0) || (wl->tx_frames_cnt > 0); + ret = (wl1271_tx_total_queue_count(wl) > 0) || (wl->tx_frames_cnt > 0); /* the above is appropriate for STA mode for PS purposes */ WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 3e68a664c9d..3548377ab9c 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -193,24 +193,27 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid) { - int i, filtered = 0; + int i; struct sk_buff *skb; struct ieee80211_tx_info *info; unsigned long flags; + int filtered[NUM_TX_QUEUES]; /* filter all frames currently the low level queus for this hlid */ for (i = 0; i < NUM_TX_QUEUES; i++) { + filtered[i] = 0; while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { info = IEEE80211_SKB_CB(skb); info->flags |= IEEE80211_TX_STAT_TX_FILTERED; info->status.rates[0].idx = -1; ieee80211_tx_status_ni(wl->hw, skb); - filtered++; + filtered[i]++; } } spin_lock_irqsave(&wl->wl_lock, flags); - wl->tx_queue_count -= filtered; + for (i = 0; i < NUM_TX_QUEUES; i++) + wl->tx_queue_count[i] -= filtered[i]; spin_unlock_irqrestore(&wl->wl_lock, flags); wl1271_handle_tx_low_watermark(wl); diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 75984dc81a8..48fde96ce0d 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -448,8 +448,7 @@ void wl1271_handle_tx_low_watermark(struct wl1271 *wl) for (i = 0; i < NUM_TX_QUEUES; i++) { if (test_bit(i, &wl->stopped_queues_map) && - skb_queue_len(&wl->tx_queue[i]) <= - WL1271_TX_QUEUE_LOW_WATERMARK) { + wl->tx_queue_count[i] <= WL1271_TX_QUEUE_LOW_WATERMARK) { /* firmware buffer has space, restart queues */ spin_lock_irqsave(&wl->wl_lock, flags); ieee80211_wake_queue(wl->hw, @@ -498,8 +497,9 @@ static struct sk_buff *wl1271_sta_skb_dequeue(struct wl1271 *wl) out: if (skb) { + int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); spin_lock_irqsave(&wl->wl_lock, flags); - wl->tx_queue_count--; + wl->tx_queue_count[q]--; spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -535,9 +535,10 @@ static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl) } if (skb) { + int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); wl->last_tx_hlid = h; spin_lock_irqsave(&wl->wl_lock, flags); - wl->tx_queue_count--; + wl->tx_queue_count[q]--; spin_unlock_irqrestore(&wl->wl_lock, flags); } else { wl->last_tx_hlid = 0; @@ -558,9 +559,12 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) if (!skb && test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { + int q; + skb = wl->dummy_packet; + q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); spin_lock_irqsave(&wl->wl_lock, flags); - wl->tx_queue_count--; + wl->tx_queue_count[q]--; spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -585,7 +589,7 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) } spin_lock_irqsave(&wl->wl_lock, flags); - wl->tx_queue_count++; + wl->tx_queue_count[q]++; spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -813,23 +817,26 @@ void wl1271_tx_complete(struct wl1271 *wl) void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) { struct sk_buff *skb; - int i, total = 0; + int i; unsigned long flags; struct ieee80211_tx_info *info; + int total[NUM_TX_QUEUES]; for (i = 0; i < NUM_TX_QUEUES; i++) { + total[i] = 0; while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { wl1271_debug(DEBUG_TX, "link freeing skb 0x%p", skb); info = IEEE80211_SKB_CB(skb); info->status.rates[0].idx = -1; info->status.rates[0].count = 0; ieee80211_tx_status_ni(wl->hw, skb); - total++; + total[i]++; } } spin_lock_irqsave(&wl->wl_lock, flags); - wl->tx_queue_count -= total; + for (i = 0; i < NUM_TX_QUEUES; i++) + wl->tx_queue_count[i] -= total[i]; spin_unlock_irqrestore(&wl->wl_lock, flags); wl1271_handle_tx_low_watermark(wl); @@ -864,10 +871,10 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) ieee80211_tx_status_ni(wl->hw, skb); } } + wl->tx_queue_count[i] = 0; } } - wl->tx_queue_count = 0; wl->stopped_queues_map = 0; /* @@ -921,8 +928,10 @@ void wl1271_tx_flush(struct wl1271 *wl) while (!time_after(jiffies, timeout)) { mutex_lock(&wl->mutex); wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d", - wl->tx_frames_cnt, wl->tx_queue_count); - if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) { + wl->tx_frames_cnt, + wl1271_tx_total_queue_count(wl)); + if ((wl->tx_frames_cnt == 0) && + (wl1271_tx_total_queue_count(wl) == 0)) { mutex_unlock(&wl->mutex); return; } diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 6b7bf3150ec..5d719b5a3d1 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -198,6 +198,16 @@ static inline int wl1271_tx_get_mac80211_queue(int queue) } } +static inline int wl1271_tx_total_queue_count(struct wl1271 *wl) +{ + int i, count = 0; + + for (i = 0; i < NUM_TX_QUEUES; i++) + count += wl->tx_queue_count[i]; + + return count; +} + void wl1271_tx_work(struct work_struct *work); void wl1271_tx_work_locked(struct wl1271 *wl); void wl1271_tx_complete(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 94bfc0a25d5..1a8751eb814 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -438,7 +438,7 @@ struct wl1271 { /* Frames scheduled for transmission, not handled yet */ struct sk_buff_head tx_queue[NUM_TX_QUEUES]; - int tx_queue_count; + int tx_queue_count[NUM_TX_QUEUES]; long stopped_queues_map; /* Frames received, not handled yet by mac80211 */ -- cgit v1.2.3-70-g09d2 From d1507051bf6004c8ff0cf823fc5e115fc0a740b3 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 5 Jul 2011 23:54:07 +0200 Subject: b43: make b43_wireless_init bus generic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 834df5a3fb6..410b77f2957 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4959,9 +4959,9 @@ static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl) ieee80211_free_hw(hw); } -static struct b43_wl *b43_wireless_init(struct ssb_device *dev) +static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) { - struct ssb_sprom *sprom = &dev->bus->sprom; + struct ssb_sprom *sprom = dev->bus_sprom; struct ieee80211_hw *hw; struct b43_wl *wl; @@ -5003,7 +5003,7 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev) skb_queue_head_init(&wl->tx_queue); b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", - dev->bus->chip_id, dev->id.revision); + dev->chip_id, dev->core_rev); return wl; } @@ -5045,7 +5045,7 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) /* Probing the first core. Must setup common struct b43_wl */ first = 1; b43_sprom_fixup(sdev->bus); - wl = b43_wireless_init(sdev); + wl = b43_wireless_init(dev); if (IS_ERR(wl)) { err = PTR_ERR(wl); goto out; -- cgit v1.2.3-70-g09d2 From 397915c30731340ee3f348d1be597b22467acbdf Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 19:03:46 +0200 Subject: b43: implement BCMA bus ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 100 ++++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/bus.h | 3 ++ drivers/net/wireless/b43/main.c | 7 +++ 3 files changed, 110 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 4200713eb59..c45c76dc49c 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -23,6 +23,106 @@ #include "b43.h" #include "bus.h" +/* BCMA */ +#ifdef CONFIG_B43_BCMA +static int b43_bus_bcma_bus_may_powerdown(struct b43_bus_dev *dev) +{ + return 0; /* bcma_bus_may_powerdown(dev->bdev->bus); */ +} +static int b43_bus_bcma_bus_powerup(struct b43_bus_dev *dev, + bool dynamic_pctl) +{ + return 0; /* bcma_bus_powerup(dev->sdev->bus, dynamic_pctl); */ +} +static int b43_bus_bcma_device_is_enabled(struct b43_bus_dev *dev) +{ + return bcma_core_is_enabled(dev->bdev); +} +static void b43_bus_bcma_device_enable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + bcma_core_enable(dev->bdev, core_specific_flags); +} +static void b43_bus_bcma_device_disable(struct b43_bus_dev *dev, + u32 core_specific_flags) +{ + bcma_core_disable(dev->bdev, core_specific_flags); +} +static u16 b43_bus_bcma_read16(struct b43_bus_dev *dev, u16 offset) +{ + return bcma_read16(dev->bdev, offset); +} +static u32 b43_bus_bcma_read32(struct b43_bus_dev *dev, u16 offset) +{ + return bcma_read32(dev->bdev, offset); +} +static +void b43_bus_bcma_write16(struct b43_bus_dev *dev, u16 offset, u16 value) +{ + bcma_write16(dev->bdev, offset, value); +} +static +void b43_bus_bcma_write32(struct b43_bus_dev *dev, u16 offset, u32 value) +{ + bcma_write32(dev->bdev, offset, value); +} +static +void b43_bus_bcma_block_read(struct b43_bus_dev *dev, void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + bcma_block_read(dev->bdev, buffer, count, offset, reg_width); +} +static +void b43_bus_bcma_block_write(struct b43_bus_dev *dev, const void *buffer, + size_t count, u16 offset, u8 reg_width) +{ + bcma_block_write(dev->bdev, buffer, count, offset, reg_width); +} + +struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core) +{ + struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->bus_type = B43_BUS_BCMA; + dev->bdev = core; + + dev->bus_may_powerdown = b43_bus_bcma_bus_may_powerdown; + dev->bus_powerup = b43_bus_bcma_bus_powerup; + dev->device_is_enabled = b43_bus_bcma_device_is_enabled; + dev->device_enable = b43_bus_bcma_device_enable; + dev->device_disable = b43_bus_bcma_device_disable; + + dev->read16 = b43_bus_bcma_read16; + dev->read32 = b43_bus_bcma_read32; + dev->write16 = b43_bus_bcma_write16; + dev->write32 = b43_bus_bcma_write32; + dev->block_read = b43_bus_bcma_block_read; + dev->block_write = b43_bus_bcma_block_write; + + dev->dev = &core->dev; + dev->dma_dev = core->dma_dev; + dev->irq = core->irq; + + /* + dev->board_vendor = core->bus->boardinfo.vendor; + dev->board_type = core->bus->boardinfo.type; + dev->board_rev = core->bus->boardinfo.rev; + */ + + dev->chip_id = core->bus->chipinfo.id; + dev->chip_rev = core->bus->chipinfo.rev; + dev->chip_pkg = core->bus->chipinfo.pkg; + + dev->bus_sprom = &core->bus->sprom; + + dev->core_id = core->id.id; + dev->core_rev = core->id.rev; + + return dev; +} +#endif /* CONFIG_B43_BCMA */ /* SSB */ #ifdef CONFIG_B43_SSB diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index 79a5ab4270c..a70b7b9a550 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -2,12 +2,14 @@ #define B43_BUS_H_ enum b43_bus_type { + B43_BUS_BCMA, B43_BUS_SSB, }; struct b43_bus_dev { enum b43_bus_type bus_type; union { + struct bcma_device *bdev; struct ssb_device *sdev; }; @@ -57,6 +59,7 @@ static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); } +struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core); struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); #endif /* B43_BUS_H_ */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 410b77f2957..b85a9737ecb 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -5010,7 +5010,14 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) #ifdef CONFIG_B43_BCMA static int b43_bcma_probe(struct bcma_device *core) { + struct b43_bus_dev *dev; + + dev = b43_bus_dev_bcma_init(core); + if (!dev) + return -ENODEV; + b43err(NULL, "BCMA is not supported yet!"); + kfree(dev); return -EOPNOTSUPP; } -- cgit v1.2.3-70-g09d2 From 523b02ea23b175dd3e46e3daf1bc9354376640a3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Jul 2011 22:28:01 +0200 Subject: mac80211: fix TKIP races, make API easier to use Our current TKIP code races against itself on TX since we can process multiple packets at the same time on different ACs, but they all share the TX context for TKIP. This can lead to bad IVs etc. Also, the crypto offload helper code just obtains the P1K/P2K from the cache, and can update it as well, but there's no guarantee that packets are really processed in order. To fix these issues, first introduce a spinlock that will protect the IV16/IV32 values in the TX context. This first step makes sure that we don't assign the same IV multiple times or get confused in other ways. Secondly, change the way the P1K cache works. I add a field "p1k_iv32" that stores the value of the IV32 when the P1K was last recomputed, and if different from the last time, then a new P1K is recomputed. This can cause the P1K computation to flip back and forth if packets are processed out of order. All this also happens under the new spinlock. Finally, because there are argument differences, split up the ieee80211_get_tkip_key() API into ieee80211_get_tkip_p1k() and ieee80211_get_tkip_p2k() and give them the correct arguments. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/b43/xmit.c | 3 +- drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 3 +- include/net/mac80211.h | 48 ++++++------ net/mac80211/key.c | 1 + net/mac80211/key.h | 10 ++- net/mac80211/tkip.c | 111 +++++++++++++++------------- net/mac80211/tkip.h | 8 +- net/mac80211/wpa.c | 9 ++- 9 files changed, 103 insertions(+), 93 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 488b898418a..82bcf759513 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, /* we give the phase1key and iv16 here, the key is stored in * shm. With that the hardware can do phase 2 and encryption. */ - ieee80211_get_tkip_key(info->control.hw_key, skb_frag, - IEEE80211_TKIP_P1_KEY, (u8*)phase1key); + ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key); /* phase1key is in host endian. Copy to little-endian txhdr->iv. */ for (i = 0; i < 5; i++) { txhdr->iv[i * 2 + 0] = phase1key[i]; diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c index 79ac081832f..ac4f64de136 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c @@ -240,8 +240,7 @@ static void iwl4965_tx_cmd_build_hwcrypto(struct iwl_priv *priv, case WLAN_CIPHER_SUITE_TKIP: tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; - ieee80211_get_tkip_key(keyconf, skb_frag, - IEEE80211_TKIP_P2_KEY, tx_cmd->key); + ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c05a8d9fbd2..a87e95728b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -497,8 +497,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, case WLAN_CIPHER_SUITE_TKIP: tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; - ieee80211_get_tkip_key(keyconf, skb_frag, - IEEE80211_TKIP_P2_KEY, tx_cmd->key); + ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); break; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2474019f47d..0aae7bc1eea 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -961,21 +961,6 @@ enum sta_notify_cmd { STA_NOTIFY_SLEEP, STA_NOTIFY_AWAKE, }; -/** - * enum ieee80211_tkip_key_type - get tkip key - * - * Used by drivers which need to get a tkip key for skb. Some drivers need a - * phase 1 key, others need a phase 2 key. A single function allows the driver - * to get the key, this enum indicates what type of key is required. - * - * @IEEE80211_TKIP_P1_KEY: the driver needs a phase 1 key - * @IEEE80211_TKIP_P2_KEY: the driver needs a phase 2 key - */ -enum ieee80211_tkip_key_type { - IEEE80211_TKIP_P1_KEY, - IEEE80211_TKIP_P2_KEY, -}; - /** * enum ieee80211_hw_flags - hardware flags * @@ -2579,21 +2564,32 @@ struct sk_buff * ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif); /** - * ieee80211_get_tkip_key - get a TKIP rc4 for skb + * ieee80211_get_tkip_p1k - get a TKIP phase 1 key + * + * This function returns the TKIP phase 1 key for the IV32 taken + * from the given packet. + * + * @keyconf: the parameter passed with the set key + * @skb: the packet to take the IV32 value from that will be encrypted + * with this P1K + * @p1k: a buffer to which the key will be written, as 5 u16 values + */ +void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf, + struct sk_buff *skb, u16 *p1k); + +/** + * ieee80211_get_tkip_p2k - get a TKIP phase 2 key * - * This function computes a TKIP rc4 key for an skb. It computes - * a phase 1 key if needed (iv16 wraps around). This function is to - * be used by drivers which can do HW encryption but need to compute - * to phase 1/2 key in SW. + * This function computes the TKIP RC4 key for the IV values + * in the packet. * * @keyconf: the parameter passed with the set key - * @skb: the skb for which the key is needed - * @type: TBD - * @key: a buffer to which the key will be written + * @skb: the packet to take the IV32/IV16 values from that will be + * encrypted with this key + * @p2k: a buffer to which the key will be written, 16 bytes */ -void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, - struct sk_buff *skb, - enum ieee80211_tkip_key_type type, u8 *key); +void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, + struct sk_buff *skb, u8 *p2k); /** * ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1208a7878bf..d930d4d4876 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -369,6 +369,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, get_unaligned_le16(seq); } } + spin_lock_init(&key->u.tkip.txlock); break; case WLAN_CIPHER_SUITE_CCMP: key->conf.iv_len = CCMP_HDR_LEN; diff --git a/net/mac80211/key.h b/net/mac80211/key.h index d801d535133..1493c3e56b9 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -52,9 +52,10 @@ enum ieee80211_internal_tkip_state { }; struct tkip_ctx { - u32 iv32; - u16 iv16; - u16 p1k[5]; + u32 iv32; /* current iv32 */ + u16 iv16; /* current iv16 */ + u16 p1k[5]; /* p1k cache */ + u32 p1k_iv32; /* iv32 for which p1k computed */ enum ieee80211_internal_tkip_state state; }; @@ -71,6 +72,9 @@ struct ieee80211_key { union { struct { + /* protects tx context */ + spinlock_t txlock; + /* last used TSC */ struct tkip_ctx tx; diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 757e4eb2baf..de570b38460 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -101,6 +101,7 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; } ctx->state = TKIP_STATE_PHASE1_DONE; + ctx->p1k_iv32 = tsc_IV32; } static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, @@ -140,60 +141,72 @@ static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets * of the IV. Returns pointer to the octet following IVs (i.e., beginning of * the packet payload). */ -u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) +u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key) { - pos = write_tkip_iv(pos, iv16); + lockdep_assert_held(&key->u.tkip.txlock); + + pos = write_tkip_iv(pos, key->u.tkip.tx.iv16); *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; put_unaligned_le32(key->u.tkip.tx.iv32, pos); return pos + 4; } -void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, - struct sk_buff *skb, enum ieee80211_tkip_key_type type, - u8 *outkey) +static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32) +{ + struct ieee80211_sub_if_data *sdata = key->sdata; + struct tkip_ctx *ctx = &key->u.tkip.tx; + const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; + + lockdep_assert_held(&key->u.tkip.txlock); + + /* + * Update the P1K when the IV32 is different from the value it + * had when we last computed it (or when not initialised yet). + * This might flip-flop back and forth if packets are processed + * out-of-order due to the different ACs, but then we have to + * just compute the P1K more often. + */ + if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT) + tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32); +} + +void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf, + struct sk_buff *skb, u16 *p1k) { struct ieee80211_key *key = (struct ieee80211_key *) container_of(keyconf, struct ieee80211_key, conf); + struct tkip_ctx *ctx = &key->u.tkip.tx; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u8 *data; - const u8 *tk; - struct tkip_ctx *ctx; - u16 iv16; - u32 iv32; - - data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); - iv16 = data[2] | (data[0] << 8); - iv32 = get_unaligned_le32(&data[4]); - - tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; - ctx = &key->u.tkip.tx; - -#ifdef CONFIG_MAC80211_TKIP_DEBUG - printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", - iv16, iv32); - - if (iv32 != ctx->iv32) { - printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", - iv32, ctx->iv32); - printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " - "fragmented packet\n"); - } -#endif - - /* Update the p1k only when the iv16 in the packet wraps around, this - * might occur after the wrap around of iv16 in the key in case of - * fragmented packets. */ - if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) - tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); - - if (type == IEEE80211_TKIP_P1_KEY) { - memcpy(outkey, ctx->p1k, sizeof(u16) * 5); - return; - } + const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); + u32 iv32 = get_unaligned_le32(&data[4]); + unsigned long flags; + + spin_lock_irqsave(&key->u.tkip.txlock, flags); + ieee80211_compute_tkip_p1k(key, iv32); + memcpy(p1k, ctx->p1k, sizeof(ctx->p1k)); + spin_unlock_irqrestore(&key->u.tkip.txlock, flags); +} +EXPORT_SYMBOL(ieee80211_get_tkip_p1k); - tkip_mixing_phase2(tk, ctx, iv16, outkey); +void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, + struct sk_buff *skb, u8 *p2k) +{ + struct ieee80211_key *key = (struct ieee80211_key *) + container_of(keyconf, struct ieee80211_key, conf); + const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; + struct tkip_ctx *ctx = &key->u.tkip.tx; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); + u32 iv32 = get_unaligned_le32(&data[4]); + u16 iv16 = data[2] | (data[0] << 8); + unsigned long flags; + + spin_lock_irqsave(&key->u.tkip.txlock, flags); + ieee80211_compute_tkip_p1k(key, iv32); + tkip_mixing_phase2(tk, ctx, iv16, p2k); + spin_unlock_irqrestore(&key->u.tkip.txlock, flags); } -EXPORT_SYMBOL(ieee80211_get_tkip_key); +EXPORT_SYMBOL(ieee80211_get_tkip_p2k); /* * Encrypt packet payload with TKIP using @key. @pos is a pointer to the @@ -204,19 +217,15 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key); */ int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, struct ieee80211_key *key, - u8 *pos, size_t payload_len, u8 *ta) + struct sk_buff *skb, + u8 *payload, size_t payload_len) { u8 rc4key[16]; - struct tkip_ctx *ctx = &key->u.tkip.tx; - const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; - - /* Calculate per-packet key */ - if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) - tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); - tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); + ieee80211_get_tkip_p2k(&key->conf, skb, rc4key); - return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); + return ieee80211_wep_encrypt_data(tfm, rc4key, 16, + payload, payload_len); } /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index 1cab9c86978..e3ecb659b90 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h @@ -13,11 +13,13 @@ #include #include "key.h" -u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); +u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key); int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, - struct ieee80211_key *key, - u8 *pos, size_t payload_len, u8 *ta); + struct ieee80211_key *key, + struct sk_buff *skb, + u8 *payload, size_t payload_len); + enum { TKIP_DECRYPT_OK = 0, TKIP_DECRYPT_NO_EXT_IV = -1, diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index d91c1a26630..4ded2ae48a5 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -171,6 +171,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_key *key = tx->key; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + unsigned long flags; unsigned int hdrlen; int len, tail; u8 *pos; @@ -198,11 +199,12 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) pos += hdrlen; /* Increase IV for the frame */ + spin_lock_irqsave(&key->u.tkip.txlock, flags); key->u.tkip.tx.iv16++; if (key->u.tkip.tx.iv16 == 0) key->u.tkip.tx.iv32++; - - pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); + pos = ieee80211_tkip_add_iv(pos, key); + spin_unlock_irqrestore(&key->u.tkip.txlock, flags); /* hwaccel - with software IV */ if (info->control.hw_key) @@ -211,9 +213,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) /* Add room for ICV */ skb_put(skb, TKIP_ICV_LEN); - hdr = (struct ieee80211_hdr *) skb->data; return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, - key, pos, len, hdr->addr2); + key, skb, pos, len); } -- cgit v1.2.3-70-g09d2 From 6cbab0d9139246405b2449ffebecc8c48d927a6e Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 15:45:26 +0200 Subject: b43: use switches for SSB specific code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 1 - drivers/net/wireless/b43/bus.h | 2 + drivers/net/wireless/b43/dma.c | 9 ++- drivers/net/wireless/b43/main.c | 144 +++++++++++++++++++++++++++------------ drivers/net/wireless/b43/phy_n.c | 40 ++++++++--- 5 files changed, 139 insertions(+), 57 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 666515e348b..08a28270bbb 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -726,7 +726,6 @@ enum { /* Data structure for one wireless device (802.11 core) */ struct b43_wldev { - struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */ struct b43_bus_dev *dev; struct b43_wl *wl; diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index a70b7b9a550..f3c30ebc642 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -2,7 +2,9 @@ #define B43_BUS_H_ enum b43_bus_type { +#ifdef CONFIG_B43_BCMA B43_BUS_BCMA, +#endif B43_BUS_SSB, }; diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 7a09a467339..ce572aebeff 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1055,7 +1055,14 @@ int b43_dma_init(struct b43_wldev *dev) err = b43_dma_set_mask(dev, dmamask); if (err) return err; - dma->translation = ssb_dma_translation(dev->sdev); + + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + dma->translation = ssb_dma_translation(dev->dev->sdev); + break; +#endif + } err = -ENOMEM; /* setup TX DMA channels. */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index b85a9737ecb..dd6d6523587 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1187,7 +1187,13 @@ void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode) { u32 macctl; - b43_ssb_wireless_core_reset(dev, gmode); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + b43_ssb_wireless_core_reset(dev, gmode); + break; +#endif + } /* Turn Analog ON, but only if we already know the PHY-type. * This protects against very early setup where we don't know the @@ -2624,11 +2630,17 @@ static int b43_gpio_init(struct b43_wldev *dev) if (dev->dev->core_rev >= 2) mask |= 0x0010; /* FIXME: This is redundant. */ - gpiodev = b43_ssb_gpio_dev(dev); - if (gpiodev) - ssb_write32(gpiodev, B43_GPIO_CONTROL, - (ssb_read32(gpiodev, B43_GPIO_CONTROL) - & mask) | set); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + gpiodev = b43_ssb_gpio_dev(dev); + if (gpiodev) + ssb_write32(gpiodev, B43_GPIO_CONTROL, + (ssb_read32(gpiodev, B43_GPIO_CONTROL) + & mask) | set); + break; +#endif + } return 0; } @@ -2638,9 +2650,15 @@ static void b43_gpio_cleanup(struct b43_wldev *dev) { struct ssb_device *gpiodev; - gpiodev = b43_ssb_gpio_dev(dev); - if (gpiodev) - ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + gpiodev = b43_ssb_gpio_dev(dev); + if (gpiodev) + ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); + break; +#endif + } } /* http://bcm-specs.sipsolutions.net/EnableMac */ @@ -2712,12 +2730,20 @@ out: /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) { - u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); - if (on) - tmslow |= B43_TMSLOW_MACPHYCLKEN; - else - tmslow &= ~B43_TMSLOW_MACPHYCLKEN; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); + u32 tmp; + + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + if (on) + tmp |= B43_TMSLOW_MACPHYCLKEN; + else + tmp &= ~B43_TMSLOW_MACPHYCLKEN; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + break; +#endif + } } static void b43_adjust_opmode(struct b43_wldev *dev) @@ -2956,8 +2982,14 @@ static int b43_chip_init(struct b43_wldev *dev) b43_mac_phy_clock_set(dev, true); - b43_write16(dev, B43_MMIO_POWERUP_DELAY, - dev->sdev->bus->chipco.fast_pwrup_delay); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + b43_write16(dev, B43_MMIO_POWERUP_DELAY, + dev->dev->sdev->bus->chipco.fast_pwrup_delay); + break; +#endif + } err = 0; b43dbg(dev->wl, "Chip initialized\n"); @@ -3473,21 +3505,27 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) static void b43_put_phy_into_reset(struct b43_wldev *dev) { - struct ssb_device *sdev = dev->sdev; - u32 tmslow; + u32 tmp; - tmslow = ssb_read32(sdev, SSB_TMSLOW); - tmslow &= ~B43_TMSLOW_GMODE; - tmslow |= B43_TMSLOW_PHYRESET; - tmslow |= SSB_TMSLOW_FGC; - ssb_write32(sdev, SSB_TMSLOW, tmslow); - msleep(1); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + tmp &= ~B43_TMSLOW_GMODE; + tmp |= B43_TMSLOW_PHYRESET; + tmp |= SSB_TMSLOW_FGC; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + msleep(1); + + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + tmp &= ~SSB_TMSLOW_FGC; + tmp |= B43_TMSLOW_PHYRESET; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + msleep(1); - tmslow = ssb_read32(sdev, SSB_TMSLOW); - tmslow &= ~SSB_TMSLOW_FGC; - tmslow |= B43_TMSLOW_PHYRESET; - ssb_write32(sdev, SSB_TMSLOW, tmslow); - msleep(1); + break; +#endif + } } static const char *band_to_string(enum ieee80211_band band) @@ -4347,7 +4385,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) /* Initialize a wireless core */ static int b43_wireless_core_init(struct b43_wldev *dev) { - struct ssb_bus *bus = dev->sdev->bus; struct ssb_sprom *sprom = dev->dev->bus_sprom; struct b43_phy *phy = &dev->phy; int err; @@ -4366,7 +4403,14 @@ static int b43_wireless_core_init(struct b43_wldev *dev) phy->ops->prepare_structs(dev); /* Enable IRQ routing to this device. */ - ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore, + dev->dev->sdev); + break; +#endif + } b43_imcfglo_timeouts_workaround(dev); b43_bluetooth_coext_disable(dev); @@ -4397,8 +4441,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev) if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ #ifdef CONFIG_SSB_DRIVER_PCICORE - if ((bus->bustype == SSB_BUSTYPE_PCI) && - (bus->pcicore.dev->id.revision <= 10)) + if (dev->dev->bus_type == B43_BUS_SSB && + dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && + dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */ #endif hf &= ~B43_HF_SKCFPUP; @@ -4764,8 +4809,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev) static int b43_wireless_core_attach(struct b43_wldev *dev) { struct b43_wl *wl = dev->wl; - struct ssb_bus *bus = dev->sdev->bus; - struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; + struct pci_dev *pdev = NULL; int err; bool have_2ghz_phy = 0, have_5ghz_phy = 0; @@ -4776,20 +4820,31 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) * that in core_init(), too. */ +#ifdef CONFIG_B43_SSB + if (dev->dev->bus_type == B43_BUS_SSB && + dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI) + pdev = dev->dev->sdev->bus->host_pci; +#endif + err = b43_bus_powerup(dev, 0); if (err) { b43err(wl, "Bus powerup failed\n"); goto out; } - /* Get the PHY type. */ - if (dev->dev->core_rev >= 5) { - u32 tmshigh; - tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); - have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); - have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); - } else - B43_WARN_ON(1); + /* Get the PHY type. */ + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + if (dev->dev->core_rev >= 5) { + u32 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); + have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); + have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); + } else + B43_WARN_ON(1); + break; +#endif + } dev->phy.gmode = have_2ghz_phy; dev->phy.radio_on = 1; @@ -4898,7 +4953,6 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl) wldev->use_pio = b43_modparam_pio; wldev->dev = dev; - wldev->sdev = dev->sdev; /* TODO: Remove when not needed */ wldev->wl = wl; b43_set_status(wldev, B43_STAT_UNINIT); wldev->bad_frames_preempt = modparam_bad_frames_preempt; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e7dfdac9e4d..41aea6a49af 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -603,17 +603,23 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev) /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force) { - u32 tmslow; + u32 tmp; if (dev->phy.type != B43_PHYTYPE_N) return; - tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); - if (force) - tmslow |= SSB_TMSLOW_FGC; - else - tmslow &= ~SSB_TMSLOW_FGC; - ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); + if (force) + tmp |= SSB_TMSLOW_FGC; + else + tmp &= ~SSB_TMSLOW_FGC; + ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); + break; +#endif + } } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ @@ -958,8 +964,15 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); - ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00, - 0xFC00); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco, + 0xFC00, 0xFC00); + break; +#endif + } + b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) & ~B43_MACCTL_GPOUTSMSK); @@ -3600,7 +3613,14 @@ int b43_phy_initn(struct b43_wldev *dev) if ((dev->phy.rev >= 3) && (sprom->boardflags_lo & B43_BFL_EXTLNA) && (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { - chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + chipco_set32(&dev->dev->sdev->bus->chipco, + SSB_CHIPCO_CHIPCTL, 0x40); + break; +#endif + } } nphy->deaf_count = 0; b43_nphy_tables_init(dev); -- cgit v1.2.3-70-g09d2 From 42c9a458965da2b74e772054fdc4bcdec0351da8 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 15:45:27 +0200 Subject: b43: handle BCMA in bus switches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 68 ++++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_n.c | 22 +++++++++++++ 2 files changed, 90 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index dd6d6523587..f80a53d23d7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1155,6 +1155,21 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) } } +#ifdef CONFIG_B43_BCMA +static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode) +{ + u32 flags = 0; + + if (gmode) + flags = B43_BCMA_IOCTL_GMODE; + flags |= B43_BCMA_IOCTL_PHY_CLKEN; + flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */ + b43_device_enable(dev, flags); + + /* TODO: reset PHY */ +} +#endif + static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) { struct ssb_device *sdev = dev->dev->sdev; @@ -1188,6 +1203,11 @@ void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode) u32 macctl; switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + b43_bcma_wireless_core_reset(dev, gmode); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: b43_ssb_wireless_core_reset(dev, gmode); @@ -2631,6 +2651,13 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0010; /* FIXME: This is redundant. */ switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, + (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, + BCMA_CC_GPIOCTL) & mask) | set); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: gpiodev = b43_ssb_gpio_dev(dev); @@ -2651,6 +2678,12 @@ static void b43_gpio_cleanup(struct b43_wldev *dev) struct ssb_device *gpiodev; switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, + 0); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: gpiodev = b43_ssb_gpio_dev(dev); @@ -2733,6 +2766,16 @@ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) u32 tmp; switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL); + if (on) + tmp |= B43_BCMA_IOCTL_MACPHYCLKEN; + else + tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN; + bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); @@ -2983,6 +3026,12 @@ static int b43_chip_init(struct b43_wldev *dev) b43_mac_phy_clock_set(dev, true); switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + /* FIXME: 0xE74 is quite common, but should be read from CC */ + b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: b43_write16(dev, B43_MMIO_POWERUP_DELAY, @@ -3508,6 +3557,12 @@ static void b43_put_phy_into_reset(struct b43_wldev *dev) u32 tmp; switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + b43err(dev->wl, + "Putting PHY into reset not supported on BCMA\n"); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); @@ -4404,6 +4459,12 @@ static int b43_wireless_core_init(struct b43_wldev *dev) /* Enable IRQ routing to this device. */ switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci, + dev->dev->bdev, true); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore, @@ -4834,6 +4895,13 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) /* Get the PHY type. */ switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + /* FIXME */ + have_2ghz_phy = 1; + have_5ghz_phy = 0; + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: if (dev->dev->core_rev >= 5) { diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 41aea6a49af..95c28f584ed 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -609,6 +609,16 @@ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force) return; switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL); + if (force) + tmp |= BCMA_IOCTL_FGC; + else + tmp &= ~BCMA_IOCTL_FGC; + bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); @@ -965,6 +975,12 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, + 0xFC00, 0xFC00); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco, @@ -3614,6 +3630,12 @@ int b43_phy_initn(struct b43_wldev *dev) (sprom->boardflags_lo & B43_BFL_EXTLNA) && (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_cc_set32(&dev->dev->bdev->bus->drv_cc, + BCMA_CC_CHIPCTL, 0x40); + break; +#endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: chipco_set32(&dev->dev->sdev->bus->chipco, -- cgit v1.2.3-70-g09d2 From 74abacb6b5b91141eb8963faa2f22b3f1bd7c68d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 15:45:28 +0200 Subject: b43: bus: add helpers for getting/setting wldev from/in bus core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 29 +++++++++++++++++++++++++++++ drivers/net/wireless/b43/bus.h | 3 +++ drivers/net/wireless/b43/main.c | 6 +++--- 3 files changed, 35 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index c45c76dc49c..a5e61a9fb53 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -225,3 +225,32 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) return dev; } #endif /* CONFIG_B43_SSB */ + +void *b43_bus_get_wldev(struct b43_bus_dev *dev) +{ + switch (dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + return bcma_get_drvdata(dev->bdev); +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + return ssb_get_drvdata(dev->sdev); +#endif + } + return NULL; +} + +void b43_bus_set_wldev(struct b43_bus_dev *dev, void *wldev) +{ + switch (dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + bcma_set_drvdata(dev->bdev, wldev); +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + ssb_set_drvdata(dev->sdev, wldev); +#endif + } +} diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h index f3c30ebc642..184c9565927 100644 --- a/drivers/net/wireless/b43/bus.h +++ b/drivers/net/wireless/b43/bus.h @@ -64,4 +64,7 @@ static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core); struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); +void *b43_bus_get_wldev(struct b43_bus_dev *dev); +void b43_bus_set_wldev(struct b43_bus_dev *dev, void *data); + #endif /* B43_BUS_H_ */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index f80a53d23d7..f0b9dd14ea2 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -5000,13 +5000,13 @@ static void b43_one_core_detach(struct b43_bus_dev *dev) /* Do not cancel ieee80211-workqueue based work here. * See comment in b43_remove(). */ - wldev = ssb_get_drvdata(dev->sdev); + wldev = b43_bus_get_wldev(dev); wl = wldev->wl; b43_debugfs_remove_device(wldev); b43_wireless_core_detach(wldev); list_del(&wldev->list); wl->nr_devs--; - ssb_set_drvdata(dev->sdev, NULL); + b43_bus_set_wldev(dev, NULL); kfree(wldev); } @@ -5032,7 +5032,7 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl) list_add(&wldev->list, &wl->devlist); wl->nr_devs++; - ssb_set_drvdata(dev->sdev, wldev); + b43_bus_set_wldev(dev, wldev); b43_debugfs_add_device(wldev); out: -- cgit v1.2.3-70-g09d2 From 6ff1e5cf70abbe04b261b4ccd9696e1ab6785086 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 17:41:55 +0200 Subject: b43: change selecting ucode for newer cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Older cores had unique PHY. This is not true anymore for newer ones. For example core rev 16 can be LP, SSLPN or N (PHY). Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index f0b9dd14ea2..cddc5a87df7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2160,20 +2160,28 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) int err; /* Get microcode */ - if ((rev >= 5) && (rev <= 10)) + if ((rev >= 5) && (rev <= 10)) { filename = "ucode5"; - else if ((rev >= 11) && (rev <= 12)) + } else if ((rev >= 11) && (rev <= 12)) { filename = "ucode11"; - else if (rev == 13) + } else if (rev == 13) { filename = "ucode13"; - else if (rev == 14) + } else if (rev == 14) { filename = "ucode14"; - else if (rev == 15) + } else if (rev == 15) { filename = "ucode15"; - else if ((rev >= 16) && (rev <= 20)) - filename = "ucode16_mimo"; - else - goto err_no_ucode; + } else { + switch (dev->phy.type) { + case B43_PHYTYPE_N: + if (rev >= 16) + filename = "ucode16_mimo"; + else + goto err_no_ucode; + break; + default: + goto err_no_ucode; + } + } err = b43_do_request_fw(ctx, filename, &fw->ucode); if (err) goto err_load; -- cgit v1.2.3-70-g09d2 From 8c8b964c20adb79a7deb58dc9d55754b0ca1233c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 18:05:14 +0200 Subject: b43: select BLOCKIO for BCMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want PIO as fallback for BCMA as well. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index d5add69aac8..21b079898eb 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -90,6 +90,12 @@ config B43_SDIO #Data transfers to the device via PIO. We want it as a fallback even # if we can do DMA. +config B43_BCMA_PIO + bool + depends on B43_BCMA + select BCMA_BLOCKIO + default y + config B43_PIO bool depends on B43 -- cgit v1.2.3-70-g09d2 From 3fd48508d0d3d8e5423cab6b52a3b818085b6245 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 20:27:24 +0200 Subject: b43: use radio ID reading code to older cores only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer ones need separated way Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index cddc5a87df7..074765a1e67 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4218,22 +4218,30 @@ static int b43_phy_versioning(struct b43_wldev *dev) analog_type, phy_type, phy_rev); /* Get RADIO versioning */ - if (dev->dev->chip_id == 0x4317) { - if (dev->dev->chip_rev == 0) - tmp = 0x3205017F; - else if (dev->dev->chip_rev == 1) - tmp = 0x4205017F; - else - tmp = 0x5205017F; + if (dev->dev->core_rev >= 24) { + /* TODO */ } else { - b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); - tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); - b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); - tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16; - } - radio_manuf = (tmp & 0x00000FFF); - radio_ver = (tmp & 0x0FFFF000) >> 12; - radio_rev = (tmp & 0xF0000000) >> 28; + if (dev->dev->chip_id == 0x4317) { + if (dev->dev->chip_rev == 0) + tmp = 0x3205017F; + else if (dev->dev->chip_rev == 1) + tmp = 0x4205017F; + else + tmp = 0x5205017F; + } else { + b43_write16(dev, B43_MMIO_RADIO_CONTROL, + B43_RADIOCTL_ID); + tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); + b43_write16(dev, B43_MMIO_RADIO_CONTROL, + B43_RADIOCTL_ID); + tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) + << 16; + } + radio_manuf = (tmp & 0x00000FFF); + radio_ver = (tmp & 0x0FFFF000) >> 12; + radio_rev = (tmp & 0xF0000000) >> 28; + } + if (radio_manuf != 0x17F /* Broadcom */) unsupported = 1; switch (phy_type) { -- cgit v1.2.3-70-g09d2 From 544e5d8bcd7ab305494e57cfa388b2d06a43c520 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 6 Jul 2011 20:27:25 +0200 Subject: b43: read radio ID on new cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 074765a1e67..bff08707c43 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4219,7 +4219,19 @@ static int b43_phy_versioning(struct b43_wldev *dev) /* Get RADIO versioning */ if (dev->dev->core_rev >= 24) { - /* TODO */ + u16 radio24[3]; + + for (tmp = 0; tmp < 3; tmp++) { + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp); + radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); + } + + /* Broadcom uses "id" for our "ver" and has separated "ver" */ + /* radio_ver = (radio24[0] & 0xF0) >> 4; */ + + radio_manuf = 0x17F; + radio_ver = (radio24[2] << 8) | radio24[1]; + radio_rev = (radio24[0] & 0xF); } else { if (dev->dev->chip_id == 0x4317) { if (dev->dev->chip_rev == 0) -- cgit v1.2.3-70-g09d2 From 1d738e64f3d957d56c1b51e64ebdef986a8760e3 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Jul 2011 15:25:27 +0200 Subject: b43: LCN-PHY add place for new PHY support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LCN-PHY was found in 14e4:4727 card. It uses LCN/1 and 0x2064/1 radio. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 8 +++++ drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/main.c | 10 ++++++ drivers/net/wireless/b43/phy_lcn.c | 52 +++++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_lcn.h | 14 +++++++++ drivers/net/wireless/b43/tables_phy_lcn.c | 34 ++++++++++++++++++++ drivers/net/wireless/b43/tables_phy_lcn.h | 6 ++++ 7 files changed, 125 insertions(+) create mode 100644 drivers/net/wireless/b43/phy_lcn.c create mode 100644 drivers/net/wireless/b43/phy_lcn.h create mode 100644 drivers/net/wireless/b43/tables_phy_lcn.c create mode 100644 drivers/net/wireless/b43/tables_phy_lcn.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 21b079898eb..d2293dcc117 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -131,6 +131,14 @@ config B43_PHY_HT Say N, this is BROKEN and crashes driver. +config B43_PHY_LCN + bool "Support for LCN-PHY devices (BROKEN)" + depends on B43 && BROKEN + ---help--- + Support for the LCN-PHY. + + Say N, this is BROKEN and crashes driver. + # This config option automatically enables b43 LEDS support, # if it's possible. config B43_LEDS diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 1b25604be54..4648bbf76ab 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -13,6 +13,7 @@ b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o b43-$(CONFIG_B43_PHY_HT) += phy_ht.o b43-$(CONFIG_B43_PHY_HT) += tables_phy_ht.o b43-$(CONFIG_B43_PHY_HT) += radio_2059.o +b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o b43-y += sysfs.o b43-y += xmit.o b43-y += lo.o diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index bff08707c43..5a3454ab038 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4204,6 +4204,12 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (phy_rev > 1) unsupported = 1; break; +#endif +#ifdef CONFIG_B43_PHY_LCN + case B43_PHYTYPE_LCN: + if (phy_rev > 1) + unsupported = 1; + break; #endif default: unsupported = 1; @@ -4285,6 +4291,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (radio_ver != 0x2059) unsupported = 1; break; + case B43_PHYTYPE_LCN: + if (radio_ver != 0x2064) + unsupported = 1; + break; default: B43_WARN_ON(1); } diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c new file mode 100644 index 00000000000..9f7dbbd5ced --- /dev/null +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -0,0 +1,52 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n LCN-PHY support + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include + +#include "b43.h" +#include "phy_lcn.h" +#include "tables_phy_lcn.h" +#include "main.h" + +/************************************************** + * PHY ops struct. + **************************************************/ + +const struct b43_phy_operations b43_phyops_lcn = { + /* + .allocate = b43_phy_lcn_op_allocate, + .free = b43_phy_lcn_op_free, + .prepare_structs = b43_phy_lcn_op_prepare_structs, + .init = b43_phy_lcn_op_init, + .phy_read = b43_phy_lcn_op_read, + .phy_write = b43_phy_lcn_op_write, + .phy_maskset = b43_phy_lcn_op_maskset, + .radio_read = b43_phy_lcn_op_radio_read, + .radio_write = b43_phy_lcn_op_radio_write, + .software_rfkill = b43_phy_lcn_op_software_rfkill, + .switch_analog = b43_phy_lcn_op_switch_analog, + .switch_channel = b43_phy_lcn_op_switch_channel, + .get_default_chan = b43_phy_lcn_op_get_default_chan, + .recalc_txpower = b43_phy_lcn_op_recalc_txpower, + .adjust_txpower = b43_phy_lcn_op_adjust_txpower, + */ +}; diff --git a/drivers/net/wireless/b43/phy_lcn.h b/drivers/net/wireless/b43/phy_lcn.h new file mode 100644 index 00000000000..c046c2a6cab --- /dev/null +++ b/drivers/net/wireless/b43/phy_lcn.h @@ -0,0 +1,14 @@ +#ifndef B43_PHY_LCN_H_ +#define B43_PHY_LCN_H_ + +#include "phy_common.h" + + +struct b43_phy_lcn { +}; + + +struct b43_phy_operations; +extern const struct b43_phy_operations b43_phyops_lcn; + +#endif /* B43_PHY_LCN_H_ */ \ No newline at end of file diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c new file mode 100644 index 00000000000..40c1d0915dd --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -0,0 +1,34 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n LCN-PHY data tables + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "tables_phy_lcn.h" +#include "phy_common.h" +#include "phy_lcn.h" + +/************************************************** + * Tables ops. + **************************************************/ + +void b43_phy_lcn_tables_init(struct b43_wldev *dev) +{ +} diff --git a/drivers/net/wireless/b43/tables_phy_lcn.h b/drivers/net/wireless/b43/tables_phy_lcn.h new file mode 100644 index 00000000000..5e31b15b81e --- /dev/null +++ b/drivers/net/wireless/b43/tables_phy_lcn.h @@ -0,0 +1,6 @@ +#ifndef B43_TABLES_PHY_LCN_H_ +#define B43_TABLES_PHY_LCN_H_ + +void b43_phy_lcn_tables_init(struct b43_wldev *dev); + +#endif /* B43_TABLES_PHY_LCN_H_ */ -- cgit v1.2.3-70-g09d2 From 8b9bda759e5b7c042c2b3ae852aaa332c0ee4495 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Jul 2011 18:58:24 +0200 Subject: b43: define firmwares for HT and LCN PHYs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were uploading different firmwares to the hardware until finding responding one. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5a3454ab038..fceb5716e9c 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2159,6 +2159,8 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) u32 tmshigh; int err; + /* Files for HT and LCN were found by trying one by one */ + /* Get microcode */ if ((rev >= 5) && (rev <= 10)) { filename = "ucode5"; @@ -2178,6 +2180,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) else goto err_no_ucode; break; + case B43_PHYTYPE_HT: + if (rev == 29) + filename = "ucode29_mimo"; + else + goto err_no_ucode; + break; + case B43_PHYTYPE_LCN: + if (rev == 24) + filename = "ucode24_mimo"; + else + goto err_no_ucode; + break; default: goto err_no_ucode; } @@ -2240,6 +2254,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) else goto err_no_initvals; break; + case B43_PHYTYPE_HT: + if (rev == 29) + filename = "ht0initvals29"; + else + goto err_no_initvals; + break; + case B43_PHYTYPE_LCN: + if (rev == 24) + filename = "lcn0initvals24"; + else + goto err_no_initvals; + break; default: goto err_no_initvals; } @@ -2287,6 +2313,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) else goto err_no_initvals; break; + case B43_PHYTYPE_HT: + if (rev == 29) + filename = "ht0bsinitvals29"; + else + goto err_no_initvals; + break; + case B43_PHYTYPE_LCN: + if (rev == 24) + filename = "lcn0bsinitvals24"; + else + goto err_no_initvals; + break; default: goto err_no_initvals; } @@ -4976,6 +5014,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) #endif case B43_PHYTYPE_G: case B43_PHYTYPE_N: + case B43_PHYTYPE_HT: + case B43_PHYTYPE_LCN: have_2ghz_phy = 1; break; default: -- cgit v1.2.3-70-g09d2 From 58eb7ff3dc056c6935c1cedee365ccf554000f45 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Jul 2011 18:58:25 +0200 Subject: b43: LCN-PHY: include new PHY in common code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_common.c | 6 ++++++ drivers/net/wireless/b43/phy_common.h | 3 +++ 2 files changed, 9 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 9705950f059..101957512bc 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -32,6 +32,7 @@ #include "phy_n.h" #include "phy_lp.h" #include "phy_ht.h" +#include "phy_lcn.h" #include "b43.h" #include "main.h" @@ -63,6 +64,11 @@ int b43_phy_allocate(struct b43_wldev *dev) case B43_PHYTYPE_HT: #ifdef CONFIG_B43_PHY_HT phy->ops = &b43_phyops_ht; +#endif + break; + case B43_PHYTYPE_LCN: +#ifdef CONFIG_B43_PHY_LCN + phy->ops = &b43_phyops_lcn; #endif break; } diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 47dcb800a3c..aa77ba612a9 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -195,6 +195,7 @@ struct b43_phy_g; struct b43_phy_n; struct b43_phy_lp; struct b43_phy_ht; +struct b43_phy_lcn; struct b43_phy { /* Hardware operation callbacks. */ @@ -219,6 +220,8 @@ struct b43_phy { struct b43_phy_lp *lp; /* HT-PHY specific information */ struct b43_phy_ht *ht; + /* LCN-PHY specific information */ + struct b43_phy_lcn *lcn; }; /* Band support flags. */ -- cgit v1.2.3-70-g09d2 From 565dfefbe196206bc1e40bf92e7c5d53e9d9f706 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 7 Jul 2011 23:33:38 +0530 Subject: ath9k_htc: do not configure filter before driver is started Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 7b779689543..7212acb2bd6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1294,11 +1294,16 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, u32 rfilt; mutex_lock(&priv->mutex); - ath9k_htc_ps_wakeup(priv); - changed_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS; + if (priv->op_flags & OP_INVALID) { + ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_ANY, + "Unable to configure filter on invalid state\n"); + return; + } + ath9k_htc_ps_wakeup(priv); + priv->rxfilter = *total_flags; rfilt = ath9k_htc_calcrxfilter(priv); ath9k_hw_setrxfilter(priv->ah, rfilt); -- cgit v1.2.3-70-g09d2 From 21a18f284b00f977b355a2901d0ca6dae929b370 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Jul 2011 20:06:56 +0200 Subject: b43: HT-PHY: define dummy TX power functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without them we get Oops with NULL pointer Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_ht.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 30b19c61037..29821036bad 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -373,6 +373,16 @@ static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg, b43_write16(dev, B43_MMIO_RADIO24_DATA, value); } +static enum b43_txpwr_result +b43_phy_ht_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi) +{ + return B43_TXPWR_RES_DONE; +} + +static void b43_phy_ht_op_adjust_txpower(struct b43_wldev *dev) +{ +} + /************************************************** * PHY ops struct. **************************************************/ @@ -391,8 +401,6 @@ const struct b43_phy_operations b43_phyops_ht = { .switch_analog = b43_phy_ht_op_switch_analog, .switch_channel = b43_phy_ht_op_switch_channel, .get_default_chan = b43_phy_ht_op_get_default_chan, - /* .recalc_txpower = b43_phy_ht_op_recalc_txpower, .adjust_txpower = b43_phy_ht_op_adjust_txpower, - */ }; -- cgit v1.2.3-70-g09d2 From cae561473e87fd01b07d980c643acd51c07e1f64 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 7 Jul 2011 21:58:10 +0200 Subject: net/b43: don't return IRQ_HANDLED if nothing was done Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index fceb5716e9c..8bcda5084de 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1964,7 +1964,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; reason &= dev->irq_mask; if (!reason) - return IRQ_HANDLED; + return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) & 0x0001DC00; -- cgit v1.2.3-70-g09d2 From 69f7235fe69be5c644f934566f3b972988e71ee4 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 7 Jul 2011 23:01:25 +0200 Subject: carl9170: Implement tx_frames_pending mac80211 callback function Implementing this callback function will cause mac80211 refrain from going to powersave state when there are still untransmitted TX frames in the queues. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index d2b9f1256bc..a61cf6781d5 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1484,6 +1484,13 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, } } +static bool carl9170_tx_frames_pending(struct ieee80211_hw *hw) +{ + struct ar9170 *ar = hw->priv; + + return !!atomic_read(&ar->tx_total_queued); +} + static const struct ieee80211_ops carl9170_ops = { .start = carl9170_op_start, .stop = carl9170_op_stop, @@ -1504,6 +1511,7 @@ static const struct ieee80211_ops carl9170_ops = { .get_survey = carl9170_op_get_survey, .get_stats = carl9170_op_get_stats, .ampdu_action = carl9170_op_ampdu_action, + .tx_frames_pending = carl9170_tx_frames_pending, }; void *carl9170_alloc(size_t priv_size) -- cgit v1.2.3-70-g09d2 From b988a887a448be479696544de31656754c133f30 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:13:17 -0400 Subject: ath5k: remove PRIV_ENTRY and PRIV_ASSIGN macros, they obfuscate the code Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/trace.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h index 2de68adb624..235e0768ce1 100644 --- a/drivers/net/wireless/ath/ath5k/trace.h +++ b/drivers/net/wireless/ath/ath5k/trace.h @@ -12,9 +12,6 @@ static inline void trace_ ## name(proto) {} struct sk_buff; -#define PRIV_ENTRY __field(struct ath5k_softc *, priv) -#define PRIV_ASSIGN __entry->priv = priv - #undef TRACE_SYSTEM #define TRACE_SYSTEM ath5k @@ -22,12 +19,12 @@ TRACE_EVENT(ath5k_rx, TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb), TP_ARGS(priv, skb), TP_STRUCT__entry( - PRIV_ENTRY + __field(struct ath5k_softc *, priv) __field(unsigned long, skbaddr) __dynamic_array(u8, frame, skb->len) ), TP_fast_assign( - PRIV_ASSIGN; + __entry->priv = priv; __entry->skbaddr = (unsigned long) skb; memcpy(__get_dynamic_array(frame), skb->data, skb->len); ), @@ -43,14 +40,14 @@ TRACE_EVENT(ath5k_tx, TP_ARGS(priv, skb, q), TP_STRUCT__entry( - PRIV_ENTRY + __field(struct ath5k_softc *, priv) __field(unsigned long, skbaddr) __field(u8, qnum) __dynamic_array(u8, frame, skb->len) ), TP_fast_assign( - PRIV_ASSIGN; + __entry->priv = priv; __entry->skbaddr = (unsigned long) skb; __entry->qnum = (u8) q->qnum; memcpy(__get_dynamic_array(frame), skb->data, skb->len); @@ -69,7 +66,7 @@ TRACE_EVENT(ath5k_tx_complete, TP_ARGS(priv, skb, q, ts), TP_STRUCT__entry( - PRIV_ENTRY + __field(struct ath5k_softc *, priv) __field(unsigned long, skbaddr) __field(u8, qnum) __field(u8, ts_status) @@ -78,7 +75,7 @@ TRACE_EVENT(ath5k_tx_complete, ), TP_fast_assign( - PRIV_ASSIGN; + __entry->priv = priv; __entry->skbaddr = (unsigned long) skb; __entry->qnum = (u8) q->qnum; __entry->ts_status = ts->ts_status; -- cgit v1.2.3-70-g09d2 From 0a5d381348fcb12d27289b3a66824fb3481911ce Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:13:24 -0400 Subject: ath5k: replace spaces with tabs as suggested by checkpatch.pl Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 114 +++++++++++++++--------------- drivers/net/wireless/ath/ath5k/base.h | 2 +- drivers/net/wireless/ath/ath5k/eeprom.c | 8 +-- drivers/net/wireless/ath/ath5k/initvals.c | 12 ++-- drivers/net/wireless/ath/ath5k/phy.c | 6 +- drivers/net/wireless/ath/ath5k/reg.h | 34 ++++----- drivers/net/wireless/ath/ath5k/reset.c | 2 +- drivers/net/wireless/ath/ath5k/rfbuffer.h | 4 +- drivers/net/wireless/ath/ath5k/rfgain.h | 2 +- drivers/net/wireless/ath/ath5k/sysfs.c | 4 +- 10 files changed, 94 insertions(+), 94 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index c4c02d5145c..79e11ff40fc 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -39,34 +39,34 @@ #include "../ath.h" /* PCI IDs */ -#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ -#define PCI_DEVICE_ID_ATHEROS_AR5311 0x0011 /* AR5311 */ -#define PCI_DEVICE_ID_ATHEROS_AR5211 0x0012 /* AR5211 */ -#define PCI_DEVICE_ID_ATHEROS_AR5212 0x0013 /* AR5212 */ -#define PCI_DEVICE_ID_3COM_3CRDAG675 0x0013 /* 3CRDAG675 (Atheros AR5212) */ -#define PCI_DEVICE_ID_3COM_2_3CRPAG175 0x0013 /* 3CRPAG175 (Atheros AR5212) */ -#define PCI_DEVICE_ID_ATHEROS_AR5210_AP 0x0207 /* AR5210 (Early) */ +#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ +#define PCI_DEVICE_ID_ATHEROS_AR5311 0x0011 /* AR5311 */ +#define PCI_DEVICE_ID_ATHEROS_AR5211 0x0012 /* AR5211 */ +#define PCI_DEVICE_ID_ATHEROS_AR5212 0x0013 /* AR5212 */ +#define PCI_DEVICE_ID_3COM_3CRDAG675 0x0013 /* 3CRDAG675 (Atheros AR5212) */ +#define PCI_DEVICE_ID_3COM_2_3CRPAG175 0x0013 /* 3CRPAG175 (Atheros AR5212) */ +#define PCI_DEVICE_ID_ATHEROS_AR5210_AP 0x0207 /* AR5210 (Early) */ #define PCI_DEVICE_ID_ATHEROS_AR5212_IBM 0x1014 /* AR5212 (IBM MiniPCI) */ -#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT 0x1107 /* AR5210 (no eeprom) */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT 0x1113 /* AR5212 (no eeprom) */ -#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT 0x1112 /* AR5211 (no eeprom) */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA 0xf013 /* AR5212 (emulation board) */ -#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY 0xff12 /* AR5211 (emulation board) */ -#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B 0xf11b /* AR5211 (emulation board) */ -#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ -#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ -#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8 0x0058 /* AR5312 WMAC (AP43-030) */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0014 0x0014 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0015 0x0015 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0016 0x0016 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0017 0x0017 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0018 0x0018 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0019 0x0019 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR2413 0x001a /* AR2413 (Griffin-lite) */ -#define PCI_DEVICE_ID_ATHEROS_AR5413 0x001b /* AR5413 (Eagle) */ -#define PCI_DEVICE_ID_ATHEROS_AR5424 0x001c /* AR5424 (Condor PCI-E) */ -#define PCI_DEVICE_ID_ATHEROS_AR5416 0x0023 /* AR5416 */ -#define PCI_DEVICE_ID_ATHEROS_AR5418 0x0024 /* AR5418 */ +#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT 0x1107 /* AR5210 (no eeprom) */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT 0x1113 /* AR5212 (no eeprom) */ +#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT 0x1112 /* AR5211 (no eeprom) */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA 0xf013 /* AR5212 (emulation board) */ +#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY 0xff12 /* AR5211 (emulation board) */ +#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B 0xf11b /* AR5211 (emulation board) */ +#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ +#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ +#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8 0x0058 /* AR5312 WMAC (AP43-030) */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_0014 0x0014 /* AR5212 compatible */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_0015 0x0015 /* AR5212 compatible */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_0016 0x0016 /* AR5212 compatible */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_0017 0x0017 /* AR5212 compatible */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_0018 0x0018 /* AR5212 compatible */ +#define PCI_DEVICE_ID_ATHEROS_AR5212_0019 0x0019 /* AR5212 compatible */ +#define PCI_DEVICE_ID_ATHEROS_AR2413 0x001a /* AR2413 (Griffin-lite) */ +#define PCI_DEVICE_ID_ATHEROS_AR5413 0x001b /* AR5413 (Eagle) */ +#define PCI_DEVICE_ID_ATHEROS_AR5424 0x001c /* AR5424 (Condor PCI-E) */ +#define PCI_DEVICE_ID_ATHEROS_AR5416 0x0023 /* AR5416 */ +#define PCI_DEVICE_ID_ATHEROS_AR5418 0x0024 /* AR5418 */ /****************************\ GENERIC DRIVER DEFINITIONS @@ -374,7 +374,7 @@ struct ath5k_srev_name { * they are exclusive. * */ -#define MODULATION_XR 0x00000200 +#define MODULATION_XR 0x00000200 /* * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s @@ -495,9 +495,9 @@ enum ath5k_tx_queue { */ enum ath5k_tx_queue_subtype { AR5K_WME_AC_BK = 0, /*Background traffic*/ - AR5K_WME_AC_BE, /*Best-effort (normal) traffic)*/ - AR5K_WME_AC_VI, /*Video traffic*/ - AR5K_WME_AC_VO, /*Voice traffic*/ + AR5K_WME_AC_BE, /*Best-effort (normal) traffic)*/ + AR5K_WME_AC_VI, /*Video traffic*/ + AR5K_WME_AC_VO, /*Voice traffic*/ }; /* @@ -791,47 +791,47 @@ extern int ath5k_modparam_nohwcrypt; * enum ath5k_int - Hardware interrupt masks helpers * * @AR5K_INT_RX: mask to identify received frame interrupts, of type - * AR5K_ISR_RXOK or AR5K_ISR_RXERR + * AR5K_ISR_RXOK or AR5K_ISR_RXERR * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?) * @AR5K_INT_RXNOFRM: No frame received (?) * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The - * Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's - * LinkPtr is NULL. For more details, refer to: - * http://www.freepatentsonline.com/20030225739.html + * Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's + * LinkPtr is NULL. For more details, refer to: + * http://www.freepatentsonline.com/20030225739.html * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors). - * Note that Rx overrun is not always fatal, on some chips we can continue - * operation without reseting the card, that's why int_fatal is not - * common for all chips. + * Note that Rx overrun is not always fatal, on some chips we can continue + * operation without reseting the card, that's why int_fatal is not + * common for all chips. * @AR5K_INT_TX: mask to identify received frame interrupts, of type - * AR5K_ISR_TXOK or AR5K_ISR_TXERR + * AR5K_ISR_TXOK or AR5K_ISR_TXERR * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?) * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold - * We currently do increments on interrupt by - * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 + * We currently do increments on interrupt by + * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 * @AR5K_INT_MIB: Indicates the either Management Information Base counters or * one of the PHY error counters reached the maximum value and should be * read and cleared. * @AR5K_INT_RXPHY: RX PHY Error * @AR5K_INT_RXKCM: RX Key cache miss * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a - * beacon that must be handled in software. The alternative is if you - * have VEOL support, in that case you let the hardware deal with things. + * beacon that must be handled in software. The alternative is if you + * have VEOL support, in that case you let the hardware deal with things. * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing - * beacons from the AP have associated with, we should probably try to - * reassociate. When in IBSS mode this might mean we have not received - * any beacons from any local stations. Note that every station in an - * IBSS schedules to send beacons at the Target Beacon Transmission Time - * (TBTT) with a random backoff. + * beacons from the AP have associated with, we should probably try to + * reassociate. When in IBSS mode this might mean we have not received + * any beacons from any local stations. Note that every station in an + * IBSS schedules to send beacons at the Target Beacon Transmission Time + * (TBTT) with a random backoff. * @AR5K_INT_BNR: Beacon Not Ready interrupt - ?? * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now - * until properly handled + * until properly handled * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA - * errors. These types of errors we can enable seem to be of type - * AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR. + * errors. These types of errors we can enable seem to be of type + * AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR. * @AR5K_INT_GLOBAL: Used to clear and set the IER * @AR5K_INT_NOCARD: signals the card has been removed * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same - * bit value + * bit value * * These are mapped to take advantage of some common bits * between the MACs, to be able to set intr properties @@ -968,9 +968,9 @@ enum ath5k_capability_type { AR5K_CAP_MCAST_KEYSRCH = 14, /* Supports multicast key search */ AR5K_CAP_TSF_ADJUST = 15, /* Supports beacon tsf adjust */ AR5K_CAP_XR = 16, /* Supports XR mode */ - AR5K_CAP_WME_TKIPMIC = 17, /* Supports TKIP MIC when using WMM */ - AR5K_CAP_CHAN_HALFRATE = 18, /* Supports half rate channels */ - AR5K_CAP_CHAN_QUARTERRATE = 19, /* Supports quarter rate channels */ + AR5K_CAP_WME_TKIPMIC = 17, /* Supports TKIP MIC when using WMM */ + AR5K_CAP_CHAN_HALFRATE = 18, /* Supports half rate channels */ + AR5K_CAP_CHAN_QUARTERRATE = 19, /* Supports quarter rate channels */ AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */ }; @@ -1362,12 +1362,12 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah) { - return &ah->common; + return &ah->common; } static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah) { - return &(ath5k_hw_common(ah)->regulatory); + return &(ath5k_hw_common(ah)->regulatory); } #ifdef CONFIG_ATHEROS_AR231X diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index b294f330501..3016562a771 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -251,7 +251,7 @@ struct ath5k_softc { unsigned int nexttbtt; /* next beacon time in TU */ struct ath5k_txq *cabq; /* content after beacon */ - int power_level; /* Requested tx power in dbm */ + int power_level; /* Requested tx power in dbm */ bool assoc; /* associate state */ bool enable_beacon; /* true if beacons are on */ diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 1fef84f87c7..4198f4ef88d 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -223,14 +223,14 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, ah->ah_ant_ctl[mode][AR5K_ANT_CTL] = (ee->ee_ant_control[mode][0] << 4); ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] = - ee->ee_ant_control[mode][1] | - (ee->ee_ant_control[mode][2] << 6) | + ee->ee_ant_control[mode][1] | + (ee->ee_ant_control[mode][2] << 6) | (ee->ee_ant_control[mode][3] << 12) | (ee->ee_ant_control[mode][4] << 18) | (ee->ee_ant_control[mode][5] << 24); ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] = - ee->ee_ant_control[mode][6] | - (ee->ee_ant_control[mode][7] << 6) | + ee->ee_ant_control[mode][6] | + (ee->ee_ant_control[mode][7] << 6) | (ee->ee_ant_control[mode][8] << 12) | (ee->ee_ant_control[mode][9] << 18) | (ee->ee_ant_control[mode][10] << 24); diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c index e49340d18df..4bfdc2e20df 100644 --- a/drivers/net/wireless/ath/ath5k/initvals.c +++ b/drivers/net/wireless/ath/ath5k/initvals.c @@ -113,8 +113,8 @@ static const struct ath5k_ini ar5210_ini[] = { { AR5K_PHY(28), 0x0000000f }, { AR5K_PHY(29), 0x00000080 }, { AR5K_PHY(30), 0x00000004 }, - { AR5K_PHY(31), 0x00000018 }, /* 0x987c */ - { AR5K_PHY(64), 0x00000000 }, /* 0x9900 */ + { AR5K_PHY(31), 0x00000018 }, /* 0x987c */ + { AR5K_PHY(64), 0x00000000 }, /* 0x9900 */ { AR5K_PHY(65), 0x00000000 }, { AR5K_PHY(66), 0x00000000 }, { AR5K_PHY(67), 0x00800000 }, @@ -549,7 +549,7 @@ static const struct ath5k_ini ar5212_ini_common_start[] = { { AR5K_DIAG_SW_5211, 0x00000000 }, { AR5K_ADDAC_TEST, 0x00000000 }, { AR5K_DEFAULT_ANTENNA, 0x00000000 }, - { AR5K_FRAME_CTL_QOSM, 0x000fc78f }, + { AR5K_FRAME_CTL_QOSM, 0x000fc78f }, { AR5K_XRMODE, 0x2a82301a }, { AR5K_XRDELAY, 0x05dc01e0 }, { AR5K_XRTIMEOUT, 0x1f402710 }, @@ -760,9 +760,9 @@ static const struct ath5k_ini_mode rf5111_ini_mode_end[] = { static const struct ath5k_ini rf5111_ini_common_end[] = { { AR5K_DCU_FP, 0x00000000 }, - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY_ADC_CTL, 0x00022ffe }, - { 0x983c, 0x00020100 }, + { AR5K_PHY_AGC, 0x00000000 }, + { AR5K_PHY_ADC_CTL, 0x00022ffe }, + { 0x983c, 0x00020100 }, { AR5K_PHY_GAIN_OFFSET, 0x1284613c }, { AR5K_PHY_PAPD_PROBE, 0x00004883 }, { 0x9940, 0x00000004 }, diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 55441913344..4e982b65404 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -2456,7 +2456,7 @@ static void ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min, s16 *table_max) { - u8 *pcdac_out = ah->ah_txpower.txp_pd_table; + u8 *pcdac_out = ah->ah_txpower.txp_pd_table; u8 *pcdac_tmp = ah->ah_txpower.tmpL[0]; u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i; s16 min_pwr, max_pwr; @@ -2502,7 +2502,7 @@ static void ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, s16 *table_max, u8 pdcurves) { - u8 *pcdac_out = ah->ah_txpower.txp_pd_table; + u8 *pcdac_out = ah->ah_txpower.txp_pd_table; u8 *pcdac_low_pwr; u8 *pcdac_high_pwr; u8 *pcdac_tmp; @@ -2596,7 +2596,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, static void ath5k_write_pcdac_table(struct ath5k_hw *ah) { - u8 *pcdac_out = ah->ah_txpower.txp_pd_table; + u8 *pcdac_out = ah->ah_txpower.txp_pd_table; int i; /* diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index d12b827033c..060a4c522ab 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -72,7 +72,7 @@ #define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */ #define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer */ #define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register access */ -#define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */ +#define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */ #define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */ #define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */ #define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (Disable dynamic clock) */ @@ -303,7 +303,7 @@ #define AR5K_ISR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ #define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */ #define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ -#define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ +#define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ #define AR5K_ISR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ #define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */ #define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */ @@ -397,7 +397,7 @@ #define AR5K_IMR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ #define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/ #define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ -#define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ +#define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ #define AR5K_IMR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ #define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/ #define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */ @@ -1328,16 +1328,16 @@ #define AR5K_RX_FILTER_5211 0x803c /* Register Address [5211+] */ #define AR5K_RX_FILTER (ah->ah_version == AR5K_AR5210 ? \ AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211) -#define AR5K_RX_FILTER_UCAST 0x00000001 /* Don't filter unicast frames */ -#define AR5K_RX_FILTER_MCAST 0x00000002 /* Don't filter multicast frames */ -#define AR5K_RX_FILTER_BCAST 0x00000004 /* Don't filter broadcast frames */ -#define AR5K_RX_FILTER_CONTROL 0x00000008 /* Don't filter control frames */ -#define AR5K_RX_FILTER_BEACON 0x00000010 /* Don't filter beacon frames */ -#define AR5K_RX_FILTER_PROM 0x00000020 /* Set promiscuous mode */ -#define AR5K_RX_FILTER_XRPOLL 0x00000040 /* Don't filter XR poll frame [5212+] */ +#define AR5K_RX_FILTER_UCAST 0x00000001 /* Don't filter unicast frames */ +#define AR5K_RX_FILTER_MCAST 0x00000002 /* Don't filter multicast frames */ +#define AR5K_RX_FILTER_BCAST 0x00000004 /* Don't filter broadcast frames */ +#define AR5K_RX_FILTER_CONTROL 0x00000008 /* Don't filter control frames */ +#define AR5K_RX_FILTER_BEACON 0x00000010 /* Don't filter beacon frames */ +#define AR5K_RX_FILTER_PROM 0x00000020 /* Set promiscuous mode */ +#define AR5K_RX_FILTER_XRPOLL 0x00000040 /* Don't filter XR poll frame [5212+] */ #define AR5K_RX_FILTER_PROBEREQ 0x00000080 /* Don't filter probe requests [5212+] */ #define AR5K_RX_FILTER_PHYERR_5212 0x00000100 /* Don't filter phy errors [5212+] */ -#define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */ +#define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */ #define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */ #define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */ #define AR5K_RX_FILTER_PHYERR \ @@ -1461,7 +1461,7 @@ * ADDAC test register [5211+] */ #define AR5K_ADDAC_TEST 0x8054 /* Register Address */ -#define AR5K_ADDAC_TEST_TXCONT 0x00000001 /* Test continuous tx */ +#define AR5K_ADDAC_TEST_TXCONT 0x00000001 /* Test continuous tx */ #define AR5K_ADDAC_TEST_TST_MODE 0x00000002 /* Test mode */ #define AR5K_ADDAC_TEST_LOOP_EN 0x00000004 /* Enable loop */ #define AR5K_ADDAC_TEST_LOOP_LEN 0x00000008 /* Loop length (field) */ @@ -2038,7 +2038,7 @@ #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S 24 /* Low thresholds */ -#define AR5K_PHY_WEAK_OFDM_LOW_THR 0x986c +#define AR5K_PHY_WEAK_OFDM_LOW_THR 0x986c #define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN 0x00000001 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT 0x00003f00 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S 8 @@ -2281,22 +2281,22 @@ #define AR5K_PHY_RADAR 0x9954 #define AR5K_PHY_RADAR_ENABLE 0x00000001 #define AR5K_PHY_RADAR_DISABLE 0x00000000 -#define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold +#define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold 5-bits, units unknown {0..31} (? MHz ?) */ #define AR5K_PHY_RADAR_INBANDTHR_S 1 -#define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold +#define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold 6-bits, dBm range {0..63} in dBm units. */ #define AR5K_PHY_RADAR_PRSSI_THR_S 6 -#define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold +#define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold 6-bits, dBm range {0..63} in dBm units. */ #define AR5K_PHY_RADAR_PHEIGHT_THR_S 12 -#define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold. +#define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold. 6-bits, dBm range {0..63} in dBm units. */ #define AR5K_PHY_RADAR_RSSI_THR_S 18 diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 1676a3e3dc3..3188204d8fd 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -25,7 +25,7 @@ #include -#include /* To determine if a card is pci-e */ +#include /* To determine if a card is pci-e */ #include #include #include "ath5k.h" diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h index 16b67e84906..5d11c23b429 100644 --- a/drivers/net/wireless/ath/ath5k/rfbuffer.h +++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h @@ -254,7 +254,7 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = { /* RFX112 (Derby 1) */ -/* BANK 6 len pos col */ +/* BANK 6 len pos col */ #define AR5K_RF5112_OB_2GHZ { 3, 269, 0 } #define AR5K_RF5112_DB_2GHZ { 3, 272, 0 } @@ -495,7 +495,7 @@ static const struct ath5k_ini_rfbuffer rfb_5112a[] = { /* BANK 2 len pos col */ #define AR5K_RF2413_RF_TURBO { 1, 1, 2 } -/* BANK 6 len pos col */ +/* BANK 6 len pos col */ #define AR5K_RF2413_OB_2GHZ { 3, 168, 0 } #define AR5K_RF2413_DB_2GHZ { 3, 165, 0 } diff --git a/drivers/net/wireless/ath/ath5k/rfgain.h b/drivers/net/wireless/ath/ath5k/rfgain.h index 1354d8c392c..70c9a45609f 100644 --- a/drivers/net/wireless/ath/ath5k/rfgain.h +++ b/drivers/net/wireless/ath/ath5k/rfgain.h @@ -452,7 +452,7 @@ static const struct ath5k_ini_rfgain rfgain_2425[] = { /* Check if our current measurement is inside our * current variable attenuation window */ -#define AR5K_GAIN_CHECK_ADJUST(_g) \ +#define AR5K_GAIN_CHECK_ADJUST(_g) \ ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high) struct ath5k_gain_opt_step { diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c index 929c68cdf8a..1090bbab945 100644 --- a/drivers/net/wireless/ath/ath5k/sysfs.c +++ b/drivers/net/wireless/ath/ath5k/sysfs.c @@ -11,7 +11,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ char *buf) \ { \ struct ath5k_softc *sc = dev_get_drvdata(dev); \ - return snprintf(buf, PAGE_SIZE, "%d\n", get); \ + return snprintf(buf, PAGE_SIZE, "%d\n", get); \ } \ \ static ssize_t ath5k_attr_store_##name(struct device *dev, \ @@ -34,7 +34,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ char *buf) \ { \ struct ath5k_softc *sc = dev_get_drvdata(dev); \ - return snprintf(buf, PAGE_SIZE, "%d\n", get); \ + return snprintf(buf, PAGE_SIZE, "%d\n", get); \ } \ static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) -- cgit v1.2.3-70-g09d2 From fdd55d14b7d3a721e60fdc8be12ec0beb9cda8c6 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:13:30 -0400 Subject: ath5k: remove unneeded parentheses after return Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/pcu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 79e11ff40fc..48bd2ded449 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -780,7 +780,7 @@ extern int ath5k_modparam_nohwcrypt; #define AR5K_ASSERT_ENTRY(_e, _s) do { \ if (_e >= _s) \ - return (false); \ + return false; \ } while (0) /* diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 712a9ac4000..0a0f63e9675 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -536,7 +536,7 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) WARN_ON( i == ATH5K_MAX_TSF_READ ); - return (((u64)tsf_upper1 << 32) | tsf_lower); + return ((u64)tsf_upper1 << 32) | tsf_lower; } /** -- cgit v1.2.3-70-g09d2 From ef82763d8dad6b2312ce388fd9af23dd2b4626d4 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:13:36 -0400 Subject: ath5k: use KERN_WARNING in ATH5K_PRINTF Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 48bd2ded449..f53cf711b9e 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -72,7 +72,8 @@ GENERIC DRIVER DEFINITIONS \****************************/ -#define ATH5K_PRINTF(fmt, ...) printk("%s: " fmt, __func__, ##__VA_ARGS__) +#define ATH5K_PRINTF(fmt, ...) \ + printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__) #define ATH5K_PRINTK(_sc, _level, _fmt, ...) \ printk(_level "ath5k %s: " _fmt, \ -- cgit v1.2.3-70-g09d2 From 25380d8068dbe983c929f5d10ae18647082511d8 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:13:42 -0400 Subject: ath5k: use DEFINE_PCI_DEVICE_TABLE in led.c, mark users with __devinit Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- drivers/net/wireless/ath/ath5k/led.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a6623ddfdef..21d10dc3401 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2357,7 +2357,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work) * Initialization routines * \*************************/ -int +int __devinit ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) { struct ieee80211_hw *hw = sc->hw; @@ -2771,7 +2771,7 @@ static void ath5k_reset_work(struct work_struct *work) mutex_unlock(&sc->lock); } -static int +static int __devinit ath5k_init(struct ieee80211_hw *hw) { diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 576edf2965d..56f1d95abb0 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -52,7 +52,7 @@ #define ATH_POLARITY(data) ((data) & 0xff) /* Devices we match on for LED config info (typically laptops) */ -static const struct pci_device_id ath5k_led_devices[] = { +static DEFINE_PCI_DEVICE_TABLE(ath5k_led_devices) = { /* AR5211 */ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) }, /* HP Compaq nc6xx, nc4000, nx6000 */ @@ -157,7 +157,7 @@ void ath5k_unregister_leds(struct ath5k_softc *sc) ath5k_unregister_led(&sc->tx_led); } -int ath5k_init_leds(struct ath5k_softc *sc) +int __devinit ath5k_init_leds(struct ath5k_softc *sc) { int ret = 0; struct ieee80211_hw *hw = sc->hw; -- cgit v1.2.3-70-g09d2 From 2724a74a2620f98bd63e866e54938d092a017b21 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:13:48 -0400 Subject: ath5k: use more readable way to clear MAC address Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/attach.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 1588401de3c..f781eeb5085 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -104,6 +104,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah) */ int ath5k_hw_init(struct ath5k_softc *sc) { + static const u8 zero_mac[ETH_ALEN] = { }; struct ath5k_hw *ah = sc->ah; struct ath_common *common = ath5k_hw_common(ah); struct pci_dev *pdev = sc->pdev; @@ -334,7 +335,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) } /* MAC address is cleared until add_interface */ - ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){}); + ath5k_hw_set_lladdr(ah, zero_mac); /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); -- cgit v1.2.3-70-g09d2 From 2753f87a574c4844dfa1709c7d0a474f0dc8d818 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:13:55 -0400 Subject: ath5k: don't use volatile, it's not needed Signed-off-by: Pavel Roskin The reg variable is only used by __raw_writel() and __raw_readl(), which should guarantee memory access in the right order. Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 3188204d8fd..bbeef3aac93 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -375,7 +375,7 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) { u32 mask = flags ? flags : ~0U; - volatile __iomem u32 *reg; + u32 __iomem *reg; u32 regval; u32 val = 0; -- cgit v1.2.3-70-g09d2 From 633d006ee6a7229f1d2c60924084d902d60c0e5f Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:14:01 -0400 Subject: ath5k: use parentheses around macro definitions Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- drivers/net/wireless/ath/ath5k/reg.h | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 21d10dc3401..1b48ed87ca2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1977,7 +1977,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) hw_tsf = ath5k_hw_get_tsf64(ah); hw_tu = TSF_TO_TU(hw_tsf); -#define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3 +#define FUDGE (AR5K_TUNE_SW_BEACON_RESP + 3) /* We use FUDGE to make sure the next TBTT is ahead of the current TU. * Since we later subtract AR5K_TUNE_SW_BEACON_RESP (10) in the timer * configuration we need to make sure it is bigger than that. */ diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 060a4c522ab..994d29ace34 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -2259,12 +2259,13 @@ #define AR5K_PHY_FRAME_CTL_ILLLEN_ERR 0x08000000 /* Illegal length */ #define AR5K_PHY_FRAME_CTL_SERVICE_ERR 0x20000000 #define AR5K_PHY_FRAME_CTL_TXURN_ERR 0x40000000 /* TX underrun */ -#define AR5K_PHY_FRAME_CTL_INI AR5K_PHY_FRAME_CTL_SERVICE_ERR | \ - AR5K_PHY_FRAME_CTL_TXURN_ERR | \ - AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \ - AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \ - AR5K_PHY_FRAME_CTL_PARITY_ERR | \ - AR5K_PHY_FRAME_CTL_TIMING_ERR +#define AR5K_PHY_FRAME_CTL_INI \ + (AR5K_PHY_FRAME_CTL_SERVICE_ERR | \ + AR5K_PHY_FRAME_CTL_TXURN_ERR | \ + AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \ + AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \ + AR5K_PHY_FRAME_CTL_PARITY_ERR | \ + AR5K_PHY_FRAME_CTL_TIMING_ERR) /* * PHY Tx Power adjustment register [5212A+] -- cgit v1.2.3-70-g09d2 From d2c7f7730e5660c812765acd57516f709ea35fc0 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:14:07 -0400 Subject: ath5k: fix misplaced or extraneous braces found by checkpatch.pl Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 +-- drivers/net/wireless/ath/ath5k/base.c | 14 ++++++-------- drivers/net/wireless/ath/ath5k/base.h | 3 +-- drivers/net/wireless/ath/ath5k/eeprom.c | 10 ++++++---- 4 files changed, 14 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index f53cf711b9e..68163428fdb 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1011,8 +1011,7 @@ struct ath5k_capabilities { /* size of noise floor history (keep it a power of two) */ #define ATH5K_NF_CAL_HIST_MAX 8 -struct ath5k_nfcal_hist -{ +struct ath5k_nfcal_hist { s16 index; /* current index into nfval */ s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ }; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 1b48ed87ca2..ac873425470 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1265,12 +1265,11 @@ static int ath5k_common_padpos(struct sk_buff *skb) __le16 frame_control = hdr->frame_control; int padpos = 24; - if (ieee80211_has_a4(frame_control)) { + if (ieee80211_has_a4(frame_control)) padpos += ETH_ALEN; - } - if (ieee80211_is_data_qos(frame_control)) { + + if (ieee80211_is_data_qos(frame_control)) padpos += IEEE80211_QOS_CTL_LEN; - } return padpos; } @@ -2199,13 +2198,12 @@ ath5k_intr(int irq, void *dev_id) ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "rx overrun, resetting\n"); ieee80211_queue_work(sc->hw, &sc->reset_work); - } - else + } else ath5k_schedule_rx(sc); } else { - if (status & AR5K_INT_SWBA) { + if (status & AR5K_INT_SWBA) tasklet_hi_schedule(&sc->beacontq); - } + if (status & AR5K_INT_RXEOL) { /* * NB: the hardware should re-read the link when diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 3016562a771..eb035cbe665 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -96,8 +96,7 @@ struct ath5k_txq { /* * State for LED triggers */ -struct ath5k_led -{ +struct ath5k_led { char name[ATH5K_LED_MAX_NAME_LEN + 1]; /* name of the LED in sysfs */ struct ath5k_softc *sc; /* driver state */ struct led_classdev led_dev; /* led classdev */ diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 4198f4ef88d..0c9d8b18955 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -644,10 +644,12 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) static inline void ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) { - static const u16 intercepts3[] = - { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 }; - static const u16 intercepts3_2[] = - { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; + static const u16 intercepts3[] = { + 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 + }; + static const u16 intercepts3_2[] = { + 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 + }; const u16 *ip; int i; -- cgit v1.2.3-70-g09d2 From e4bbf2f541501dcde47ce687ffc6d238bd2f7813 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:14:13 -0400 Subject: ath5k: fix formatting errors found by checkpatch.pl Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 4 +- drivers/net/wireless/ath/ath5k/ani.c | 2 +- drivers/net/wireless/ath/ath5k/ath5k.h | 21 ++-- drivers/net/wireless/ath/ath5k/attach.c | 17 ++- drivers/net/wireless/ath/ath5k/base.c | 24 ++-- drivers/net/wireless/ath/ath5k/base.h | 4 +- drivers/net/wireless/ath/ath5k/debug.c | 204 ++++++++++++++++---------------- drivers/net/wireless/ath/ath5k/dma.c | 2 +- drivers/net/wireless/ath/ath5k/eeprom.c | 20 ++-- drivers/net/wireless/ath/ath5k/eeprom.h | 2 +- drivers/net/wireless/ath/ath5k/led.c | 4 +- drivers/net/wireless/ath/ath5k/pci.c | 2 +- drivers/net/wireless/ath/ath5k/pcu.c | 2 +- drivers/net/wireless/ath/ath5k/phy.c | 46 +++---- drivers/net/wireless/ath/ath5k/reset.c | 8 +- 15 files changed, 182 insertions(+), 180 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index c38e9e84899..ba682a0b2dd 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -167,8 +167,8 @@ static int ath_ahb_probe(struct platform_device *pdev) * driver for it */ if (to_platform_device(sc->dev)->id == 0 && - (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) == - (BD_WLAN1|BD_WLAN0)) + (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) == + (BD_WLAN1 | BD_WLAN0)) __set_bit(ATH_STAT_2G_DISABLED, sc->status); } diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index f915f404302..a08f17318e6 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -642,7 +642,7 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode) /* initial values for our ani parameters */ if (mode == ATH5K_ANI_MODE_OFF) { ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n"); - } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) { + } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) { ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI manual low -> high sensitivity\n"); ath5k_ani_set_noise_immunity_level(ah, 0); diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 68163428fdb..b1de4a09c8c 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -362,7 +362,7 @@ struct ath5k_srev_name { /* * Some of this information is based on Documentation from: * - * http://madwifi-project.org/wiki/ChipsetFeatures/SuperAG + * http://madwifi-project.org/wiki/ChipsetFeatures/SuperAG * * Modulation for Atheros' eXtended Range - range enhancing extension that is * supposed to double the distance an Atheros client device can keep a @@ -617,8 +617,8 @@ struct ath5k_rx_status { #define AR5K_RXERR_FIFO 0x04 #define AR5K_RXERR_DECRYPT 0x08 #define AR5K_RXERR_MIC 0x10 -#define AR5K_RXKEYIX_INVALID ((u8) - 1) -#define AR5K_TXKEYIX_INVALID ((u32) - 1) +#define AR5K_RXKEYIX_INVALID ((u8) -1) +#define AR5K_TXKEYIX_INVALID ((u32) -1) /**************************\ @@ -679,12 +679,13 @@ struct ath5k_gain { #define CHANNEL_DYN 0x0400 /* Dynamic CCK-OFDM channel (for g operation) */ #define CHANNEL_XR 0x0800 /* XR channel */ -#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) -#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) -#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) -#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR) +#define CHANNEL_A (CHANNEL_5GHZ | CHANNEL_OFDM) +#define CHANNEL_B (CHANNEL_2GHZ | CHANNEL_CCK) +#define CHANNEL_G (CHANNEL_2GHZ | CHANNEL_OFDM) +#define CHANNEL_X (CHANNEL_5GHZ | CHANNEL_OFDM | CHANNEL_XR) -#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ) +#define CHANNEL_ALL (CHANNEL_OFDM | CHANNEL_CCK | \ + CHANNEL_2GHZ | CHANNEL_5GHZ) #define CHANNEL_MODES CHANNEL_ALL @@ -777,7 +778,7 @@ extern int ath5k_modparam_nohwcrypt; /* * Misc definitions */ -#define AR5K_RSSI_EP_MULTIPLIER (1<<7) +#define AR5K_RSSI_EP_MULTIPLIER (1 << 7) #define AR5K_ASSERT_ENTRY(_e, _s) do { \ if (_e >= _s) \ @@ -1378,7 +1379,7 @@ static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) /* On AR2315 and AR2317 the PCI clock domain registers * are outside of the WMAC register space */ if (unlikely((reg >= 0x4000) && (reg < 0x5000) && - (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6))) + (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6))) return AR5K_AR2315_PCI_BASE + reg; return ah->ah_iobase + reg; diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index f781eeb5085..d6fbb57a5d9 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -192,7 +192,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) break; case AR5K_SREV_RAD_5424: if (ah->ah_mac_version == AR5K_SREV_AR2425 || - ah->ah_mac_version == AR5K_SREV_AR2417){ + ah->ah_mac_version == AR5K_SREV_AR2417) { ah->ah_radio = AR5K_RF2425; ah->ah_single_chip = true; } else { @@ -211,28 +211,28 @@ int ath5k_hw_init(struct ath5k_softc *sc) ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, CHANNEL_2GHZ); } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) || - ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || - ah->ah_phy_revision == AR5K_SREV_PHY_2425) { + ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || + ah->ah_phy_revision == AR5K_SREV_PHY_2425) { ah->ah_radio = AR5K_RF2425; ah->ah_single_chip = true; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; } else if (srev == AR5K_SREV_AR5213A && - ah->ah_phy_revision == AR5K_SREV_PHY_5212B) { + ah->ah_phy_revision == AR5K_SREV_PHY_5212B) { ah->ah_radio = AR5K_RF5112; ah->ah_single_chip = false; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) || - ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) { + ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) { ah->ah_radio = AR5K_RF2316; ah->ah_single_chip = true; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || - ah->ah_phy_revision == AR5K_SREV_PHY_5413) { + ah->ah_phy_revision == AR5K_SREV_PHY_5413) { ah->ah_radio = AR5K_RF5413; ah->ah_single_chip = true; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || - ah->ah_phy_revision == AR5K_SREV_PHY_2413) { + ah->ah_phy_revision == AR5K_SREV_PHY_2413) { ah->ah_radio = AR5K_RF2413; ah->ah_single_chip = true; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; @@ -245,8 +245,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) /* Return on unsuported chips (unsupported eeprom etc) */ - if ((srev >= AR5K_SREV_AR5416) && - (srev < AR5K_SREV_AR2425)) { + if ((srev >= AR5K_SREV_AR5416) && (srev < AR5K_SREV_AR2425)) { ATH5K_ERR(sc, "Device not yet supported.\n"); ret = -ENODEV; goto err; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ac873425470..58997d3abae 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -814,8 +814,7 @@ ath5k_desc_alloc(struct ath5k_softc *sc) INIT_LIST_HEAD(&sc->txbuf); sc->txbuf_len = ATH_TXBUF; - for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, - da += sizeof(*ds)) { + for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, da += sizeof(*ds)) { bf->desc = ds; bf->daddr = da; list_add_tail(&bf->list, &sc->txbuf); @@ -981,7 +980,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) goto err; if (sc->opmode == NL80211_IFTYPE_AP || - sc->opmode == NL80211_IFTYPE_MESH_POINT) { + sc->opmode == NL80211_IFTYPE_MESH_POINT) { /* * Always burst out beacon and CAB traffic * (aifs = cwmin = cwmax = 0) @@ -1261,7 +1260,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) */ static int ath5k_common_padpos(struct sk_buff *skb) { - struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 frame_control = hdr->frame_control; int padpos = 24; @@ -1283,13 +1282,13 @@ static int ath5k_add_padding(struct sk_buff *skb) int padpos = ath5k_common_padpos(skb); int padsize = padpos & 3; - if (padsize && skb->len>padpos) { + if (padsize && skb->len > padpos) { if (skb_headroom(skb) < padsize) return -1; skb_push(skb, padsize); - memmove(skb->data, skb->data+padsize, padpos); + memmove(skb->data, skb->data + padsize, padpos); return padsize; } @@ -1314,7 +1313,7 @@ static int ath5k_remove_padding(struct sk_buff *skb) int padpos = ath5k_common_padpos(skb); int padsize = padpos & 3; - if (padsize && skb->len>=padpos+padsize) { + if (padsize && skb->len >= padpos + padsize) { memmove(skb->data + padsize, skb->data, padpos); skb_pull(skb, padsize); return padsize; @@ -1709,7 +1708,7 @@ ath5k_tasklet_tx(unsigned long data) int i; struct ath5k_softc *sc = (void *)data; - for (i=0; i < AR5K_NUM_TX_QUEUES; i++) + for (i = 0; i < AR5K_NUM_TX_QUEUES; i++) if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) ath5k_tx_processq(sc, &sc->txqs[i]); @@ -1900,7 +1899,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) avf = (void *)vif->drv_priv; bf = avf->bbuf; if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || - sc->opmode == NL80211_IFTYPE_MONITOR)) { + sc->opmode == NL80211_IFTYPE_MONITOR)) { ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); return; } @@ -1917,7 +1916,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) /* refresh the beacon for AP or MESH mode */ if (sc->opmode == NL80211_IFTYPE_AP || - sc->opmode == NL80211_IFTYPE_MESH_POINT) + sc->opmode == NL80211_IFTYPE_MESH_POINT) ath5k_beacon_update(sc->hw, vif); trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]); @@ -2485,7 +2484,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) /* Multi chip radio (RF5111 - RF2111) -> * report both 2GHz/5GHz radios */ else if (sc->ah->ah_radio_5ghz_revision && - sc->ah->ah_radio_2ghz_revision){ + sc->ah->ah_radio_2ghz_revision) { ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", ath5k_chip_name(AR5K_VERSION_RAD, sc->ah->ah_radio_5ghz_revision), @@ -2710,8 +2709,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; - ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, - skip_pcu); + ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, skip_pcu); if (ret) { ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); goto err; diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index eb035cbe665..e71494ee329 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -153,9 +153,9 @@ struct ath5k_statistics { }; #if CHAN_DEBUG -#define ATH_CHAN_MAX (26+26+26+200+200) +#define ATH_CHAN_MAX (26 + 26 + 26 + 200 + 200) #else -#define ATH_CHAN_MAX (14+14+14+252+20) +#define ATH_CHAN_MAX (14 + 14 + 14 + 252 + 20) #endif struct ath5k_vif { diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 0bf7313b8a1..ae1112bfa1c 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -205,35 +205,35 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf, u64 tsf; v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n", "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD, (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S); - len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n", + len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n", "AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP)); - len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n\n", + len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n\n", "AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT)); v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0); - len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n", + len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", "AR5K_TIMER0 (TBTT)", v, v); v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1); - len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n", + len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", "AR5K_TIMER1 (DMA)", v, v >> 3); v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2); - len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n", + len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", "AR5K_TIMER2 (SWBA)", v, v >> 3); v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3); - len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n", + len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", "AR5K_TIMER3 (ATIM)", v, v); tsf = ath5k_hw_get_tsf64(sc->ah); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "TSF\t\t0x%016llx\tTU: %08x\n", (unsigned long long)tsf, TSF_TO_TU(tsf)); @@ -323,16 +323,16 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf, unsigned int len = 0; unsigned int i; - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level); for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) { - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "%10s %c 0x%08x - %s\n", dbg_info[i].name, sc->debug.level & dbg_info[i].level ? '+' : ' ', dbg_info[i].level, dbg_info[i].desc); } - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "%10s %c 0x%08x - %s\n", dbg_info[i].name, sc->debug.level == dbg_info[i].level ? '+' : ' ', dbg_info[i].level, dbg_info[i].desc); @@ -384,60 +384,60 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf, unsigned int i; unsigned int v; - len += snprintf(buf+len, sizeof(buf)-len, "antenna mode\t%d\n", + len += snprintf(buf + len, sizeof(buf) - len, "antenna mode\t%d\n", sc->ah->ah_ant_mode); - len += snprintf(buf+len, sizeof(buf)-len, "default antenna\t%d\n", + len += snprintf(buf + len, sizeof(buf) - len, "default antenna\t%d\n", sc->ah->ah_def_ant); - len += snprintf(buf+len, sizeof(buf)-len, "tx antenna\t%d\n", + len += snprintf(buf + len, sizeof(buf) - len, "tx antenna\t%d\n", sc->ah->ah_tx_ant); - len += snprintf(buf+len, sizeof(buf)-len, "\nANTENNA\t\tRX\tTX\n"); + len += snprintf(buf + len, sizeof(buf) - len, "\nANTENNA\t\tRX\tTX\n"); for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) { - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "[antenna %d]\t%d\t%d\n", i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]); } - len += snprintf(buf+len, sizeof(buf)-len, "[invalid]\t%d\t%d\n", + len += snprintf(buf + len, sizeof(buf) - len, "[invalid]\t%d\t%d\n", sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]); v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v); v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n", (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_STA_ID1_DESC_ANTENNA\t%d\n", (v & AR5K_STA_ID1_DESC_ANTENNA) != 0); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n", (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n", (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0); v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n", (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0); v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_PHY_RESTART_DIV_GC\t\t%x\n", (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S); v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n", (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0); v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_0); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v); v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_1); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v); if (len > sizeof(buf)) @@ -494,36 +494,36 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, unsigned int len = 0; u32 filt = ath5k_hw_get_rx_filter(sc->ah); - len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n", + len += snprintf(buf + len, sizeof(buf) - len, "bssid-mask: %pM\n", sc->bssidmask); - len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ", + len += snprintf(buf + len, sizeof(buf) - len, "filter-flags: 0x%x ", filt); if (filt & AR5K_RX_FILTER_UCAST) - len += snprintf(buf+len, sizeof(buf)-len, " UCAST"); + len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); if (filt & AR5K_RX_FILTER_MCAST) - len += snprintf(buf+len, sizeof(buf)-len, " MCAST"); + len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); if (filt & AR5K_RX_FILTER_BCAST) - len += snprintf(buf+len, sizeof(buf)-len, " BCAST"); + len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); if (filt & AR5K_RX_FILTER_CONTROL) - len += snprintf(buf+len, sizeof(buf)-len, " CONTROL"); + len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); if (filt & AR5K_RX_FILTER_BEACON) - len += snprintf(buf+len, sizeof(buf)-len, " BEACON"); + len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); if (filt & AR5K_RX_FILTER_PROM) - len += snprintf(buf+len, sizeof(buf)-len, " PROM"); + len += snprintf(buf + len, sizeof(buf) - len, " PROM"); if (filt & AR5K_RX_FILTER_XRPOLL) - len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL"); + len += snprintf(buf + len, sizeof(buf) - len, " XRPOLL"); if (filt & AR5K_RX_FILTER_PROBEREQ) - len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ"); + len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); if (filt & AR5K_RX_FILTER_PHYERR_5212) - len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212"); + len += snprintf(buf + len, sizeof(buf) - len, " PHYERR-5212"); if (filt & AR5K_RX_FILTER_RADARERR_5212) - len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212"); + len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5212"); if (filt & AR5K_RX_FILTER_PHYERR_5211) - snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211"); + snprintf(buf + len, sizeof(buf) - len, " PHYERR-5211"); if (filt & AR5K_RX_FILTER_RADARERR_5211) - len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211"); + len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5211"); - len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n", + len += snprintf(buf + len, sizeof(buf) - len, "\nopmode: %s (%d)\n", ath_opmode_to_string(sc->opmode), sc->opmode); if (len > sizeof(buf)) @@ -550,65 +550,65 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, unsigned int len = 0; int i; - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "RX\n---------------------\n"); - len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%u\t(%u%%)\n", + len += snprintf(buf + len, sizeof(buf) - len, "CRC\t%u\t(%u%%)\n", st->rxerr_crc, st->rx_all_count > 0 ? - st->rxerr_crc*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%u\t(%u%%)\n", + st->rxerr_crc * 100 / st->rx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "PHY\t%u\t(%u%%)\n", st->rxerr_phy, st->rx_all_count > 0 ? - st->rxerr_phy*100/st->rx_all_count : 0); + st->rxerr_phy * 100 / st->rx_all_count : 0); for (i = 0; i < 32; i++) { if (st->rxerr_phy_code[i]) - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, " phy_err[%u]\t%u\n", i, st->rxerr_phy_code[i]); } - len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n", + len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n", st->rxerr_fifo, st->rx_all_count > 0 ? - st->rxerr_fifo*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%u\t(%u%%)\n", + st->rxerr_fifo * 100 / st->rx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "decrypt\t%u\t(%u%%)\n", st->rxerr_decrypt, st->rx_all_count > 0 ? - st->rxerr_decrypt*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%u\t(%u%%)\n", + st->rxerr_decrypt * 100 / st->rx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "MIC\t%u\t(%u%%)\n", st->rxerr_mic, st->rx_all_count > 0 ? - st->rxerr_mic*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "process\t%u\t(%u%%)\n", + st->rxerr_mic * 100 / st->rx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "process\t%u\t(%u%%)\n", st->rxerr_proc, st->rx_all_count > 0 ? - st->rxerr_proc*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%u\t(%u%%)\n", + st->rxerr_proc * 100 / st->rx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "jumbo\t%u\t(%u%%)\n", st->rxerr_jumbo, st->rx_all_count > 0 ? - st->rxerr_jumbo*100/st->rx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%u]\n", + st->rxerr_jumbo * 100 / st->rx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "[RX all\t%u]\n", st->rx_all_count); - len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%u\n", + len += snprintf(buf + len, sizeof(buf) - len, "RX-all-bytes\t%u\n", st->rx_bytes_count); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "\nTX\n---------------------\n"); - len += snprintf(buf+len, sizeof(buf)-len, "retry\t%u\t(%u%%)\n", + len += snprintf(buf + len, sizeof(buf) - len, "retry\t%u\t(%u%%)\n", st->txerr_retry, st->tx_all_count > 0 ? - st->txerr_retry*100/st->tx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n", + st->txerr_retry * 100 / st->tx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n", st->txerr_fifo, st->tx_all_count > 0 ? - st->txerr_fifo*100/st->tx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "filter\t%u\t(%u%%)\n", + st->txerr_fifo * 100 / st->tx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "filter\t%u\t(%u%%)\n", st->txerr_filt, st->tx_all_count > 0 ? - st->txerr_filt*100/st->tx_all_count : 0); - len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%u]\n", + st->txerr_filt * 100 / st->tx_all_count : 0); + len += snprintf(buf + len, sizeof(buf) - len, "[TX all\t%u]\n", st->tx_all_count); - len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%u\n", + len += snprintf(buf + len, sizeof(buf) - len, "TX-all-bytes\t%u\n", st->tx_bytes_count); if (len > sizeof(buf)) @@ -667,89 +667,93 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, char buf[700]; unsigned int len = 0; - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "HW has PHY error counters:\t%s\n", sc->ah->ah_capabilities.cap_has_phyerr_counters ? "yes" : "no"); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "HW max spur immunity level:\t%d\n", as->max_spur_level); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "\nANI state\n--------------------------------------------\n"); - len += snprintf(buf+len, sizeof(buf)-len, "operating mode:\t\t\t"); + len += snprintf(buf + len, sizeof(buf) - len, "operating mode:\t\t\t"); switch (as->ani_mode) { case ATH5K_ANI_MODE_OFF: - len += snprintf(buf+len, sizeof(buf)-len, "OFF\n"); + len += snprintf(buf + len, sizeof(buf) - len, "OFF\n"); break; case ATH5K_ANI_MODE_MANUAL_LOW: - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "MANUAL LOW\n"); break; case ATH5K_ANI_MODE_MANUAL_HIGH: - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "MANUAL HIGH\n"); break; case ATH5K_ANI_MODE_AUTO: - len += snprintf(buf+len, sizeof(buf)-len, "AUTO\n"); + len += snprintf(buf + len, sizeof(buf) - len, "AUTO\n"); break; default: - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "??? (not good)\n"); break; } - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "noise immunity level:\t\t%d\n", as->noise_imm_level); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "spur immunity level:\t\t%d\n", as->spur_level); - len += snprintf(buf+len, sizeof(buf)-len, "firstep level:\t\t\t%d\n", + len += snprintf(buf + len, sizeof(buf) - len, + "firstep level:\t\t\t%d\n", as->firstep_level); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "OFDM weak signal detection:\t%s\n", as->ofdm_weak_sig ? "on" : "off"); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "CCK weak signal detection:\t%s\n", as->cck_weak_sig ? "on" : "off"); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "\nMIB INTERRUPTS:\t\t%u\n", st->mib_intr); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "beacon RSSI average:\t%d\n", (int)ewma_read(&sc->ah->ah_beacon_rssi_avg)); #define CC_PRINT(_struct, _field) \ _struct._field, \ _struct.cycles > 0 ? \ - _struct._field*100/_struct.cycles : 0 + _struct._field * 100 / _struct.cycles : 0 - len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", + len += snprintf(buf + len, sizeof(buf) - len, + "profcnt tx\t\t%u\t(%d%%)\n", CC_PRINT(as->last_cc, tx_frame)); - len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", + len += snprintf(buf + len, sizeof(buf) - len, + "profcnt rx\t\t%u\t(%d%%)\n", CC_PRINT(as->last_cc, rx_frame)); - len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", + len += snprintf(buf + len, sizeof(buf) - len, + "profcnt busy\t\t%u\t(%d%%)\n", CC_PRINT(as->last_cc, rx_busy)); #undef CC_PRINT - len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", + len += snprintf(buf + len, sizeof(buf) - len, "profcnt cycles\t\t%u\n", as->last_cc.cycles); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "listen time\t\t%d\tlast: %d\n", as->listen_time, as->last_listen); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "OFDM errors\t\t%u\tlast: %u\tsum: %u\n", as->ofdm_errors, as->last_ofdm_errors, as->sum_ofdm_errors); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "CCK errors\t\t%u\tlast: %u\tsum: %u\n", as->cck_errors, as->last_cck_errors, as->sum_cck_errors); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_PHYERR_CNT1\t%x\t(=%d)\n", ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1), ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1))); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "AR5K_PHYERR_CNT2\t%x\t(=%d)\n", ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2), ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - @@ -827,13 +831,13 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, struct ath5k_buf *bf, *bf0; int i, n; - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "available txbuffers: %d\n", sc->txbuf_len); for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { txq = &sc->txqs[i]; - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, "%02d: %ssetup\n", i, txq->setup ? "" : "not "); if (!txq->setup) @@ -845,9 +849,9 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, n++; spin_unlock_bh(&txq->lock); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, " len: %d bufs: %d\n", txq->txq_len, n); - len += snprintf(buf+len, sizeof(buf)-len, + len += snprintf(buf + len, sizeof(buf) - len, " stuck: %d\n", txq->txq_stuck); } @@ -894,7 +898,7 @@ ath5k_debug_init_device(struct ath5k_softc *sc) phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir); if (!phydir) - return; + return; debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc, &fops_debug); diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 21091c26a9a..02e2e3f71b0 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -258,7 +258,7 @@ static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) /* For 2413+ order PCU to drop packets using * QUIET mechanism */ if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) && - pending){ + pending) { /* Set periodicity and duration */ ath5k_hw_reg_write(ah, AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)| diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 0c9d8b18955..f2657bf34fe 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -255,7 +255,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, ee->ee_n_piers[mode] = 0; AR5K_EEPROM_READ(o++, val); ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); - switch(mode) { + switch (mode) { case AR5K_EEPROM_MODE_11A: ee->ee_ob[mode][3] = (val >> 5) & 0x7; ee->ee_db[mode][3] = (val >> 2) & 0x7; @@ -349,7 +349,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, /* Note: >= v5 have bg freq piers on another location * so these freq piers are ignored for >= v5 (should be 0xff * anyway) */ - switch(mode) { + switch (mode) { case AR5K_EEPROM_MODE_11A: if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1) break; @@ -422,7 +422,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, if (ee->ee_version < AR5K_EEPROM_VERSION_5_0) goto done; - switch (mode){ + switch (mode) { case AR5K_EEPROM_MODE_11A: ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f; @@ -436,7 +436,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7; ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff; - if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2) + if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >= 2) ee->ee_pd_gain_overlap = (val >> 9) & 0xf; break; case AR5K_EEPROM_MODE_11G: @@ -516,7 +516,7 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, u16 val; ee->ee_n_piers[mode] = 0; - while(i < max) { + while (i < max) { AR5K_EEPROM_READ(o++, val); freq1 = val & 0xff; @@ -602,7 +602,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info *pcal; - switch(mode) { + switch (mode) { case AR5K_EEPROM_MODE_11B: pcal = ee->ee_pwr_cal_b; break; @@ -800,7 +800,7 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) u16 val; offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); - switch(mode) { + switch (mode) { case AR5K_EEPROM_MODE_11A: if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) return 0; @@ -1167,7 +1167,7 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) { u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4); - switch(mode) { + switch (mode) { case AR5K_EEPROM_MODE_11G: if (AR5K_EEPROM_HDR_11B(ee->ee_header)) offset += ath5k_pdgains_size_2413(ee, @@ -1624,8 +1624,8 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) offset += AR5K_EEPROM_GROUPS_START(ee->ee_version); rep = ee->ee_ctl_pwr; - for(i = 0; i < ee->ee_ctls; i++) { - switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) { + for (i = 0; i < ee->ee_ctls; i++) { + switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) { case AR5K_CTL_11A: case AR5K_CTL_TURBO: ctl_mode = AR5K_EEPROM_MODE_11A; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 6511c27d938..6d440e0ba14 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -223,7 +223,7 @@ #define AR5K_EEPROM_CCK_OFDM_DELTA 15 #define AR5K_EEPROM_N_IQ_CAL 2 /* 5GHz/2GHz */ -enum ath5k_eeprom_freq_bands{ +enum ath5k_eeprom_freq_bands { AR5K_EEPROM_BAND_5GHZ = 0, AR5K_EEPROM_BAND_2GHZ = 1, AR5K_EEPROM_N_FREQ_BANDS, diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 56f1d95abb0..127bfbd3517 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -43,11 +43,11 @@ #include "ath5k.h" #include "base.h" -#define ATH_SDEVICE(subv,subd) \ +#define ATH_SDEVICE(subv, subd) \ .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ .subvendor = (subv), .subdevice = (subd) -#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity)) +#define ATH_LED(pin, polarity) .driver_data = (((pin) << 8) | (polarity)) #define ATH_PIN(data) ((data) >> 8) #define ATH_POLARITY(data) ((data) & 0xff) diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 296c316a834..bb93796bfaf 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -234,7 +234,7 @@ ath5k_pci_probe(struct pci_dev *pdev, mem = pci_iomap(pdev, 0, 0); if (!mem) { - dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; + dev_err(&pdev->dev, "cannot remap PCI memory region\n"); ret = -EIO; goto err_reg; } diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 0a0f63e9675..aecd7241749 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -534,7 +534,7 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) local_irq_restore(flags); - WARN_ON( i == ATH5K_MAX_TSF_READ ); + WARN_ON(i == ATH5K_MAX_TSF_READ); return ((u64)tsf_upper1 << 32) | tsf_lower; } diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 4e982b65404..7e2867689e1 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -173,7 +173,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, data = ath5k_hw_bitswap(val, num_bits); for (bits_shifted = 0, bits_left = num_bits; bits_left > 0; - position = 0, entry++) { + position = 0, entry++) { last_bit = (position + bits_left > 8) ? 8 : position + bits_left; @@ -472,7 +472,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) level[0] = 0; level[1] = (step == 63) ? 50 : step + 4; level[2] = (step != 63) ? 64 : level[0]; - level[3] = level[2] + 50 ; + level[3] = level[2] + 50; ah->ah_gain.g_high = level[3] - (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5); @@ -549,7 +549,7 @@ static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) for (ah->ah_gain.g_target = ah->ah_gain.g_current; ah->ah_gain.g_target <= ah->ah_gain.g_low && - ah->ah_gain.g_step_idx < go->go_steps_count-1; + ah->ah_gain.g_step_idx < go->go_steps_count - 1; g_step = &go->go_step[ah->ah_gain.g_step_idx]) ah->ah_gain.g_target -= 2 * (go->go_step[++ah->ah_gain.g_step_idx].gos_gain - @@ -614,7 +614,7 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) ath5k_hw_rf_gainf_corr(ah); ah->ah_gain.g_current = ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ? - (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) : + (ah->ah_gain.g_current - ah->ah_gain.g_f_corr) : 0; } @@ -1331,7 +1331,7 @@ void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah) static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor) { struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist; - hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX-1); + hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX - 1); hist->nfval[hist->index] = noise_floor; } @@ -1344,10 +1344,10 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah) memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort)); for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) { for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) { - if (sort[j] > sort[j-1]) { + if (sort[j] > sort[j - 1]) { tmp = sort[j]; - sort[j] = sort[j-1]; - sort[j-1] = tmp; + sort[j] = sort[j - 1]; + sort[j - 1] = tmp; } } } @@ -1355,7 +1355,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah) ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, "cal %d:%d\n", i, sort[i]); } - return sort[(ATH5K_NF_CAL_HIST_MAX-1) / 2]; + return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2]; } /* @@ -2080,7 +2080,7 @@ ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right, * always 1 instead of 1.25, 1.75 etc). We scale up by 100 * to have some accuracy both for 0.5 and 0.25 steps. */ - ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left)); + ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left)); /* Now scale down to be in range */ result = y_left + (ratio * (target - x_left) / 100); @@ -2159,7 +2159,7 @@ ath5k_create_power_curve(s16 pmin, s16 pmax, u8 *vpd_table, u8 type) { u8 idx[2] = { 0, 1 }; - s16 pwr_i = 2*pmin; + s16 pwr_i = 2 * pmin; int i; if (num_points < 2) @@ -2437,7 +2437,7 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah, } if (edge_pwr) - ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr); + ah->ah_txpower.txp_max_pwr = 4 * min(edge_pwr, max_chan_pwr); } @@ -2475,8 +2475,8 @@ ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min, /* Copy values from pcdac_tmp */ pwr_idx = min_pwr; - for (i = 0 ; pwr_idx <= max_pwr && - pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) { + for (i = 0; pwr_idx <= max_pwr && + pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) { pcdac_out[pcdac_i++] = pcdac_tmp[i]; pwr_idx++; } @@ -2552,7 +2552,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, } /* This is used when setting tx power*/ - ah->ah_txpower.txp_min_idx = min_pwr_idx/2; + ah->ah_txpower.txp_min_idx = min_pwr_idx / 2; /* Fill Power to PCDAC table backwards */ pwr = max_pwr_idx; @@ -2561,10 +2561,10 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, * edge flag and set pcdac_tmp to lower * power curve.*/ if (edge_flag == 0x40 && - (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) { + (2 * pwr <= (table_max[1] - table_min[0]) || pwr == 0)) { edge_flag = 0x00; pcdac_tmp = pcdac_low_pwr; - pwr = mid_pwr_idx/2; + pwr = mid_pwr_idx / 2; } /* Don't go below 1, extrapolate below if we have @@ -2604,8 +2604,8 @@ ath5k_write_pcdac_table(struct ath5k_hw *ah) */ for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) { ath5k_hw_reg_write(ah, - (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) | - (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16), + (((pcdac_out[2 * i + 0] << 8 | 0xff) & 0xffff) << 0) | + (((pcdac_out[2 * i + 1] << 8 | 0xff) & 0xffff) << 16), AR5K_PHY_PCDAC_TXPOWER(i)); } } @@ -2789,10 +2789,10 @@ ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) */ for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) { ath5k_hw_reg_write(ah, - ((pdadc_out[4*i + 0] & 0xff) << 0) | - ((pdadc_out[4*i + 1] & 0xff) << 8) | - ((pdadc_out[4*i + 2] & 0xff) << 16) | - ((pdadc_out[4*i + 3] & 0xff) << 24), + ((pdadc_out[4 * i + 0] & 0xff) << 0) | + ((pdadc_out[4 * i + 1] & 0xff) << 8) | + ((pdadc_out[4 * i + 2] & 0xff) << 16) | + ((pdadc_out[4 * i + 3] & 0xff) << 24), AR5K_PHY_PDADC_TXPOWER(i)); } } diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index bbeef3aac93..19aefdb7541 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -142,10 +142,10 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) /* Set 32MHz USEC counter */ if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_radio == AR5K_RF2316) || - (ah->ah_radio == AR5K_RF2317)) - /* Remain on 40MHz clock ? */ + (ah->ah_radio == AR5K_RF5413) || + (ah->ah_radio == AR5K_RF2316) || + (ah->ah_radio == AR5K_RF2317)) + /* Remain on 40MHz clock ? */ sclock = 40 - 1; else sclock = 32 - 1; -- cgit v1.2.3-70-g09d2 From e2df64c1d767eb52a5c617668e20745d5e3015c8 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:14:19 -0400 Subject: ath5k: use kstrtoint() to parse numbers coming from sysfs Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c index 1090bbab945..5406f44309c 100644 --- a/drivers/net/wireless/ath/ath5k/sysfs.c +++ b/drivers/net/wireless/ath/ath5k/sysfs.c @@ -19,9 +19,11 @@ static ssize_t ath5k_attr_store_##name(struct device *dev, \ const char *buf, size_t count) \ { \ struct ath5k_softc *sc = dev_get_drvdata(dev); \ - int val; \ + int val, ret; \ \ - val = (int)simple_strtoul(buf, NULL, 10); \ + ret = kstrtoint(buf, 10, &val); \ + if (ret < 0) \ + return ret; \ set(sc->ah, val); \ return count; \ } \ -- cgit v1.2.3-70-g09d2 From 4fc5401c144d95b031e839ba3208e04c79ac84cb Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 7 Jul 2011 18:14:25 -0400 Subject: ath5k: read sc->imask with sc->irqlock held Signed-off-by: Pavel Roskin sc->imask may change if ath5k_set_current_imask() races against itself. Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 58997d3abae..28113e023c6 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1447,10 +1447,11 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) static void ath5k_set_current_imask(struct ath5k_softc *sc) { - enum ath5k_int imask = sc->imask; + enum ath5k_int imask; unsigned long flags; spin_lock_irqsave(&sc->irqlock, flags); + imask = sc->imask; if (sc->rx_pending) imask &= ~AR5K_INT_RX_ALL; if (sc->tx_pending) -- cgit v1.2.3-70-g09d2 From e6faada5daddcdf29056c8abee0869d4e2cd55b5 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 7 Jul 2011 17:33:19 -0700 Subject: mwifiex: fix regression in WEP security mode Htcapinfo is unnecessarily sent in assoc request in WEP security due to a regression introduced by commit 2be50b8df53 (mwifiex: remove redundant encryption_mode mapping). The issue is fixed in this patch. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 687c1f22349..4487d935654 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -960,7 +960,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); if (sme->key) { - if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) { + if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) { dev_dbg(priv->adapter->dev, "info: setting wep encryption" " with key len %d\n", sme->key_len); -- cgit v1.2.3-70-g09d2 From 38869d79e5b498bd35c9967231dfb01cdd301bf5 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 7 Jul 2011 17:33:20 -0700 Subject: mwifiex: fix minor issue in debugfs command 'info' Debugfs command 'info' shows wrong interface type. The regression occurred due to commit eecd8250e (mwifiex: remove MWIFIEX_BSS_MODE_ macros) in which we replaced MWIFIEX_BSS_MODE_* macros by NL80211_IFTYPE_*, for example, MWIFIEX_BSS_MODE_IBSS (2) --> NL80211_IFTYPE_ADHOC (1) The issue is fixed by swapping static character array used to display interface type information. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 46d65e02c7b..1bcf9eaa107 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -27,8 +27,8 @@ static struct dentry *mwifiex_dfs_dir; static char *bss_modes[] = { "Unknown", - "Managed", "Ad-hoc", + "Managed", "Auto" }; -- cgit v1.2.3-70-g09d2 From e156103cee78a1dd1c0d14efe08aa36fc9285013 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Thu, 7 Jul 2011 17:37:09 -0700 Subject: mwifiex: 4-byte alignment in mwifiex_process_sta_txpd() In XMIT path, the skb that we get from the kernel itself is not aligned with 4-byte boundary on some embedded platforms. Had it not been the presence of tx_pkt_offset field in txpd, 4 byte memory alignment was not possible without memmove of entire skb. And that would have increased MIPS instead of reducing. With this patch few memory cycles can be saved while fetching interface header and txpd structure because of 4 bytes memory alignment. Reported-by: Philip Rakity Signed-off-by: Yogesh Ashok Powar Tested-by: Philip Rakity Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/decl.h | 4 +++- drivers/net/wireless/mwifiex/sta_tx.c | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 0e90b0986ed..94ddc9038cb 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -30,7 +30,9 @@ #define MWIFIEX_MAX_BSS_NUM (1) -#define MWIFIEX_MIN_DATA_HEADER_LEN 32 /* (sizeof(mwifiex_txpd)) */ +#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd) + * + 4 byte alignment + */ #define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2 #define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16 diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index fa6221bc910..1822bfad889 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -47,6 +47,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; struct txpd *local_tx_pd; struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); + u8 pad; if (!skb->len) { dev_err(adapter->dev, "Tx: bad packet length: %d\n", @@ -55,15 +56,19 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, return skb->data; } - BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN)); - skb_push(skb, sizeof(*local_tx_pd)); + /* If skb->data is not aligned; add padding */ + pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; + + BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN + + pad)); + skb_push(skb, sizeof(*local_tx_pd) + pad); local_tx_pd = (struct txpd *) skb->data; memset(local_tx_pd, 0, sizeof(struct txpd)); local_tx_pd->bss_num = priv->bss_num; local_tx_pd->bss_type = priv->bss_type; local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - - sizeof(struct txpd))); + (sizeof(struct txpd) + pad))); local_tx_pd->priority = (u8) skb->priority; local_tx_pd->pkt_delay_2ms = @@ -88,7 +93,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, } /* Offset of actual data */ - local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); + local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) + pad); /* make space for INTF_HEADER_LEN */ skb_push(skb, INTF_HEADER_LEN); -- cgit v1.2.3-70-g09d2 From 331c5ea2d92c76bfe58a9bb5e6d21160850a29bc Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 8 Jul 2011 13:01:32 +0530 Subject: ath9k_hw: Disable PAPRD based on paprd_ht20_mask for 5GHz Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 30 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 2 ++ 2 files changed, 32 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index de1972307b0..f80d1d63398 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -21,6 +21,36 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath9k_channel *chan = ah->curchan; + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + + /* + * 3 bits for modalHeader5G.papdRateMaskHt20 + * is used for sub-band disabling of PAPRD. + * 5G band is divided into 3 sub-bands -- upper, + * middle, lower. + * if bit 30 of modalHeader5G.papdRateMaskHt20 is set + * -- disable PAPRD for upper band 5GHz + * if bit 29 of modalHeader5G.papdRateMaskHt20 is set + * -- disable PAPRD for middle band 5GHz + * if bit 28 of modalHeader5G.papdRateMaskHt20 is set + * -- disable PAPRD for lower band 5GHz + */ + + if (IS_CHAN_5GHZ(chan)) { + if (chan->channel >= UPPER_5G_SUB_BAND_START) { + if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20) + & BIT(30)) + val = false; + } else if (chan->channel >= MID_5G_SUB_BAND_START) { + if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20) + & BIT(29)) + val = false; + } else { + if (le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20) + & BIT(28)) + val = false; + } + } if (val) { ah->paprd_table_write_done = true; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 818acdd1ba9..a1c317455bc 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -143,6 +143,8 @@ #define AR_KEYTABLE_SIZE 128 #define POWER_UP_TIME 10000 #define SPUR_RSSI_THRESH 40 +#define UPPER_5G_SUB_BAND_START 5700 +#define MID_5G_SUB_BAND_START 5400 #define CAB_TIMEOUT_VAL 10 #define BEACON_TIMEOUT_VAL 10 -- cgit v1.2.3-70-g09d2 From 6fea2b15cc166e8e8851083395c17314c7bd874a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 8 Jul 2011 18:12:00 +0530 Subject: ath9k_hw: Update AR9003 interval to improve 5G Tx EVM The number of temperature reading samples to average during a Tx packet is decreased to 1 from 2 to improve 5G Tx EVM with chain 0-only mode. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index e8ac70da5ac..39efcbf4ba1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -780,7 +780,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = { {0x0000a43c, 0x00100000}, {0x0000a440, 0x00000000}, {0x0000a444, 0x00000000}, - {0x0000a448, 0x06000080}, + {0x0000a448, 0x05000080}, {0x0000a44c, 0x00000001}, {0x0000a450, 0x00010000}, {0x0000a458, 0x00000000}, -- cgit v1.2.3-70-g09d2 From 43d9325b2477b556ac1cc95cf15f40cbd4100e5d Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 8 Jul 2011 18:12:01 +0530 Subject: ath9k_hw: Disable power detector calibration for AR9003 The power detector calibration is disabled because this block doesn't exist in AR9003 based chips and also parallel calibration is enabled otherwise the calibration will never stop. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 39efcbf4ba1..cbe765b5ed1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -654,7 +654,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = { {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, - {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, + {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000}, @@ -761,7 +761,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = { {0x0000a3ec, 0x20202020}, {0x0000a3f0, 0x00000000}, {0x0000a3f4, 0x00000246}, - {0x0000a3f8, 0x0cdbd380}, + {0x0000a3f8, 0x0c9bd380}, {0x0000a3fc, 0x000f0f01}, {0x0000a400, 0x8fa91f01}, {0x0000a404, 0x00000000}, -- cgit v1.2.3-70-g09d2 From 1fa1238e50385707b8e9fea97d16252c931448d8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 8 Jul 2011 18:12:02 +0530 Subject: ath9k_hw: Remove read-only registers from AR9003 intervals This patch removes read only registers that cause invalid address access and also updates index for measurement filter calibration window size. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index cbe765b5ed1..2339728a730 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -653,7 +653,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = { {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, + {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, @@ -1500,8 +1500,6 @@ static const u32 ar9300_2p2_mac_core[][2] = { {0x0000816c, 0x00000000}, {0x000081c0, 0x00000000}, {0x000081c4, 0x33332210}, - {0x000081c8, 0x00000000}, - {0x000081cc, 0x00000000}, {0x000081ec, 0x00000000}, {0x000081f0, 0x00000000}, {0x000081f4, 0x00000000}, -- cgit v1.2.3-70-g09d2 From 8ae2e12f1534e647d4a816755e5a09c2de6f9fca Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 8 Jul 2011 18:12:03 +0530 Subject: ath9k_htc: Inform stack about tx ack status Recent firmware changes report tx ack status properly to driver. Hence updating ath9k_htc driver capabilities. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 61e6d395071..3bea7ea86f0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -754,6 +754,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; hw->wiphy->interface_modes = -- cgit v1.2.3-70-g09d2 From aa5ca96c8fffea769aedd795f48695112393dc89 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 7 Jul 2011 13:40:00 +0000 Subject: sky2: force receive checksum when using RSS on some hardware (v2) Found when reviewing the vendor driver. Apparently some chip versions require receive checksumming to be enabled in order for RSS to work. Also, if fix_features has to change some settings; put in message in log in similar manner to netdev_fix_features. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 20 +++++++++++++++++--- drivers/net/sky2.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index c91513ed784..3fc8683b2ff 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2996,7 +2996,8 @@ static int __devinit sky2_init(struct sky2_hw *hw) hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY | SKY2_HW_NEW_LE - | SKY2_HW_ADV_POWER_CTL; + | SKY2_HW_ADV_POWER_CTL + | SKY2_HW_RSS_CHKSUM; /* New transmit checksum */ if (hw->chip_rev != CHIP_REV_YU_EX_B0) @@ -3024,7 +3025,7 @@ static int __devinit sky2_init(struct sky2_hw *hw) /* The workaround for status conflicts VLAN tag detection. */ if (hw->chip_rev == CHIP_REV_YU_FE2_A0) - hw->flags |= SKY2_HW_VLAN_BROKEN; + hw->flags |= SKY2_HW_VLAN_BROKEN | SKY2_HW_RSS_CHKSUM; break; case CHIP_ID_YUKON_SUPR: @@ -3033,6 +3034,9 @@ static int __devinit sky2_init(struct sky2_hw *hw) | SKY2_HW_NEW_LE | SKY2_HW_AUTO_TX_SUM | SKY2_HW_ADV_POWER_CTL; + + if (hw->chip_rev == CHIP_REV_YU_SU_A0) + hw->flags |= SKY2_HW_RSS_CHKSUM; break; case CHIP_ID_YUKON_UL_2: @@ -4176,8 +4180,18 @@ static u32 sky2_fix_features(struct net_device *dev, u32 features) /* In order to do Jumbo packets on these chips, need to turn off the * transmit store/forward. Therefore checksum offload won't work. */ - if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) + if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) { + netdev_info(dev, "checksum offload not possible with jumbo frames\n"); features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM); + } + + /* Some hardware requires receive checksum for RSS to work. */ + if ( (features & NETIF_F_RXHASH) && + !(features & NETIF_F_RXCSUM) && + (sky2->hw->flags & SKY2_HW_RSS_CHKSUM)) { + netdev_info(dev, "receive hashing forces receive checksum\n"); + features |= NETIF_F_RXCSUM; + } return features; } diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 318c9ae7bf9..030221f4ea8 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -2281,6 +2281,7 @@ struct sky2_hw { #define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */ #define SKY2_HW_RSS_BROKEN 0x00000100 #define SKY2_HW_VLAN_BROKEN 0x00000200 +#define SKY2_HW_RSS_CHKSUM 0x00000400 /* RSS requires chksum */ u8 chip_id; u8 chip_rev; -- cgit v1.2.3-70-g09d2 From 8e11680f5e1abc85298c12a99e2b741249eadc0c Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 7 Jul 2011 05:50:58 +0000 Subject: sky2: use correct Inter Packet Gap at 10/100mbit This is another fix picked out of the vendor driver. The IPG value in the serial mode register is supposed to be programmed differently at lower speeds. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 25 ++++++++++++++++++++++--- drivers/net/sky2.h | 7 ++++--- 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3fc8683b2ff..b1a675a94a1 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -714,6 +714,20 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } +/* configure IPG according to used link speed */ +static void sky2_set_ipg(struct sky2_port *sky2) +{ + u16 reg; + + reg = gma_read16(sky2->hw, sky2->port, GM_SERIAL_MODE); + reg &= ~GM_SMOD_IPG_MSK; + if (sky2->speed > SPEED_100) + reg |= IPG_DATA_VAL(IPG_DATA_DEF_1000); + else + reg |= IPG_DATA_VAL(IPG_DATA_DEF_10_100); + gma_write16(sky2->hw, sky2->port, GM_SERIAL_MODE, reg); +} + /* Enable Rx/Tx */ static void sky2_enable_rx_tx(struct sky2_port *sky2) { @@ -882,7 +896,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) /* serial mode register */ reg = DATA_BLIND_VAL(DATA_BLIND_DEF) | - GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); + GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF_1000); if (hw->dev[port]->mtu > ETH_DATA_LEN) reg |= GM_SMOD_JUMBO_ENA; @@ -2053,6 +2067,8 @@ static void sky2_link_up(struct sky2_port *sky2) [FC_BOTH] = "both", }; + sky2_set_ipg(sky2); + sky2_enable_rx_tx(sky2); gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); @@ -2290,8 +2306,11 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; netdev_update_features(dev); - mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | - GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); + mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | GM_SMOD_VLAN_ENA; + if (sky2->speed > SPEED_100) + mode |= IPG_DATA_VAL(IPG_DATA_DEF_1000); + else + mode |= IPG_DATA_VAL(IPG_DATA_DEF_10_100); if (dev->mtu > ETH_DATA_LEN) mode |= GM_SMOD_JUMBO_ENA; diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 030221f4ea8..530378a6602 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1807,10 +1807,11 @@ enum { }; #define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK) -#define DATA_BLIND_DEF 0x04 - #define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK) -#define IPG_DATA_DEF 0x1e + +#define DATA_BLIND_DEF 0x04 +#define IPG_DATA_DEF_1000 0x1e +#define IPG_DATA_DEF_10_100 0x18 /* GM_SMI_CTRL 16 bit r/w SMI Control Register */ enum { -- cgit v1.2.3-70-g09d2 From 4fb99cd6ac4fe6d03a334a6f4ebb2bbfc4b479ed Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 7 Jul 2011 05:50:59 +0000 Subject: sky2: support for new Optima chipsets (EXPERIMENTAL) This is a backport from the vendor driver of support for the newer Optima (Prime and 2) chipsets. It also includes some setup changes for the current Optima chip as well. The code and comments intentionally mirror the vendor sk98lin driver to allow for easier maintenance. Although this adds support for new chip id's, these chip id's are not used by any of the current PCI device id's listed in the driver. The patch is just to get initial infrastructure in place to handle them when they come. I don't have access to any of this hardware to actually test it yet. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++---- drivers/net/sky2.h | 8 +++-- 2 files changed, 89 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index b1a675a94a1..6d6a56bf0ac 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -365,6 +365,17 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec); } } else { + if (hw->chip_id >= CHIP_ID_YUKON_OPT) { + u16 ctrl2 = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL_2); + + /* enable PHY Reverse Auto-Negotiation */ + ctrl2 |= 1u << 13; + + /* Write PHY changes (SW-reset must follow) */ + gm_phy_write(hw, port, PHY_MARV_EXT_CTRL_2, ctrl2); + } + + /* disable energy detect */ ctrl &= ~PHY_M_PC_EN_DET_MSK; @@ -626,6 +637,63 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) if (ledover) gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); + } else if (hw->chip_id == CHIP_ID_YUKON_PRM && + (sky2_read8(hw, B2_MAC_CFG) & 0xf) == 0x7) { + int i; + /* This a phy register setup workaround copied from vendor driver. */ + static const struct { + u16 reg, val; + } eee_afe[] = { + { 0x156, 0x58ce }, + { 0x153, 0x99eb }, + { 0x141, 0x8064 }, + /* { 0x155, 0x130b },*/ + { 0x000, 0x0000 }, + { 0x151, 0x8433 }, + { 0x14b, 0x8c44 }, + { 0x14c, 0x0f90 }, + { 0x14f, 0x39aa }, + /* { 0x154, 0x2f39 },*/ + { 0x14d, 0xba33 }, + { 0x144, 0x0048 }, + { 0x152, 0x2010 }, + /* { 0x158, 0x1223 },*/ + { 0x140, 0x4444 }, + { 0x154, 0x2f3b }, + { 0x158, 0xb203 }, + { 0x157, 0x2029 }, + }; + + /* Start Workaround for OptimaEEE Rev.Z0 */ + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fb); + + gm_phy_write(hw, port, 1, 0x4099); + gm_phy_write(hw, port, 3, 0x1120); + gm_phy_write(hw, port, 11, 0x113c); + gm_phy_write(hw, port, 14, 0x8100); + gm_phy_write(hw, port, 15, 0x112a); + gm_phy_write(hw, port, 17, 0x1008); + + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fc); + gm_phy_write(hw, port, 1, 0x20b0); + + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff); + + for (i = 0; i < ARRAY_SIZE(eee_afe); i++) { + /* apply AFE settings */ + gm_phy_write(hw, port, 17, eee_afe[i].val); + gm_phy_write(hw, port, 16, eee_afe[i].reg | 1u<<13); + } + + /* End Workaround for OptimaEEE */ + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); + + /* Enable 10Base-Te (EEE) */ + if (hw->chip_id >= CHIP_ID_YUKON_PRM) { + reg = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); + gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, + reg | PHY_M_10B_TE_ENABLE); + } } /* Enable phy interrupt on auto-negotiation complete (or link up) */ @@ -2959,6 +3027,8 @@ static u32 sky2_mhz(const struct sky2_hw *hw) case CHIP_ID_YUKON_SUPR: case CHIP_ID_YUKON_UL_2: case CHIP_ID_YUKON_OPT: + case CHIP_ID_YUKON_PRM: + case CHIP_ID_YUKON_OP_2: return 125; case CHIP_ID_YUKON_FE: @@ -3064,6 +3134,8 @@ static int __devinit sky2_init(struct sky2_hw *hw) break; case CHIP_ID_YUKON_OPT: + case CHIP_ID_YUKON_PRM: + case CHIP_ID_YUKON_OP_2: hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEW_LE | SKY2_HW_ADV_POWER_CTL; @@ -3163,30 +3235,33 @@ static void sky2_reset(struct sky2_hw *hw) sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS); } - if (hw->chip_id == CHIP_ID_YUKON_OPT) { + if (hw->chip_id == CHIP_ID_YUKON_OPT || + hw->chip_id == CHIP_ID_YUKON_PRM || + hw->chip_id == CHIP_ID_YUKON_OP_2) { u16 reg; u32 msk; - if (hw->chip_rev == 0) { + if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) { /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */ sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7)); /* set PHY Link Detect Timer to 1.1 second (11x 100ms) */ reg = 10; + + /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */ + sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16)); } else { /* set PHY Link Detect Timer to 0.4 second (4x 100ms) */ reg = 3; } reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE; + reg |= PSM_CONFIG_REG4_RST_PHY_LINK_DETECT; /* reset PHY Link Detect */ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - sky2_pci_write16(hw, PSM_CONFIG_REG4, - reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT); sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); - /* enable PHY Quick Link */ msk = sky2_read32(hw, B0_IMSK); msk |= Y2_IS_PHY_QLNK; @@ -4710,9 +4785,11 @@ static const char *sky2_name(u8 chipid, char *buf, int sz) "UL 2", /* 0xba */ "Unknown", /* 0xbb */ "Optima", /* 0xbc */ + "Optima Prime", /* 0xbd */ + "Optima 2", /* 0xbe */ }; - if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OPT) + if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OP_2) strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz); else snprintf(buf, sz, "(chip %#x)", chipid); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 530378a6602..0af31b8b5f1 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -412,7 +412,7 @@ enum { Y2_IS_HW_ERR = 1<<31, /* Interrupt HW Error */ Y2_IS_STAT_BMU = 1<<30, /* Status BMU Interrupt */ Y2_IS_ASF = 1<<29, /* ASF subsystem Interrupt */ - + Y2_IS_CPU_TO = 1<<28, /* CPU Timeout */ Y2_IS_POLL_CHK = 1<<27, /* Check IRQ from polling unit */ Y2_IS_TWSI_RDY = 1<<26, /* IRQ on end of TWSI Tx */ Y2_IS_IRQ_SW = 1<<25, /* SW forced IRQ */ @@ -547,6 +547,8 @@ enum { CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */ CHIP_ID_YUKON_UL_2 = 0xba, /* YUKON-2 Ultra 2 */ CHIP_ID_YUKON_OPT = 0xbc, /* YUKON-2 Optima */ + CHIP_ID_YUKON_PRM = 0xbd, /* YUKON-2 Optima Prime */ + CHIP_ID_YUKON_OP_2 = 0xbe, /* YUKON-2 Optima 2 */ }; enum yukon_xl_rev { @@ -1420,8 +1422,10 @@ enum { PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */ PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */ PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */ - PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */}; + PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */ + PHY_M_10B_TE_ENABLE = 1<<7, /* 10Base-Te Enable (88E8079 and above) */ +}; #define PHY_M_EC_M_DSC(x) ((u16)(x)<<10 & PHY_M_EC_M_DSC_MSK) /* 00=1x; 01=2x; 10=3x; 11=4x */ #define PHY_M_EC_S_DSC(x) ((u16)(x)<<8 & PHY_M_EC_S_DSC_MSK) -- cgit v1.2.3-70-g09d2 From 4ec8f0ca2ab6e1f89fd0ea73ede92a2e2d7409ef Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 7 Jul 2011 05:51:00 +0000 Subject: sky2: version 1.29 Since new hardware chip support was added bump version. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 6d6a56bf0ac..57339da7632 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -50,7 +50,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.28" +#define DRV_VERSION "1.29" /* * The Yukon II chipset takes 64 bit command blocks (called list elements) -- cgit v1.2.3-70-g09d2 From 560040b8400bbc9074ff23afb28891378482ee52 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 7 Jul 2011 05:51:01 +0000 Subject: skge/sky2: change config references to Marvell Change references to SysKonnect in Kconfig to Marvell since SysKonnect was acquired by Marvell back in 2002. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7cae8b619e5..17ed4dda7c0 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2272,7 +2272,7 @@ config SIS190 will be called sis190. This is recommended. config SKGE - tristate "SysKonnect GigaEthernet support" + tristate "Marvell Yukon Gigabit Ethernet support" depends on PCI select CRC32 ---help--- @@ -2288,7 +2288,7 @@ config SKGE Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872. It does not support the newer Yukon2 chipset: a separate driver, - sky2, is provided for Yukon2-based adapters. + sky2, is provided for these adapters. To compile this driver as a module, choose M here: the module will be called skge. This is recommended. @@ -2313,7 +2313,7 @@ config SKGE_GENESIS by making code smaller. If unsure say Y. config SKY2 - tristate "SysKonnect Yukon2 support" + tristate "Marvell Yukon 2 support" depends on PCI select CRC32 ---help--- @@ -2323,7 +2323,7 @@ config SKY2 88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21 There is companion driver for the older Marvell Yukon and - Genesis based adapters: skge. + SysKonnect Genesis based adapters: skge. To compile this driver as a module, choose M here: the module will be called sky2. This is recommended. -- cgit v1.2.3-70-g09d2 From 498d8e236304a62a2774d7264bdff2c6e8102b5b Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 7 Jul 2011 22:06:26 +0000 Subject: drivers/net: Omit check for multicast bit in netdev_for_each_mc_addr There is no need to check for the address being a multicast address in the netdev_for_each_mc_addr loop, so remove it. This patch covers all remaining network drivers still containing such a check. Cc: Joe Perches Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/7990.c | 9 +-------- drivers/net/a2065.c | 9 +-------- drivers/net/bmac.c | 8 +------- drivers/net/declance.c | 9 +-------- drivers/net/ewrk3.c | 31 ++++++++++++++----------------- drivers/net/fec.c | 4 ---- drivers/net/hp100.c | 18 ++++++++---------- drivers/net/ioc3-eth.c | 7 +------ drivers/net/korina.c | 7 +------ drivers/net/ks8851_mll.c | 2 -- drivers/net/ksz884x.c | 2 -- drivers/net/pcnet32.c | 9 +-------- drivers/net/smc911x.c | 5 ----- drivers/net/smc9194.c | 5 ----- drivers/net/smc91x.c | 5 ----- drivers/net/sunbmac.c | 8 +------- drivers/net/sungem.c | 7 +------ drivers/net/sunhme.c | 16 ++-------------- drivers/net/sunlance.c | 8 +------- drivers/net/sunqe.c | 7 +------ 20 files changed, 35 insertions(+), 141 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 903bcb3ef5b..60b35fb5f52 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -594,7 +594,6 @@ static void lance_load_multicast (struct net_device *dev) volatile struct lance_init_block *ib = lp->init_block; volatile u16 *mcast_table = (u16 *)&ib->filter; struct netdev_hw_addr *ha; - char *addrs; u32 crc; /* set all multicast bits */ @@ -609,13 +608,7 @@ static void lance_load_multicast (struct net_device *dev) /* Add addresses */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - /* multicast address? */ - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc = crc >> 26; mcast_table [crc >> 4] |= 1 << (crc & 0xf); } diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 7d9a1a6ea8b..e1e1b07d9b8 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -587,7 +587,6 @@ static void lance_load_multicast(struct net_device *dev) volatile struct lance_init_block *ib = lp->init_block; volatile u16 *mcast_table = (u16 *)&ib->filter; struct netdev_hw_addr *ha; - char *addrs; u32 crc; /* set all multicast bits */ @@ -602,13 +601,7 @@ static void lance_load_multicast(struct net_device *dev) /* Add addresses */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - /* multicast address? */ - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc = crc >> 26; mcast_table[crc >> 4] |= 1 << (crc & 0xf); } diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index d2e58e2bea7..45e45e8d3d6 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1015,7 +1015,6 @@ static void bmac_set_multicast(struct net_device *dev) static void bmac_set_multicast(struct net_device *dev) { struct netdev_hw_addr *ha; - char *addrs; int i; unsigned short rx_cfg; u32 crc; @@ -1039,12 +1038,7 @@ static void bmac_set_multicast(struct net_device *dev) for(i = 0; i < 4; i++) hash_table[i] = 0; netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - if(!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc >>= 26; hash_table[crc >> 4] |= 1 << (crc & 0xf); } diff --git a/drivers/net/declance.c b/drivers/net/declance.c index cabd3a542ef..d5598f6584a 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -946,7 +946,6 @@ static void lance_load_multicast(struct net_device *dev) struct lance_private *lp = netdev_priv(dev); volatile u16 *ib = (volatile u16 *)dev->mem_start; struct netdev_hw_addr *ha; - char *addrs; u32 crc; /* set all multicast bits */ @@ -965,13 +964,7 @@ static void lance_load_multicast(struct net_device *dev) /* Add addresses */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - /* multicast address? */ - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(ETH_ALEN, addrs); + crc = ether_crc_le(ETH_ALEN, ha->addr); crc = crc >> 26; *lib_ptr(ib, filter[crc >> 4], lp->type) |= 1 << (crc & 0xf); } diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index d1e229f9e54..05a5f71451a 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -1169,7 +1169,7 @@ static void SetMulticastFilter(struct net_device *dev) struct netdev_hw_addr *ha; u_long iobase = dev->base_addr; int i; - char *addrs, bit, byte; + char bit, byte; short __iomem *p = lp->mctbl; u16 hashcode; u32 crc; @@ -1211,25 +1211,22 @@ static void SetMulticastFilter(struct net_device *dev) /* Update table */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - if ((*addrs & 0x01) == 1) { /* multicast address? */ - crc = ether_crc_le(ETH_ALEN, addrs); - hashcode = crc & ((1 << 9) - 1); /* hashcode is 9 LSb of CRC */ + crc = ether_crc_le(ETH_ALEN, ha->addr); + hashcode = crc & ((1 << 9) - 1); /* hashcode is 9 LSb of CRC */ - byte = hashcode >> 3; /* bit[3-8] -> byte in filter */ - bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */ + byte = hashcode >> 3; /* bit[3-8] -> byte in filter */ + bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */ - if (lp->shmem_length == IO_ONLY) { - u_char tmp; + if (lp->shmem_length == IO_ONLY) { + u_char tmp; - outw(PAGE0_HTE + byte, EWRK3_PIR1); - tmp = inb(EWRK3_DATA); - tmp |= bit; - outw(PAGE0_HTE + byte, EWRK3_PIR1); - outb(tmp, EWRK3_DATA); - } else { - writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte); - } + outw(PAGE0_HTE + byte, EWRK3_PIR1); + tmp = inb(EWRK3_DATA); + tmp |= bit; + outw(PAGE0_HTE + byte, EWRK3_PIR1); + outb(tmp, EWRK3_DATA); + } else { + writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte); } } } diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 7ae3f281420..5b631fe7473 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1227,10 +1227,6 @@ static void set_multicast_list(struct net_device *ndev) writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); netdev_for_each_mc_addr(ha, ndev) { - /* Only support group multicast for now */ - if (!(ha->addr[0] & 1)) - continue; - /* calculate crc32 value of mac address */ crc = 0xffffffff; diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index c3ecb118c1d..b6519c1ba7e 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -2103,20 +2103,18 @@ static void hp100_set_multicast_list(struct net_device *dev) #endif netdev_for_each_mc_addr(ha, dev) { addrs = ha->addr; - if ((*addrs & 0x01) == 0x01) { /* multicast address? */ #ifdef HP100_DEBUG - printk("hp100: %s: multicast = %pM, ", - dev->name, addrs); + printk("hp100: %s: multicast = %pM, ", + dev->name, addrs); #endif - for (i = idx = 0; i < 6; i++) { - idx ^= *addrs++ & 0x3f; - printk(":%02x:", idx); - } + for (i = idx = 0; i < 6; i++) { + idx ^= *addrs++ & 0x3f; + printk(":%02x:", idx); + } #ifdef HP100_DEBUG - printk("idx = %i\n", idx); + printk("idx = %i\n", idx); #endif - lp->hash_bytes[idx >> 3] |= (1 << (idx & 7)); - } + lp->hash_bytes[idx >> 3] |= (1 << (idx & 7)); } } #else diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 318a25a9231..a234e450452 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -1664,12 +1664,7 @@ static void ioc3_set_multicast_list(struct net_device *dev) ip->ehar_l = 0xffffffff; } else { netdev_for_each_mc_addr(ha, dev) { - char *addr = ha->addr; - - if (!(*addr & 1)) - continue; - - ehar |= (1UL << ioc3_hash(addr)); + ehar |= (1UL << ioc3_hash(ha->addr)); } ip->ehar_h = ehar >> 32; ip->ehar_l = ehar & 0xffffffff; diff --git a/drivers/net/korina.c b/drivers/net/korina.c index c7a9bef4dfb..763844c587f 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -504,12 +504,7 @@ static void korina_multicast_list(struct net_device *dev) hash_table[i] = 0; netdev_for_each_mc_addr(ha, dev) { - char *addrs = ha->addr; - - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc >>= 26; hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); } diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index a82378231fc..d19c849059d 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -1190,8 +1190,6 @@ static void ks_set_rx_mode(struct net_device *netdev) int i = 0; netdev_for_each_mc_addr(ha, netdev) { - if (!(*ha->addr & 1)) - continue; if (i >= MAX_MCAST_LST) break; memcpy(ks->mcast_lst[i++], ha->addr, ETH_ALEN); diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 2ac6c6c984b..27418d31a09 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -5785,8 +5785,6 @@ static void netdev_set_rx_mode(struct net_device *dev) } netdev_for_each_mc_addr(ha, dev) { - if (!(*ha->addr & 1)) - continue; if (i >= MAX_MULTICAST_LIST) break; memcpy(hw->multi_list[i++], ha->addr, MAC_ADDR_LEN); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index b48aba9e422..8b3090dc4bc 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -2570,7 +2570,6 @@ static void pcnet32_load_multicast(struct net_device *dev) volatile __le16 *mcast_table = (__le16 *)ib->filter; struct netdev_hw_addr *ha; unsigned long ioaddr = dev->base_addr; - char *addrs; int i; u32 crc; @@ -2590,13 +2589,7 @@ static void pcnet32_load_multicast(struct net_device *dev) /* Add addresses */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - /* multicast address? */ - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc = crc >> 26; mcast_table[crc >> 4] |= cpu_to_le16(1 << (crc & 0xf)); } diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 053863aefb1..a91fe172302 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -1351,11 +1351,6 @@ static void smc911x_set_multicast_list(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { u32 position; - /* make sure this is a multicast address - - shouldn't this be a given if we have it here ? */ - if (!(*ha->addr & 1)) - continue; - /* upper 6 bits are used as hash index */ position = ether_crc(ETH_ALEN, ha->addr)>>26; diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index 7486d090806..5b65ac4b3ce 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -447,11 +447,6 @@ static void smc_setmulticast(int ioaddr, struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { int position; - /* make sure this is a multicast address - shouldn't this - be a given if we have it here ? */ - if (!(*ha->addr & 1)) - continue; - /* only use the low order bits */ position = ether_crc_le(6, ha->addr) & 0x3f; diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index f6285748bd3..2b1d254d59a 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1425,11 +1425,6 @@ static void smc_set_multicast_list(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { int position; - /* make sure this is a multicast address - - shouldn't this be a given if we have it here ? */ - if (!(*ha->addr & 1)) - continue; - /* only use the low order bits */ position = crc32_le(~0, ha->addr, 6) & 0x3f; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index aa4765803a4..297a4242106 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -998,7 +998,6 @@ static void bigmac_set_multicast(struct net_device *dev) struct bigmac *bp = netdev_priv(dev); void __iomem *bregs = bp->bregs; struct netdev_hw_addr *ha; - char *addrs; int i; u32 tmp, crc; @@ -1027,12 +1026,7 @@ static void bigmac_set_multicast(struct net_device *dev) hash_table[i] = 0; netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc >>= 26; hash_table[crc >> 4] |= 1 << (crc & 0xf); } diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 71d4a0329d0..ade35dde5b5 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1802,12 +1802,7 @@ static u32 gem_setup_multicast(struct gem *gp) memset(hash_table, 0, sizeof(hash_table)); netdev_for_each_mc_addr(ha, gp->dev) { - char *addrs = ha->addr; - - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc >>= 24; hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); } diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 30aad54b1b3..856e05b9fba 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1524,17 +1524,11 @@ static int happy_meal_init(struct happy_meal *hp) } else if ((hp->dev->flags & IFF_PROMISC) == 0) { u16 hash_table[4]; struct netdev_hw_addr *ha; - char *addrs; u32 crc; memset(hash_table, 0, sizeof(hash_table)); netdev_for_each_mc_addr(ha, hp->dev) { - addrs = ha->addr; - - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc >>= 26; hash_table[crc >> 4] |= 1 << (crc & 0xf); } @@ -2361,7 +2355,6 @@ static void happy_meal_set_multicast(struct net_device *dev) struct happy_meal *hp = netdev_priv(dev); void __iomem *bregs = hp->bigmacregs; struct netdev_hw_addr *ha; - char *addrs; u32 crc; spin_lock_irq(&hp->happy_lock); @@ -2379,12 +2372,7 @@ static void happy_meal_set_multicast(struct net_device *dev) memset(hash_table, 0, sizeof(hash_table)); netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - if (!(*addrs & 1)) - continue; - - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc >>= 26; hash_table[crc >> 4] |= 1 << (crc & 0xf); } diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 32a5c7f63c4..06f2d4382dc 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1170,7 +1170,6 @@ static void lance_load_multicast(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); struct netdev_hw_addr *ha; - char *addrs; u32 crc; u32 val; @@ -1195,12 +1194,7 @@ static void lance_load_multicast(struct net_device *dev) /* Add addresses */ netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - /* multicast address? */ - if (!(*addrs & 1)) - continue; - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc = crc >> 26; if (lp->pio_buffer) { struct lance_init_block __iomem *ib = lp->init_block_iomem; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 18ecdc30375..209c7f8df00 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -628,7 +628,6 @@ static void qe_set_multicast(struct net_device *dev) struct sunqe *qep = netdev_priv(dev); struct netdev_hw_addr *ha; u8 new_mconfig = qep->mconfig; - char *addrs; int i; u32 crc; @@ -651,11 +650,7 @@ static void qe_set_multicast(struct net_device *dev) memset(hash_table, 0, sizeof(hash_table)); netdev_for_each_mc_addr(ha, dev) { - addrs = ha->addr; - - if (!(*addrs & 1)) - continue; - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(6, ha->addr); crc >>= 26; hash_table[crc >> 4] |= 1 << (crc & 0xf); } -- cgit v1.2.3-70-g09d2 From 0a0e2344a62ce9e7fac6129d6292e59aecfceced Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 8 Jul 2011 05:29:30 +0000 Subject: bna: use netdev_alloc_skb_ip_align() Some workloads need some headroom (NET_SKB_PAD) to avoid expensive reallocations. Using netdev_alloc_skb_ip_align() instead of bare skb_alloc() brings the NET_IP_ALIGN and the NET_SKB_PAD headroom. Signed-off-by: Eric Dumazet CC: Rasesh Mody CC: Debashis Dutt Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 44e219c910d..795b93b73b1 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -386,14 +386,12 @@ bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, wi_range); } - skb = alloc_skb(rcb->rxq->buffer_size + NET_IP_ALIGN, - GFP_ATOMIC); + skb = netdev_alloc_skb_ip_align(bnad->netdev, + rcb->rxq->buffer_size); if (unlikely(!skb)) { BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed); goto finishing; } - skb->dev = bnad->netdev; - skb_reserve(skb, NET_IP_ALIGN); unmap_array[unmap_prod].skb = skb; dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data, rcb->rxq->buffer_size, -- cgit v1.2.3-70-g09d2 From 42c8b11e284fe3186e27555d1adb7d4b77398e1b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 9 Jul 2011 02:56:56 -0700 Subject: benet: Add missing comma between constant string array Multiple quoted strings are concatenated without comma separators. Make the arrays const while there. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 696f634b7e3..4ebd7000b0c 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -44,7 +44,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { }; MODULE_DEVICE_TABLE(pci, be_dev_ids); /* UE Status Low CSR */ -static char *ue_status_low_desc[] = { +static const char * const ue_status_low_desc[] = { "CEV", "CTX", "DBUF", @@ -79,7 +79,7 @@ static char *ue_status_low_desc[] = { "MPU_INTPEND" }; /* UE Status High CSR */ -static char *ue_status_hi_desc[] = { +static const char * const ue_status_hi_desc[] = { "LPCMEMHOST", "MGMT_MAC", "PCS0ONLINE", @@ -103,7 +103,7 @@ static char *ue_status_hi_desc[] = { "HOST7", "HOST8", "HOST9", - "NETC" + "NETC", "Unknown", "Unknown", "Unknown", -- cgit v1.2.3-70-g09d2 From afaf6b5742f85bab46232faae97fdd1493061173 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 8 Jul 2011 08:46:09 -0700 Subject: iwlagn: remove the CMD_MAPPED flag It is uneeded since Johannes removed the HUGE flag. The DMA mapping is always held in the same index as the command. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-tx.c | 16 ++++------------ 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f4501f83615..e429e32f748 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -263,7 +263,6 @@ enum { CMD_NO_SKB = 0, CMD_ASYNC = (1 << 1), CMD_WANT_SKB = (1 << 2), - CMD_MAPPED = (1 << 3), }; #define DEF_CMD_PAYLOAD_SIZE 320 diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index db5abaa2ff7..dc8f63f81cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -291,11 +291,9 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) while (q->read_ptr != q->write_ptr) { i = get_cmd_index(q, q->read_ptr); - if (txq->meta[i].flags & CMD_MAPPED) { - iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i], - DMA_BIDIRECTIONAL); - txq->meta[i].flags = 0; - } + iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i], + DMA_BIDIRECTIONAL); + txq->meta[i].flags = 0; q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } @@ -496,11 +494,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) out_cmd = txq->cmd[idx]; out_meta = &txq->meta[idx]; - if (WARN_ON(out_meta->flags & CMD_MAPPED)) { - spin_unlock_irqrestore(&priv->hcmd_lock, flags); - return -ENOSPC; - } - memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ if (cmd->flags & CMD_WANT_SKB) out_meta->source = cmd; @@ -574,7 +567,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) #endif } - out_meta->flags = cmd->flags | CMD_MAPPED; + out_meta->flags = cmd->flags; txq->need_update = 1; @@ -684,7 +677,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) wake_up_interruptible(&priv->wait_command_queue); } - /* Mark as unmapped */ meta->flags = 0; spin_unlock_irqrestore(&priv->hcmd_lock, flags); -- cgit v1.2.3-70-g09d2 From 1359ca4f305a1680ea6a1347a43bea76c352097c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 8 Jul 2011 08:46:10 -0700 Subject: iwlagn: add an API to free the TX context Tx free functions move to the transport layer. Unify the functions that deal with tx queues and cmd queue. Since the CMD queue is not fully allocated, but uses the q->n_bd / q->window trick, the release flow of TX queue and CMD queue was different. iwlagn_txq_free_tfd receives now the index of the TFD to be freed, which allows to unify the release flow for all the queues. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 32 +-------- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 4 +- drivers/net/wireless/iwlwifi/iwl-core.c | 6 -- drivers/net/wireless/iwlwifi/iwl-core.h | 5 -- drivers/net/wireless/iwlwifi/iwl-dev.h | 3 + drivers/net/wireless/iwlwifi/iwl-trans.c | 83 ++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-tx.c | 108 ++---------------------------- 8 files changed, 95 insertions(+), 148 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a87e95728b1..c90c78a081d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -851,31 +851,6 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, memset(ptr, 0, sizeof(*ptr)); } -/** - * iwlagn_hw_txq_ctx_free - Free TXQ Context - * - * Destroy all TX DMA queues and structures - */ -void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv) -{ - int txq_id; - - /* Tx queues */ - if (priv->txq) { - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - if (txq_id == priv->cmd_queue) - iwl_cmd_queue_free(priv); - else - iwl_tx_queue_free(priv, txq_id); - } - iwlagn_free_dma_ptr(priv, &priv->kw); - - iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls); - - /* free tx queue structure */ - iwl_free_txq_mem(priv); -} - /** * iwlagn_txq_ctx_stop - Stop all Tx DMA channels */ @@ -906,10 +881,7 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv) /* Unmap DMA from host system and free skb's */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - if (txq_id == priv->cmd_queue) - iwl_cmd_queue_unmap(priv); - else - iwl_tx_queue_unmap(priv, txq_id); + iwl_tx_queue_unmap(priv, txq_id); } /* @@ -1170,7 +1142,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) iwlagn_txq_inval_byte_cnt_tbl(priv, txq); - iwlagn_txq_free_tfd(priv, txq); + iwlagn_txq_free_tfd(priv, txq, txq->q.read_ptr); } return nfreed; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7e6c463abbd..4d5b7cc3394 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3710,7 +3710,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_dealloc_ucode(priv); priv->trans.ops->rx_free(priv); - iwlagn_hw_txq_ctx_free(priv); + priv->trans.ops->tx_free(priv); iwl_eeprom_free(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 4351151e2a9..fabab0ff557 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -198,7 +198,8 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); void iwl_setup_rx_handlers(struct iwl_priv *priv); /* tx */ -void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); +void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int index); int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, dma_addr_t addr, u16 len, u8 reset); @@ -217,7 +218,6 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); -void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv); void iwlagn_txq_ctx_stop(struct iwl_priv *priv); static inline u32 iwl_tx_status_to_mac80211(u32 status) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f91e306c249..9bf46864f0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1370,12 +1370,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, } -void iwl_free_txq_mem(struct iwl_priv *priv) -{ - kfree(priv->txq); - priv->txq = NULL; -} - #ifdef CONFIG_IWLWIFI_DEBUGFS #define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6c21de9f5b6..7d8be6b26ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -328,8 +328,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p); -void iwl_free_txq_mem(struct iwl_priv *priv); - #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_alloc_traffic_mem(struct iwl_priv *priv); void iwl_free_traffic_mem(struct iwl_priv *priv); @@ -371,8 +369,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, /***************************************************** * RX ******************************************************/ -void iwl_cmd_queue_free(struct iwl_priv *priv); -void iwl_cmd_queue_unmap(struct iwl_priv *priv); void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q); int iwl_rx_queue_space(const struct iwl_rx_queue *q); @@ -386,7 +382,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); * TX ******************************************************/ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); -void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, int count, int slots_num, u32 id); void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e429e32f748..a29fdd43a9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1233,11 +1233,14 @@ struct iwl_trans; * @rx_init: inits the rx memory, allocate it if needed * @rx_free: frees the rx memory * @tx_init:inits the tx memory, allocate if needed + * @tx_free: frees the tx memory */ struct iwl_trans_ops { int (*rx_init)(struct iwl_priv *priv); void (*rx_free)(struct iwl_priv *priv); + int (*tx_init)(struct iwl_priv *priv); + void (*tx_free)(struct iwl_priv *priv); }; struct iwl_trans { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 7b7b97d8c2e..38b43e41d56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -203,6 +203,16 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, return 0; } +static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, + struct iwl_dma_ptr *ptr) +{ + if (unlikely(!ptr->addr)) + return; + + dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma); + memset(ptr, 0, sizeof(*ptr)); +} + static int iwl_trans_txq_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id) { @@ -212,6 +222,8 @@ static int iwl_trans_txq_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq, if (WARN_ON(txq->meta || txq->cmd || txq->txb || txq->tfds)) return -EINVAL; + txq->q.n_window = slots_num; + txq->meta = kzalloc(sizeof(txq->meta[0]) * slots_num, GFP_KERNEL); txq->cmd = kzalloc(sizeof(txq->cmd[0]) * slots_num, @@ -306,6 +318,72 @@ static int iwl_trans_txq_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, return 0; } +/** + * iwl_tx_queue_free - Deallocate DMA queue. + * @txq: Transmit queue to deallocate. + * + * Empty queue by removing and destroying all BD's. + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. + */ +static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct device *dev = priv->bus.dev; + int i; + if (WARN_ON(!txq)) + return; + + iwl_tx_queue_unmap(priv, txq_id); + + /* De-alloc array of command/tx buffers */ + for (i = 0; i < txq->q.n_window; i++) + kfree(txq->cmd[i]); + + /* De-alloc circular buffer of TFDs */ + if (txq->q.n_bd) { + dma_free_coherent(dev, priv->hw_params.tfd_size * + txq->q.n_bd, txq->tfds, txq->q.dma_addr); + memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr)); + } + + /* De-alloc array of per-TFD driver data */ + kfree(txq->txb); + txq->txb = NULL; + + /* deallocate arrays */ + kfree(txq->cmd); + kfree(txq->meta); + txq->cmd = NULL; + txq->meta = NULL; + + /* 0-fill queue descriptor structure */ + memset(txq, 0, sizeof(*txq)); +} + +/** + * iwl_trans_tx_free - Free TXQ Context + * + * Destroy all TX DMA queues and structures + */ +static void iwl_trans_tx_free(struct iwl_priv *priv) +{ + int txq_id; + + /* Tx queues */ + if (priv->txq) { + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) + iwl_tx_queue_free(priv, txq_id); + } + + kfree(priv->txq); + priv->txq = NULL; + + iwlagn_free_dma_ptr(priv, &priv->kw); + + iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls); +} + /** * iwl_trans_tx_alloc - allocate TX context * Allocate all Tx DMA structures and initialize them @@ -362,7 +440,7 @@ static int iwl_trans_tx_alloc(struct iwl_priv *priv) return 0; error: - iwlagn_hw_txq_ctx_free(priv); + priv->trans.ops->tx_free(priv); return ret; } @@ -406,7 +484,7 @@ static int iwl_trans_tx_init(struct iwl_priv *priv) error: /*Upon error, free only if we allocated something */ if (alloc) - iwlagn_hw_txq_ctx_free(priv); + priv->trans.ops->tx_free(priv); return ret; } @@ -415,6 +493,7 @@ static const struct iwl_trans_ops trans_ops = { .rx_free = iwl_trans_rx_free, .tx_init = iwl_trans_tx_init, + .tx_free = iwl_trans_tx_free, }; void iwl_trans_register(struct iwl_trans *trans) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index dc8f63f81cf..36b643a385b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -157,14 +157,15 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * @priv - driver private data * @txq - tx queue + * @index - the index of the TFD to be freed * * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ -void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int index) { struct iwl_tfd *tfd_tmp = txq->tfds; - int index = txq->q.read_ptr; iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index], DMA_TO_DEVICE); @@ -173,12 +174,12 @@ void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) if (txq->txb) { struct sk_buff *skb; - skb = txq->txb[txq->q.read_ptr].skb; + skb = txq->txb[index].skb; /* can be called from irqs-disabled context */ if (skb) { dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; + txq->txb[index].skb = NULL; } } } @@ -232,108 +233,11 @@ void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) return; while (q->write_ptr != q->read_ptr) { - iwlagn_txq_free_tfd(priv, txq); + iwlagn_txq_free_tfd(priv, txq, get_cmd_index(q, q->read_ptr)); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } } -/** - * iwl_tx_queue_free - Deallocate DMA queue. - * @txq: Transmit queue to deallocate. - * - * Empty queue by removing and destroying all BD's. - * Free all buffers. - * 0-fill, but do not free "txq" descriptor structure. - */ -void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) -{ - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct device *dev = priv->bus.dev; - int i; - - iwl_tx_queue_unmap(priv, txq_id); - - /* De-alloc array of command/tx buffers */ - for (i = 0; i < TFD_TX_CMD_SLOTS; i++) - kfree(txq->cmd[i]); - - /* De-alloc circular buffer of TFDs */ - if (txq->q.n_bd) - dma_free_coherent(dev, priv->hw_params.tfd_size * - txq->q.n_bd, txq->tfds, txq->q.dma_addr); - - /* De-alloc array of per-TFD driver data */ - kfree(txq->txb); - txq->txb = NULL; - - /* deallocate arrays */ - kfree(txq->cmd); - kfree(txq->meta); - txq->cmd = NULL; - txq->meta = NULL; - - /* 0-fill queue descriptor structure */ - memset(txq, 0, sizeof(*txq)); -} - -/** - * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue - */ -void iwl_cmd_queue_unmap(struct iwl_priv *priv) -{ - struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; - struct iwl_queue *q = &txq->q; - int i; - - if (q->n_bd == 0) - return; - - while (q->read_ptr != q->write_ptr) { - i = get_cmd_index(q, q->read_ptr); - - iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i], - DMA_BIDIRECTIONAL); - txq->meta[i].flags = 0; - - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); - } -} - -/** - * iwl_cmd_queue_free - Deallocate DMA queue. - * @txq: Transmit queue to deallocate. - * - * Empty queue by removing and destroying all BD's. - * Free all buffers. - * 0-fill, but do not free "txq" descriptor structure. - */ -void iwl_cmd_queue_free(struct iwl_priv *priv) -{ - struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; - struct device *dev = priv->bus.dev; - int i; - - iwl_cmd_queue_unmap(priv); - - /* De-alloc array of command/tx buffers */ - for (i = 0; i < TFD_CMD_SLOTS; i++) - kfree(txq->cmd[i]); - - /* De-alloc circular buffer of TFDs */ - if (txq->q.n_bd) - dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd, - txq->tfds, txq->q.dma_addr); - - /* deallocate arrays */ - kfree(txq->cmd); - kfree(txq->meta); - txq->cmd = NULL; - txq->meta = NULL; - - /* 0-fill queue descriptor structure */ - memset(txq, 0, sizeof(*txq)); -} - /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** * DMA services * -- cgit v1.2.3-70-g09d2 From c2c52e8bed1a186d060166ec57228e2a123cab2e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 8 Jul 2011 08:46:11 -0700 Subject: iwlagn: add an API for RX stop Rx stop moves to transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 24 +++++++----------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans.c | 10 ++++++++++ 4 files changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 90d366e15d2..25a592a656a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -905,17 +905,6 @@ void iwlagn_rx_replenish_now(struct iwl_priv *priv) iwlagn_rx_queue_restock(priv); } -int iwlagn_rxq_stop(struct iwl_priv *priv) -{ - - /* stop Rx DMA */ - iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG, - FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); - - return 0; -} - int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) { int idx = 0; @@ -2321,13 +2310,14 @@ void iwlagn_stop_device(struct iwl_priv *priv) * already dead. */ if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) { - iwlagn_txq_ctx_stop(priv); - iwlagn_rxq_stop(priv); + iwlagn_txq_ctx_stop(priv); + priv->trans.ops->rx_stop(priv); - /* Power-down device's busmaster DMA clocks */ - iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); - udelay(5); - } + /* Power-down device's busmaster DMA clocks */ + iwl_write_prph(priv, APMG_CLK_DIS_REG, + APMG_CLK_VAL_DMA_CLK_RQT); + udelay(5); + } /* Make sure (redundant) we've released our request to stay awake */ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index fabab0ff557..0fa379b4f46 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -193,7 +193,6 @@ void iwlagn_rx_queue_restock(struct iwl_priv *priv); void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority); void iwlagn_rx_replenish(struct iwl_priv *priv); void iwlagn_rx_replenish_now(struct iwl_priv *priv); -int iwlagn_rxq_stop(struct iwl_priv *priv); int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); void iwl_setup_rx_handlers(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index a29fdd43a9f..8611cf0e555 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1231,12 +1231,14 @@ struct iwl_trans; * struct iwl_trans_ops - transport specific operations * @rx_init: inits the rx memory, allocate it if needed + * @rx_stop: stop the rx * @rx_free: frees the rx memory * @tx_init:inits the tx memory, allocate if needed * @tx_free: frees the tx memory */ struct iwl_trans_ops { int (*rx_init)(struct iwl_priv *priv); + int (*rx_stop)(struct iwl_priv *priv); void (*rx_free)(struct iwl_priv *priv); int (*tx_init)(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 38b43e41d56..c4cd363d81f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -188,6 +188,15 @@ static void iwl_trans_rx_free(struct iwl_priv *priv) rxq->rb_stts = NULL; } +static int iwl_trans_rx_stop(struct iwl_priv *priv) +{ + + /* stop Rx DMA */ + iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + return iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG, + FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); +} + /* TODO:remove this code duplication */ static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, struct iwl_dma_ptr *ptr, size_t size) @@ -490,6 +499,7 @@ error: static const struct iwl_trans_ops trans_ops = { .rx_init = iwl_trans_rx_init, + .rx_stop = iwl_trans_rx_stop, .rx_free = iwl_trans_rx_free, .tx_init = iwl_trans_tx_init, -- cgit v1.2.3-70-g09d2 From c170b867cc119fb9f6e9cac3a8245a3347bc718c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 8 Jul 2011 08:46:12 -0700 Subject: iwlagn: add an API for TX stop Tx stop moves to transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 33 ------------------ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +-- drivers/net/wireless/iwlwifi/iwl-trans.c | 56 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-tx.c | 17 --------- 7 files changed, 59 insertions(+), 55 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 25a592a656a..a926142f470 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2310,7 +2310,7 @@ void iwlagn_stop_device(struct iwl_priv *priv) * already dead. */ if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) { - iwlagn_txq_ctx_stop(priv); + priv->trans.ops->tx_stop(priv); priv->trans.ops->rx_stop(priv); /* Power-down device's busmaster DMA clocks */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c90c78a081d..f29b31d73be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -851,39 +851,6 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, memset(ptr, 0, sizeof(*ptr)); } -/** - * iwlagn_txq_ctx_stop - Stop all Tx DMA channels - */ -void iwlagn_txq_ctx_stop(struct iwl_priv *priv) -{ - int ch, txq_id; - unsigned long flags; - - /* Turn off all Tx DMA fifos */ - spin_lock_irqsave(&priv->lock, flags); - - iwlagn_txq_set_sched(priv, 0); - - /* Stop each Tx DMA channel, and wait for it to be idle */ - for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { - iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, - FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), - 1000)) - IWL_ERR(priv, "Failing on timeout while stopping" - " DMA channel %d [0x%08x]", ch, - iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG)); - } - spin_unlock_irqrestore(&priv->lock, flags); - - if (!priv->txq) - return; - - /* Unmap DMA from host system and free skb's */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - iwl_tx_queue_unmap(priv, txq_id); -} - /* * Find first available (lowest unused) Tx Queue, mark it "active". * Called only when finding queue for aggregation. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 0fa379b4f46..ff0b2ed7123 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -217,7 +217,6 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); -void iwlagn_txq_ctx_stop(struct iwl_priv *priv); static inline u32 iwl_tx_status_to_mac80211(u32 status) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7d8be6b26ac..76f65350ebc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -384,7 +384,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, int count, int slots_num, u32 id); -void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id); void iwl_setup_watchdog(struct iwl_priv *priv); /***************************************************** * TX power diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8611cf0e555..85e4fa35037 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -694,8 +694,6 @@ struct iwl_hw_params { ****************************************************************************/ extern void iwl_update_chain_flags(struct iwl_priv *priv); extern const u8 iwl_bcast_addr[ETH_ALEN]; -extern int iwl_rxq_stop(struct iwl_priv *priv); -extern void iwl_txq_ctx_stop(struct iwl_priv *priv); extern int iwl_queue_space(const struct iwl_queue *q); static inline int iwl_queue_used(const struct iwl_queue *q, int i) { @@ -1234,6 +1232,7 @@ struct iwl_trans; * @rx_stop: stop the rx * @rx_free: frees the rx memory * @tx_init:inits the tx memory, allocate if needed + * @tx_stop: stop the tx * @tx_free: frees the tx memory */ struct iwl_trans_ops { @@ -1242,6 +1241,7 @@ struct iwl_trans_ops { void (*rx_free)(struct iwl_priv *priv); int (*tx_init)(struct iwl_priv *priv); + int (*tx_stop)(struct iwl_priv *priv); void (*tx_free)(struct iwl_priv *priv); }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index c4cd363d81f..81716fdd593 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -327,6 +327,24 @@ static int iwl_trans_txq_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, return 0; } +/** + * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's + */ +static void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + + if (!q->n_bd) + return; + + while (q->write_ptr != q->read_ptr) { + /* The read_ptr needs to bound by q->n_window */ + iwlagn_txq_free_tfd(priv, txq, get_cmd_index(q, q->read_ptr)); + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); + } +} + /** * iwl_tx_queue_free - Deallocate DMA queue. * @txq: Transmit queue to deallocate. @@ -497,12 +515,50 @@ error: return ret; } +/** + * iwlagn_txq_ctx_stop - Stop all Tx DMA channels + */ +static int iwl_trans_tx_stop(struct iwl_priv *priv) +{ + int ch, txq_id; + unsigned long flags; + + /* Turn off all Tx DMA fifos */ + spin_lock_irqsave(&priv->lock, flags); + + iwlagn_txq_set_sched(priv, 0); + + /* Stop each Tx DMA channel, and wait for it to be idle */ + for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { + iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); + if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), + 1000)) + IWL_ERR(priv, "Failing on timeout while stopping" + " DMA channel %d [0x%08x]", ch, + iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG)); + } + spin_unlock_irqrestore(&priv->lock, flags); + + if (!priv->txq) { + IWL_WARN(priv, "Stopping tx queues that aren't allocated..."); + return 0; + } + + /* Unmap DMA from host system and free skb's */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) + iwl_tx_queue_unmap(priv, txq_id); + + return 0; +} + static const struct iwl_trans_ops trans_ops = { .rx_init = iwl_trans_rx_init, .rx_stop = iwl_trans_rx_stop, .rx_free = iwl_trans_rx_free, .tx_init = iwl_trans_tx_init, + .tx_stop = iwl_trans_tx_stop, .tx_free = iwl_trans_tx_free, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 36b643a385b..b62d03235b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -221,23 +221,6 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv, return 0; } -/** - * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's - */ -void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) -{ - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct iwl_queue *q = &txq->q; - - if (q->n_bd == 0) - return; - - while (q->write_ptr != q->read_ptr) { - iwlagn_txq_free_tfd(priv, txq, get_cmd_index(q, q->read_ptr)); - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); - } -} - /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** * DMA services * -- cgit v1.2.3-70-g09d2 From 06f491ef4b659fa6f6850f31d05a4a03db0d9d96 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 8 Jul 2011 08:46:13 -0700 Subject: iwlagn: remove code duplication Code duplication was needed during the move, not needed any more. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 21 --------------------- drivers/net/wireless/iwlwifi/iwl-trans.c | 1 - 2 files changed, 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index f29b31d73be..db3ec7aaf94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -830,27 +830,6 @@ drop_unlock_priv: return -1; } -static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, - struct iwl_dma_ptr *ptr, size_t size) -{ - ptr->addr = dma_alloc_coherent(priv->bus.dev, size, - &ptr->dma, GFP_KERNEL); - if (!ptr->addr) - return -ENOMEM; - ptr->size = size; - return 0; -} - -static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, - struct iwl_dma_ptr *ptr) -{ - if (unlikely(!ptr->addr)) - return; - - dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma); - memset(ptr, 0, sizeof(*ptr)); -} - /* * Find first available (lowest unused) Tx Queue, mark it "active". * Called only when finding queue for aggregation. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 81716fdd593..de627f9ae10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -197,7 +197,6 @@ static int iwl_trans_rx_stop(struct iwl_priv *priv) FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); } -/* TODO:remove this code duplication */ static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, struct iwl_dma_ptr *ptr, size_t size) { -- cgit v1.2.3-70-g09d2 From e419d62d72b23392e7f9a5da047fb17d70edc54a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 8 Jul 2011 08:46:14 -0700 Subject: iwlagn: consolidate the API that sends host commands and move to transport Now, there are only two functions to send a host command: * send_cmd that receives a iwl_host_cmd * send_cmd_pdu that builds the iwl_host_cmd itself and received flags The flags CMD_ASYNC / CMD_SYNC / CMD_WANT_SKB are not changed by the API functions. Kill the unused flags CMD_SIZE_NORMAL / CMD_NO_SKB on the way. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 7 +++--- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 16 ++++++++------ drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 17 ++++++++------- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 17 +++++++++------ drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 11 ++++++---- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 ++++++++++------ drivers/net/wireless/iwlwifi/iwl-core.c | 16 ++++++++------ drivers/net/wireless/iwlwifi/iwl-core.h | 9 +------- drivers/net/wireless/iwlwifi/iwl-dev.h | 23 ++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 32 +++++----------------------- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-sta.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-sv-open.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.c | 4 ++++ 19 files changed, 100 insertions(+), 92 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index c55cec853f5..82093344b9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -316,7 +316,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return iwl_send_cmd_sync(priv, &hcmd); + return priv->trans.ops->send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl5000_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 965d010794b..2134514a40d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -255,7 +255,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return iwl_send_cmd_sync(priv, &hcmd); + return priv->trans.ops->send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl6000_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index c9255def108..e7c74fcb55c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -87,6 +87,7 @@ int iwl_send_calib_results(struct iwl_priv *priv) struct iwl_host_cmd hcmd = { .id = REPLY_PHY_CALIBRATION_CMD, + .flags = CMD_SYNC, }; for (i = 0; i < IWL_CALIB_MAX; i++) { @@ -95,7 +96,7 @@ int iwl_send_calib_results(struct iwl_priv *priv) hcmd.len[0] = priv->calib_results[i].buf_len; hcmd.data[0] = priv->calib_results[i].buf; hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - ret = iwl_send_cmd_sync(priv, &hcmd); + ret = priv->trans.ops->send_cmd(priv, &hcmd); if (ret) { IWL_ERR(priv, "Error %d iteration %d\n", ret, i); @@ -481,7 +482,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), sizeof(u16)*HD_TABLE_SIZE); - return iwl_send_cmd(priv, &cmd_out); + return priv->trans.ops->send_cmd(priv, &cmd_out); } /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ @@ -545,7 +546,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); - return iwl_send_cmd(priv, &cmd_out); + return priv->trans.ops->send_cmd(priv, &cmd_out); } void iwl_init_sensitivity(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index ce7d4b56d9b..406bf59bd44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -45,7 +45,9 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) if (IWL_UCODE_API(priv->ucode_ver) > 1) { IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); - return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD, + return priv->trans.ops->send_cmd_pdu(priv, + TX_ANT_CONFIGURATION_CMD, + CMD_SYNC, sizeof(struct iwl_tx_ant_config_cmd), &tx_ant_cmd); } else { @@ -115,8 +117,8 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, priv->_agn.phy_calib_chain_noise_gain_cmd); cmd.delta_gain_1 = data->delta_gain_code[1]; cmd.delta_gain_2 = data->delta_gain_code[2]; - iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, - sizeof(cmd), &cmd, NULL); + priv->trans.ops->send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + CMD_ASYNC, sizeof(cmd), &cmd); data->radio_write = 1; data->state = IWL_CHAIN_NOISE_CALIBRATED; @@ -144,8 +146,9 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, priv->_agn.phy_calib_chain_noise_reset_cmd); - ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, - sizeof(cmd), &cmd); + ret = priv->trans.ops->send_cmd_pdu(priv, + REPLY_PHY_CALIBRATION_CMD, + CMD_SYNC, sizeof(cmd), &cmd); if (ret) IWL_ERR(priv, "Could not send REPLY_PHY_CALIBRATION_CMD\n"); @@ -290,7 +293,8 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) cmd.slots[0].width = cpu_to_le16(slot0); cmd.slots[1].width = cpu_to_le16(slot1); - ret = iwl_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, sizeof(cmd), &cmd); + ret = priv->trans.ops->send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC, + sizeof(cmd), &cmd); if (ret) IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a926142f470..39664c9bbff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -540,8 +540,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) else tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; - return iwl_send_cmd_pdu(priv, tx_ant_cfg_cmd, sizeof(tx_power_cmd), - &tx_power_cmd); + return priv->trans.ops->send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC, + sizeof(tx_power_cmd), &tx_power_cmd); } void iwlagn_temperature(struct iwl_priv *priv) @@ -1063,6 +1063,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) struct iwl_host_cmd cmd = { .id = REPLY_SCAN_CMD, .len = { sizeof(struct iwl_scan_cmd), }, + .flags = CMD_SYNC, }; struct iwl_scan_cmd *scan; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; @@ -1359,7 +1360,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (ret) return ret; - ret = iwl_send_cmd_sync(priv, &cmd); + ret = priv->trans.ops->send_cmd(priv, &cmd); if (ret) { clear_bit(STATUS_SCAN_HW, &priv->status); iwlagn_set_pan_params(priv); @@ -1465,7 +1466,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) flush_cmd.fifo_control); flush_cmd.flush_control = cpu_to_le16(flush_control); - return iwl_send_cmd(priv, &cmd); + return priv->trans.ops->send_cmd(priv, &cmd); } void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) @@ -1657,13 +1658,13 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) if (priv->cfg->bt_params->bt_session_2) { memcpy(&bt_cmd_2000.basic, &basic, sizeof(basic)); - ret = iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, - sizeof(bt_cmd_2000), &bt_cmd_2000); + ret = priv->trans.ops->send_cmd_pdu(priv, REPLY_BT_CONFIG, + CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); } else { memcpy(&bt_cmd_6000.basic, &basic, sizeof(basic)); - ret = iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, - sizeof(bt_cmd_6000), &bt_cmd_6000); + ret = priv->trans.ops->send_cmd_pdu(priv, REPLY_BT_CONFIG, + CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); } if (ret) IWL_ERR(priv, "failed to send BT Coex Config\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index c6bb73a66d9..c365295cc59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -39,7 +39,8 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); + ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, + CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -64,7 +65,8 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; send->dev_type = RXON_DEV_TYPE_P2P; - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); + ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, + CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; send->dev_type = old_dev_type; @@ -89,7 +91,8 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); + ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, + sizeof(*send), send); send->filter_flags = old_filter; @@ -117,7 +120,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags); - ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, + ret = priv->trans.ops->send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, sizeof(struct iwl_qosparam_cmd), &ctx->qos_data.def_qos_parm); if (ret) @@ -176,8 +179,8 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, ctx->staging.ofdm_ht_triple_stream_basic_rates; rxon_assoc.acquisition_data = ctx->staging.acquisition_data; - ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, - sizeof(rxon_assoc), &rxon_assoc, NULL); + ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_assoc_cmd, + CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); return ret; } @@ -262,7 +265,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, * Associated RXON doesn't clear the station table in uCode, * so we don't need to restore stations etc. after this. */ - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 9b32f83f0b7..b0e54c915c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -180,7 +180,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, cmd.len[0] = cmd_size; if (not_empty || send_if_empty) - return iwl_send_cmd(priv, &cmd); + return priv->trans.ops->send_cmd(priv, &cmd); else return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 2043c8b3139..1976582df24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -223,7 +223,7 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv) calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL; calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL; - return iwl_send_cmd(priv, &cmd); + return priv->trans.ops->send_cmd(priv, &cmd); } void iwlagn_rx_calib_result(struct iwl_priv *priv, @@ -321,7 +321,8 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv) /* coexistence is disabled */ memset(&coex_cmd, 0, sizeof(coex_cmd)); } - return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD, + return priv->trans.ops->send_cmd_pdu(priv, + COEX_PRIORITY_TABLE_CMD, CMD_SYNC, sizeof(coex_cmd), &coex_cmd); } @@ -353,7 +354,8 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv) memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl, sizeof(iwlagn_bt_prio_tbl)); - if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE, + if (priv->trans.ops->send_cmd_pdu(priv, + REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, sizeof(prio_tbl_cmd), &prio_tbl_cmd)) IWL_ERR(priv, "failed to send BT prio tbl command\n"); } @@ -365,7 +367,8 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) env_cmd.action = action; env_cmd.type = type; - ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, + ret = priv->trans.ops->send_cmd_pdu(priv, + REPLY_BT_COEX_PROT_ENV, CMD_SYNC, sizeof(env_cmd), &env_cmd); if (ret) IWL_ERR(priv, "failed to send BT env command\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4d5b7cc3394..d56d17c59de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -129,6 +129,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) struct iwl_tx_beacon_cmd *tx_beacon_cmd; struct iwl_host_cmd cmd = { .id = REPLY_TX_BEACON, + .flags = CMD_SYNC, }; struct ieee80211_tx_info *info; u32 frame_size; @@ -205,7 +206,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) cmd.data[1] = priv->beacon_skb->data; cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; - return iwl_send_cmd_sync(priv, &cmd); + return priv->trans.ops->send_cmd(priv, &cmd); } static void iwl_bg_beacon_update(struct work_struct *work) @@ -578,7 +579,8 @@ static void iwl_rx_handle(struct iwl_priv *priv) if (reclaim) { /* Invoke any callbacks, transfer the buffer to caller, - * and fire off the (possibly) blocking iwl_send_cmd() + * and fire off the (possibly) blocking + * priv->trans.ops->send_cmd() * as we reclaim the driver command queue */ if (rxb->page) iwl_tx_cmd_complete(priv, rxb); @@ -1940,8 +1942,9 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) adv_cmd.critical_temperature_exit = cpu_to_le32(priv->hw_params.ct_kill_exit_threshold); - ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, - sizeof(adv_cmd), &adv_cmd); + ret = priv->trans.ops->send_cmd_pdu(priv, + REPLY_CT_KILL_CONFIG_CMD, + CMD_SYNC, sizeof(adv_cmd), &adv_cmd); if (ret) IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); else @@ -1955,8 +1958,9 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) cmd.critical_temperature_R = cpu_to_le32(priv->hw_params.ct_kill_threshold); - ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, - sizeof(cmd), &cmd); + ret = priv->trans.ops->send_cmd_pdu(priv, + REPLY_CT_KILL_CONFIG_CMD, + CMD_SYNC, sizeof(cmd), &cmd); if (ret) IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); else @@ -1980,7 +1984,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); - return iwl_send_cmd(priv, &cmd); + return priv->trans.ops->send_cmd(priv, &cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 9bf46864f0d..78e031e2548 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -375,8 +375,8 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) le32_to_cpu(ctx->timing.beacon_init_val), le16_to_cpu(ctx->timing.atim_window)); - return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd, - sizeof(ctx->timing), &ctx->timing); + return priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_timing_cmd, + CMD_SYNC, sizeof(ctx->timing), &ctx->timing); } void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -1131,8 +1131,8 @@ void iwl_send_bt_config(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "BT coex %s\n", (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); - if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, - sizeof(struct iwl_bt_cmd), &bt_cmd)) + if (priv->trans.ops->send_cmd_pdu(priv, REPLY_BT_CONFIG, + CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); } @@ -1144,11 +1144,13 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) }; if (flags & CMD_ASYNC) - return iwl_send_cmd_pdu_async(priv, REPLY_STATISTICS_CMD, + return priv->trans.ops->send_cmd_pdu(priv, REPLY_STATISTICS_CMD, + CMD_ASYNC, sizeof(struct iwl_statistics_cmd), - &statistics_cmd, NULL); + &statistics_cmd); else - return iwl_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, + return priv->trans.ops->send_cmd_pdu(priv, REPLY_STATISTICS_CMD, + CMD_SYNC, sizeof(struct iwl_statistics_cmd), &statistics_cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 76f65350ebc..3f7b921922a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -434,16 +434,9 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, *****************************************************/ const char *get_cmd_string(u8 cmd); -int __must_check iwl_send_cmd_sync(struct iwl_priv *priv, - struct iwl_host_cmd *cmd); int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); -int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, +int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags, u16 len, const void *data); -int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, - const void *data, - void (*callback)(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt)); int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 85e4fa35037..975ad79a5f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -259,10 +259,8 @@ struct iwl_channel_info { enum { CMD_SYNC = 0, - CMD_SIZE_NORMAL = 0, - CMD_NO_SKB = 0, - CMD_ASYNC = (1 << 1), - CMD_WANT_SKB = (1 << 2), + CMD_ASYNC = BIT(0), + CMD_WANT_SKB = BIT(1), }; #define DEF_CMD_PAYLOAD_SIZE 320 @@ -295,6 +293,16 @@ enum iwl_hcmd_dataflag { IWL_HCMD_DFL_NOCOPY = BIT(0), }; +/** + * struct iwl_host_cmd - Host command to the uCode + * @data: array of chunks that composes the data of the host command + * @reply_page: pointer to the page that holds the response to the host command + * @callback: + * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC + * @len: array of the lenths of the chunks in data + * @dataflags: + * @id: id of the host command + */ struct iwl_host_cmd { const void *data[IWL_MAX_CMD_TFDS]; unsigned long reply_page; @@ -1234,6 +1242,8 @@ struct iwl_trans; * @tx_init:inits the tx memory, allocate if needed * @tx_stop: stop the tx * @tx_free: frees the tx memory + * @send_cmd:send a host command + * @send_cmd_pdu:send a host command: flags can be CMD_* */ struct iwl_trans_ops { int (*rx_init)(struct iwl_priv *priv); @@ -1243,6 +1253,11 @@ struct iwl_trans_ops { int (*tx_init)(struct iwl_priv *priv); int (*tx_stop)(struct iwl_priv *priv); void (*tx_free)(struct iwl_priv *priv); + + int (*send_cmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd); + + int (*send_cmd_pdu)(struct iwl_priv *priv, u8 id, u32 flags, u16 len, + const void *data); }; struct iwl_trans { diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 107b38e2ee9..6cff8c165ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -143,9 +143,6 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { int ret; - if (WARN_ON(!(cmd->flags & CMD_ASYNC))) - return -EINVAL; - /* An asynchronous command can not expect an SKB to be set. */ if (WARN_ON(cmd->flags & CMD_WANT_SKB)) return -EINVAL; @@ -166,16 +163,13 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return 0; } -int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +static int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { int cmd_idx; int ret; lockdep_assert_held(&priv->mutex); - if (WARN_ON(cmd->flags & CMD_ASYNC)) - return -EINVAL; - /* A synchronous command can not have a callback set. */ if (WARN_ON(cmd->callback)) return -EINVAL; @@ -263,31 +257,15 @@ int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return iwl_send_cmd_sync(priv, cmd); } -int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) -{ - struct iwl_host_cmd cmd = { - .id = id, - .len = { len, }, - .data = { data, }, - }; - - return iwl_send_cmd_sync(priv, &cmd); -} - -int iwl_send_cmd_pdu_async(struct iwl_priv *priv, - u8 id, u16 len, const void *data, - void (*callback)(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt)) +int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags, u16 len, + const void *data) { struct iwl_host_cmd cmd = { .id = id, .len = { len, }, .data = { data, }, + .flags = flags, }; - cmd.flags |= CMD_ASYNC; - cmd.callback = callback; - - return iwl_send_cmd_async(priv, &cmd); + return iwl_send_cmd(priv, &cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index ff08da09975..d5bc3e09a92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -111,7 +111,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); - return iwl_send_cmd(priv, &cmd); + return priv->trans.ops->send_cmd(priv, &cmd); } /* Set led pattern command */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 565e57e48be..0c08dfd40dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -334,7 +334,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) le32_to_cpu(cmd->sleep_interval[3]), le32_to_cpu(cmd->sleep_interval[4])); - return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, + return priv->trans.ops->send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, sizeof(struct iwl_powertable_cmd), cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 438eecd8733..4c809bf9aac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -61,7 +61,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) struct iwl_rx_packet *pkt; struct iwl_host_cmd cmd = { .id = REPLY_SCAN_ABORT_CMD, - .flags = CMD_WANT_SKB, + .flags = CMD_SYNC | CMD_WANT_SKB, }; /* Exit instantly with error when device is not ready @@ -74,7 +74,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EIO; - ret = iwl_send_cmd_sync(priv, &cmd); + ret = priv->trans.ops->send_cmd(priv, &cmd); if (ret) return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7df2814fd4f..06faa1e2237 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -156,7 +156,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, } cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); - ret = iwl_send_cmd(priv, &cmd); + ret = priv->trans.ops->send_cmd(priv, &cmd); if (ret || (flags & CMD_ASYNC)) return ret; @@ -412,7 +412,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, cmd.flags |= CMD_WANT_SKB; - ret = iwl_send_cmd(priv, &cmd); + ret = priv->trans.ops->send_cmd(priv, &cmd); if (ret) return ret; @@ -781,7 +781,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return -EINVAL; if (is_lq_table_valid(priv, ctx, lq)) - ret = iwl_send_cmd(priv, &cmd); + ret = priv->trans.ops->send_cmd(priv, &cmd); else ret = -EINVAL; diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index c00aa5a1b8b..6f92d22d07e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -239,7 +239,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," " len %d\n", cmd.id, cmd.flags, cmd.len[0]); /* ok, let's submit the command to ucode */ - return iwl_send_cmd(priv, &cmd); + return priv->trans.ops->send_cmd(priv, &cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index de627f9ae10..5c5a489a21f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -66,6 +66,7 @@ #include "iwl-helpers.h" /*TODO remove uneeded includes when the transport layer tx_free will be here */ #include "iwl-agn.h" +#include "iwl-core.h" static int iwl_trans_rx_alloc(struct iwl_priv *priv) { @@ -559,6 +560,9 @@ static const struct iwl_trans_ops trans_ops = { .tx_init = iwl_trans_tx_init, .tx_stop = iwl_trans_tx_stop, .tx_free = iwl_trans_tx_free, + + .send_cmd = iwl_send_cmd, + .send_cmd_pdu = iwl_send_cmd_pdu, }; void iwl_trans_register(struct iwl_trans *trans) -- cgit v1.2.3-70-g09d2 From 02f6f659b0080e60021aae3503163576f88c5ba8 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:15 -0700 Subject: iwlagn: remove the indirection for the dma channel num Not needed since the driver split. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 -- drivers/net/wireless/iwlwifi/iwl-fh.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.c | 2 +- 8 files changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index cf1449df4f0..9cc161df3f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -125,7 +125,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index a401113c065..0c3245061f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -123,7 +123,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 82093344b9b..0c5105f24ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -156,7 +156,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); @@ -200,7 +199,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 2134514a40d..ced3bbea643 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -144,7 +144,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 1976582df24..d31b82626a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -406,7 +406,7 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) priv->scd_bc_tbls.dma >> 10); /* Enable DMA channel */ - for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++) + for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 975ad79a5f7..92f8ce9d5a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -640,7 +640,6 @@ struct iwl_sensitivity_ranges { /** * struct iwl_hw_params * @max_txq_num: Max # Tx queues supported - * @dma_chnl_num: Number of Tx DMA/FIFO channels * @scd_bc_tbls_size: size of scheduler byte count tables * @tfd_size: TFD size * @tx/rx_chains_num: Number of TX/RX chains @@ -662,7 +661,6 @@ struct iwl_sensitivity_ranges { */ struct iwl_hw_params { u8 max_txq_num; - u8 dma_chnl_num; u16 scd_bc_tbls_size; u32 tfd_size; u8 tx_chains_num; diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 6dfa806aefe..0ad60b3c04d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -326,7 +326,7 @@ #define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60) /* Find Control/Status reg for given Tx DMA/FIFO channel */ -#define FH50_TCSR_CHNL_NUM (8) +#define FH_TCSR_CHNL_NUM (8) /* TCSR: tx_config register values */ #define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 5c5a489a21f..0c924569636 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -529,7 +529,7 @@ static int iwl_trans_tx_stop(struct iwl_priv *priv) iwlagn_txq_set_sched(priv, 0); /* Stop each Tx DMA channel, and wait for it to be idle */ - for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { + for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), -- cgit v1.2.3-70-g09d2 From bdfbf0924ab05e02d28e50bd2d5024097642a78d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 8 Jul 2011 08:46:16 -0700 Subject: iwlagn: provide heplers to access the transport ops This removes the for priv->trans.ops->... Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-5000.c | 3 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 7 +++-- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 9 +++--- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 19 +++++++------ drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 13 +++++---- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 9 +++--- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 +++++----- drivers/net/wireless/iwlwifi/iwl-core.c | 9 +++--- drivers/net/wireless/iwlwifi/iwl-led.c | 3 +- drivers/net/wireless/iwlwifi/iwl-power.c | 3 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 3 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 7 +++-- drivers/net/wireless/iwlwifi/iwl-sv-open.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-trans.c | 4 +-- drivers/net/wireless/iwlwifi/iwl-trans.h | 41 ++++++++++++++++++++++++++++ 17 files changed, 104 insertions(+), 50 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 0c5105f24ee..835ed7a295e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -46,6 +46,7 @@ #include "iwl-agn.h" #include "iwl-agn-hw.h" #include "iwl-5000-hw.h" +#include "iwl-trans.h" /* Highest firmware API version supported */ #define IWL5000_UCODE_API_MAX 5 @@ -314,7 +315,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return priv->trans.ops->send_cmd(priv, &hcmd); + return trans_send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl5000_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ced3bbea643..f03448f40f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -45,6 +45,7 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-6000-hw.h" +#include "iwl-trans.h" /* Highest firmware API version supported */ #define IWL6000_UCODE_API_MAX 4 @@ -254,7 +255,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return priv->trans.ops->send_cmd(priv, &hcmd); + return trans_send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl6000_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index e7c74fcb55c..2ec3863306b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -66,6 +66,7 @@ #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-agn-calib.h" +#include "iwl-trans.h" /***************************************************************************** * INIT calibrations framework @@ -96,7 +97,7 @@ int iwl_send_calib_results(struct iwl_priv *priv) hcmd.len[0] = priv->calib_results[i].buf_len; hcmd.data[0] = priv->calib_results[i].buf; hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - ret = priv->trans.ops->send_cmd(priv, &hcmd); + ret = trans_send_cmd(priv, &hcmd); if (ret) { IWL_ERR(priv, "Error %d iteration %d\n", ret, i); @@ -482,7 +483,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), sizeof(u16)*HD_TABLE_SIZE); - return priv->trans.ops->send_cmd(priv, &cmd_out); + return trans_send_cmd(priv, &cmd_out); } /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ @@ -546,7 +547,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); - return priv->trans.ops->send_cmd(priv, &cmd_out); + return trans_send_cmd(priv, &cmd_out); } void iwl_init_sensitivity(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 406bf59bd44..4d7674c0c72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -36,6 +36,7 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-agn.h" +#include "iwl-trans.h" int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) { @@ -45,7 +46,7 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) if (IWL_UCODE_API(priv->ucode_ver) > 1) { IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); - return priv->trans.ops->send_cmd_pdu(priv, + return trans_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD, CMD_SYNC, sizeof(struct iwl_tx_ant_config_cmd), @@ -117,7 +118,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, priv->_agn.phy_calib_chain_noise_gain_cmd); cmd.delta_gain_1 = data->delta_gain_code[1]; cmd.delta_gain_2 = data->delta_gain_code[2]; - priv->trans.ops->send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + trans_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, CMD_ASYNC, sizeof(cmd), &cmd); data->radio_write = 1; @@ -146,7 +147,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, priv->_agn.phy_calib_chain_noise_reset_cmd); - ret = priv->trans.ops->send_cmd_pdu(priv, + ret = trans_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, CMD_SYNC, sizeof(cmd), &cmd); if (ret) @@ -293,7 +294,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) cmd.slots[0].width = cpu_to_le16(slot0); cmd.slots[1].width = cpu_to_le16(slot1); - ret = priv->trans.ops->send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC, + ret = trans_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC, sizeof(cmd), &cmd); if (ret) IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 39664c9bbff..cfe945c58fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -39,6 +39,7 @@ #include "iwl-agn-hw.h" #include "iwl-agn.h" #include "iwl-sta.h" +#include "iwl-trans.h" static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp) { @@ -540,7 +541,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) else tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; - return priv->trans.ops->send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC, + return trans_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC, sizeof(tx_power_cmd), &tx_power_cmd); } @@ -714,7 +715,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) priv->cfg->ops->lib->apm_ops.config(priv); /* Allocate the RX queue, or reset if it is already allocated */ - priv->trans.ops->rx_init(priv); + trans_rx_init(priv); iwlagn_rx_replenish(priv); @@ -728,7 +729,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); /* Allocate or reset and init all Tx and Command queues */ - if (priv->trans.ops->tx_init(priv)) + if (trans_tx_init(priv)) return -ENOMEM; if (priv->cfg->base_params->shadow_reg_enable) { @@ -1360,7 +1361,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (ret) return ret; - ret = priv->trans.ops->send_cmd(priv, &cmd); + ret = trans_send_cmd(priv, &cmd); if (ret) { clear_bit(STATUS_SCAN_HW, &priv->status); iwlagn_set_pan_params(priv); @@ -1466,7 +1467,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) flush_cmd.fifo_control); flush_cmd.flush_control = cpu_to_le16(flush_control); - return priv->trans.ops->send_cmd(priv, &cmd); + return trans_send_cmd(priv, &cmd); } void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) @@ -1658,12 +1659,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) if (priv->cfg->bt_params->bt_session_2) { memcpy(&bt_cmd_2000.basic, &basic, sizeof(basic)); - ret = priv->trans.ops->send_cmd_pdu(priv, REPLY_BT_CONFIG, + ret = trans_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); } else { memcpy(&bt_cmd_6000.basic, &basic, sizeof(basic)); - ret = priv->trans.ops->send_cmd_pdu(priv, REPLY_BT_CONFIG, + ret = trans_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); } if (ret) @@ -2311,8 +2312,8 @@ void iwlagn_stop_device(struct iwl_priv *priv) * already dead. */ if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) { - priv->trans.ops->tx_stop(priv); - priv->trans.ops->rx_stop(priv); + trans_tx_stop(priv); + trans_rx_stop(priv); /* Power-down device's busmaster DMA clocks */ iwl_write_prph(priv, APMG_CLK_DIS_REG, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index c365295cc59..d32cee1a758 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -30,6 +30,7 @@ #include "iwl-core.h" #include "iwl-agn-calib.h" #include "iwl-helpers.h" +#include "iwl-trans.h" static int iwlagn_disable_bss(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -39,7 +40,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, + ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -65,7 +66,7 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; send->dev_type = RXON_DEV_TYPE_P2P; - ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, + ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -91,7 +92,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, + ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -120,7 +121,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags); - ret = priv->trans.ops->send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, + ret = trans_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, sizeof(struct iwl_qosparam_cmd), &ctx->qos_data.def_qos_parm); if (ret) @@ -179,7 +180,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, ctx->staging.ofdm_ht_triple_stream_basic_rates; rxon_assoc.acquisition_data = ctx->staging.acquisition_data; - ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_assoc_cmd, + ret = trans_send_cmd_pdu(priv, ctx->rxon_assoc_cmd, CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); return ret; } @@ -265,7 +266,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, * Associated RXON doesn't clear the station table in uCode, * so we don't need to restore stations etc. after this. */ - ret = priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, + ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index b0e54c915c7..001622c0652 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -33,6 +33,7 @@ #include "iwl-core.h" #include "iwl-sta.h" #include "iwl-agn.h" +#include "iwl-trans.h" static struct iwl_link_quality_cmd * iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id) @@ -180,7 +181,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, cmd.len[0] = cmd_size; if (not_empty || send_if_empty) - return priv->trans.ops->send_cmd(priv, &cmd); + return trans_send_cmd(priv, &cmd); else return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index d31b82626a4..06304a681ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -39,6 +39,7 @@ #include "iwl-agn-hw.h" #include "iwl-agn.h" #include "iwl-agn-calib.h" +#include "iwl-trans.h" #define IWL_AC_UNSET -1 @@ -223,7 +224,7 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv) calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL; calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL; - return priv->trans.ops->send_cmd(priv, &cmd); + return trans_send_cmd(priv, &cmd); } void iwlagn_rx_calib_result(struct iwl_priv *priv, @@ -321,7 +322,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv) /* coexistence is disabled */ memset(&coex_cmd, 0, sizeof(coex_cmd)); } - return priv->trans.ops->send_cmd_pdu(priv, + return trans_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD, CMD_SYNC, sizeof(coex_cmd), &coex_cmd); } @@ -354,7 +355,7 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv) memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl, sizeof(iwlagn_bt_prio_tbl)); - if (priv->trans.ops->send_cmd_pdu(priv, + if (trans_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, sizeof(prio_tbl_cmd), &prio_tbl_cmd)) IWL_ERR(priv, "failed to send BT prio tbl command\n"); @@ -367,7 +368,7 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) env_cmd.action = action; env_cmd.type = type; - ret = priv->trans.ops->send_cmd_pdu(priv, + ret = trans_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, CMD_SYNC, sizeof(env_cmd), &env_cmd); if (ret) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d56d17c59de..3a4fca14fef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -206,7 +206,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) cmd.data[1] = priv->beacon_skb->data; cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; - return priv->trans.ops->send_cmd(priv, &cmd); + return trans_send_cmd(priv, &cmd); } static void iwl_bg_beacon_update(struct work_struct *work) @@ -580,7 +580,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) if (reclaim) { /* Invoke any callbacks, transfer the buffer to caller, * and fire off the (possibly) blocking - * priv->trans.ops->send_cmd() + * trans_send_cmd() * as we reclaim the driver command queue */ if (rxb->page) iwl_tx_cmd_complete(priv, rxb); @@ -1942,7 +1942,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) adv_cmd.critical_temperature_exit = cpu_to_le32(priv->hw_params.ct_kill_exit_threshold); - ret = priv->trans.ops->send_cmd_pdu(priv, + ret = trans_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, CMD_SYNC, sizeof(adv_cmd), &adv_cmd); if (ret) @@ -1958,7 +1958,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) cmd.critical_temperature_R = cpu_to_le32(priv->hw_params.ct_kill_threshold); - ret = priv->trans.ops->send_cmd_pdu(priv, + ret = trans_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, CMD_SYNC, sizeof(cmd), &cmd); if (ret) @@ -1984,7 +1984,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); - return priv->trans.ops->send_cmd(priv, &cmd); + return trans_send_cmd(priv, &cmd); } @@ -3713,8 +3713,8 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_dealloc_ucode(priv); - priv->trans.ops->rx_free(priv); - priv->trans.ops->tx_free(priv); + trans_rx_free(priv); + trans_tx_free(priv); iwl_eeprom_free(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 78e031e2548..fa3d5bacbde 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -42,6 +42,7 @@ #include "iwl-sta.h" #include "iwl-helpers.h" #include "iwl-agn.h" +#include "iwl-trans.h" u32 iwl_debug_level; @@ -375,7 +376,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) le32_to_cpu(ctx->timing.beacon_init_val), le16_to_cpu(ctx->timing.atim_window)); - return priv->trans.ops->send_cmd_pdu(priv, ctx->rxon_timing_cmd, + return trans_send_cmd_pdu(priv, ctx->rxon_timing_cmd, CMD_SYNC, sizeof(ctx->timing), &ctx->timing); } @@ -1131,7 +1132,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "BT coex %s\n", (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); - if (priv->trans.ops->send_cmd_pdu(priv, REPLY_BT_CONFIG, + if (trans_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); } @@ -1144,12 +1145,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) }; if (flags & CMD_ASYNC) - return priv->trans.ops->send_cmd_pdu(priv, REPLY_STATISTICS_CMD, + return trans_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, CMD_ASYNC, sizeof(struct iwl_statistics_cmd), &statistics_cmd); else - return priv->trans.ops->send_cmd_pdu(priv, REPLY_STATISTICS_CMD, + return trans_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, CMD_SYNC, sizeof(struct iwl_statistics_cmd), &statistics_cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index d5bc3e09a92..60e4169f25e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -40,6 +40,7 @@ #include "iwl-core.h" #include "iwl-agn.h" #include "iwl-io.h" +#include "iwl-trans.h" /* Throughput OFF time(ms) ON time (ms) * >300 25 25 @@ -111,7 +112,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); - return priv->trans.ops->send_cmd(priv, &cmd); + return trans_send_cmd(priv, &cmd); } /* Set led pattern command */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 0c08dfd40dd..9c10462c20f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -42,6 +42,7 @@ #include "iwl-commands.h" #include "iwl-debug.h" #include "iwl-power.h" +#include "iwl-trans.h" /* * Setting power level allows the card to go to sleep when not busy. @@ -334,7 +335,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) le32_to_cpu(cmd->sleep_interval[3]), le32_to_cpu(cmd->sleep_interval[4])); - return priv->trans.ops->send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, + return trans_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, sizeof(struct iwl_powertable_cmd), cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 4c809bf9aac..077d023ab7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -37,6 +37,7 @@ #include "iwl-io.h" #include "iwl-helpers.h" #include "iwl-agn.h" +#include "iwl-trans.h" /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after * sending probe req. This should be set long enough to hear probe responses @@ -74,7 +75,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EIO; - ret = priv->trans.ops->send_cmd(priv, &cmd); + ret = trans_send_cmd(priv, &cmd); if (ret) return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 06faa1e2237..78cf1076c03 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -35,6 +35,7 @@ #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-sta.h" +#include "iwl-trans.h" /* priv->sta_lock must be held */ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) @@ -156,7 +157,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, } cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); - ret = priv->trans.ops->send_cmd(priv, &cmd); + ret = trans_send_cmd(priv, &cmd); if (ret || (flags & CMD_ASYNC)) return ret; @@ -412,7 +413,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, cmd.flags |= CMD_WANT_SKB; - ret = priv->trans.ops->send_cmd(priv, &cmd); + ret = trans_send_cmd(priv, &cmd); if (ret) return ret; @@ -781,7 +782,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return -EINVAL; if (is_lq_table_valid(priv, ctx, lq)) - ret = priv->trans.ops->send_cmd(priv, &cmd); + ret = trans_send_cmd(priv, &cmd); else ret = -EINVAL; diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 6f92d22d07e..81108be841c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -76,7 +76,7 @@ #include "iwl-io.h" #include "iwl-agn.h" #include "iwl-testmode.h" - +#include "iwl-trans.h" /* The TLVs used in the gnl message policy between the kernel module and * user space application. iwl_testmode_gnl_msg_policy is to be carried @@ -239,7 +239,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," " len %d\n", cmd.id, cmd.flags, cmd.len[0]); /* ok, let's submit the command to ucode */ - return priv->trans.ops->send_cmd(priv, &cmd); + return trans_send_cmd(priv, &cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 0c924569636..d760857c863 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -467,7 +467,7 @@ static int iwl_trans_tx_alloc(struct iwl_priv *priv) return 0; error: - priv->trans.ops->tx_free(priv); + trans_tx_free(priv); return ret; } @@ -511,7 +511,7 @@ static int iwl_trans_tx_init(struct iwl_priv *priv) error: /*Upon error, free only if we allocated something */ if (alloc) - priv->trans.ops->tx_free(priv); + trans_tx_free(priv); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index bec494c5a97..111acca07d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -60,5 +60,46 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +static inline int trans_rx_init(struct iwl_priv *priv) +{ + return priv->trans.ops->rx_init(priv); +} + +static inline int trans_rx_stop(struct iwl_priv *priv) +{ + return priv->trans.ops->rx_stop(priv); +} + +static inline void trans_rx_free(struct iwl_priv *priv) +{ + priv->trans.ops->rx_free(priv); +} + +static inline int trans_tx_init(struct iwl_priv *priv) +{ + return priv->trans.ops->tx_init(priv); +} + +static inline int trans_tx_stop(struct iwl_priv *priv) +{ + return priv->trans.ops->tx_stop(priv); +} + +static inline void trans_tx_free(struct iwl_priv *priv) +{ + priv->trans.ops->tx_free(priv); +} + +static inline int trans_send_cmd(struct iwl_priv *priv, + struct iwl_host_cmd *cmd) +{ + return priv->trans.ops->send_cmd(priv, cmd); +} + +static inline int trans_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags, + u16 len, const void *data) +{ + return priv->trans.ops->send_cmd_pdu(priv, id, flags, len, data); +} void iwl_trans_register(struct iwl_trans *trans); -- cgit v1.2.3-70-g09d2 From 6b6db91c8aa14fa9bd041321026d69b9f6ea42ff Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Fri, 8 Jul 2011 08:46:17 -0700 Subject: iwlagn: remove the indirection for update_chain_flags Not needed since the driver split. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-core.h | 3 --- drivers/net/wireless/iwlwifi/iwl-power.c | 6 +++--- 8 files changed, 5 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 9cc161df3f0..11f10c13af5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -171,7 +171,6 @@ static struct iwl_lib_ops iwl1000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .update_chain_flags = iwl_update_chain_flags, .apm_ops = { .init = iwl_apm_init, .config = iwl1000_nic_config, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 0c3245061f9..953e9672a6a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -171,7 +171,6 @@ static struct iwl_lib_ops iwl2000_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .update_chain_flags = iwl_update_chain_flags, .apm_ops = { .init = iwl_apm_init, .config = iwl2000_nic_config, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 835ed7a295e..f6bc02f68f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -323,7 +323,6 @@ static struct iwl_lib_ops iwl5000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, @@ -351,7 +350,6 @@ static struct iwl_lib_ops iwl5150_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f03448f40f8..91418fa38fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -263,7 +263,6 @@ static struct iwl_lib_ops iwl6000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, @@ -293,7 +292,6 @@ static struct iwl_lib_ops iwl6030_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 2ec3863306b..710ada9c413 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -1001,8 +1001,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) /* Some power changes may have been made during the calibration. * Update and commit the RXON */ - if (priv->cfg->ops->lib->update_chain_flags) - priv->cfg->ops->lib->update_chain_flags(priv); + iwl_update_chain_flags(priv); data->state = IWL_CHAIN_NOISE_DONE; iwl_power_update_mode(priv, false); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index cfe945c58fd..c7102bbba0f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1724,8 +1724,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) if (test_bit(STATUS_SCAN_HW, &priv->status)) goto out; - if (priv->cfg->ops->lib->update_chain_flags) - priv->cfg->ops->lib->update_chain_flags(priv); + iwl_update_chain_flags(priv); if (smps_request != -1) { priv->current_ht_config.smps = smps_request; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3f7b921922a..e1ab1a17e7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -121,9 +121,6 @@ struct iwl_lib_ops { /* power management */ struct iwl_apm_ops apm_ops; - /* power */ - void (*update_chain_flags)(struct iwl_priv *priv); - /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 9c10462c20f..64ff40ae102 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -406,9 +406,9 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)) clear_bit(STATUS_POWER_PMI, &priv->status); - if (priv->cfg->ops->lib->update_chain_flags && update_chains) - priv->cfg->ops->lib->update_chain_flags(priv); - else if (priv->cfg->ops->lib->update_chain_flags) + if (update_chains) + iwl_update_chain_flags(priv); + else IWL_DEBUG_POWER(priv, "Cannot update the power, chain noise " "calibration running: %d\n", -- cgit v1.2.3-70-g09d2 From e4c598b7ce36f4416f7672617265bc1fa92e5a5f Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Fri, 8 Jul 2011 08:46:18 -0700 Subject: iwlagn: remove the indirection for iwl_apm_init Not needed since the driver split. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 5 +---- drivers/net/wireless/iwlwifi/iwl-2000.c | 5 +---- drivers/net/wireless/iwlwifi/iwl-5000.c | 10 ++-------- drivers/net/wireless/iwlwifi/iwl-6000.c | 10 ++-------- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.h | 9 ++------- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 2 +- 7 files changed, 11 insertions(+), 34 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 11f10c13af5..5be27672eb9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -171,10 +171,7 @@ static struct iwl_lib_ops iwl1000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl1000_nic_config, - }, + .nic_config = iwl1000_nic_config, .eeprom_ops = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 953e9672a6a..2580dc36f47 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -171,10 +171,7 @@ static struct iwl_lib_ops iwl2000_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl2000_nic_config, - }, + .nic_config = iwl2000_nic_config, .eeprom_ops = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index f6bc02f68f4..1d9bae376d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -324,10 +324,7 @@ static struct iwl_lib_ops iwl5000_lib = { .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .set_channel_switch = iwl5000_hw_channel_switch, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl5000_nic_config, - }, + .nic_config = iwl5000_nic_config, .eeprom_ops = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, @@ -351,10 +348,7 @@ static struct iwl_lib_ops iwl5150_lib = { .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .set_channel_switch = iwl5000_hw_channel_switch, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl5000_nic_config, - }, + .nic_config = iwl5000_nic_config, .eeprom_ops = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 91418fa38fc..73ea73eafc5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -264,10 +264,7 @@ static struct iwl_lib_ops iwl6000_lib = { .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .set_channel_switch = iwl6000_hw_channel_switch, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl6000_nic_config, - }, + .nic_config = iwl6000_nic_config, .eeprom_ops = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, @@ -293,10 +290,7 @@ static struct iwl_lib_ops iwl6030_lib = { .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .set_channel_switch = iwl6000_hw_channel_switch, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl6000_nic_config, - }, + .nic_config = iwl6000_nic_config, .eeprom_ops = { .regulatory_bands = { EEPROM_REG_BAND_1_CHANNELS, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index c7102bbba0f..f787ef5c9d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -703,7 +703,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) /* nic_init */ spin_lock_irqsave(&priv->lock, flags); - priv->cfg->ops->lib->apm_ops.init(priv); + iwl_apm_init(priv); /* Set interrupt coalescing calibration timer to default (512 usecs) */ iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); @@ -712,7 +712,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) iwlagn_set_pwr_vmain(priv); - priv->cfg->ops->lib->apm_ops.config(priv); + priv->cfg->ops->lib->nic_config(priv); /* Allocate the RX queue, or reset if it is already allocated */ trans_rx_init(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e1ab1a17e7f..47cfbb9ddaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -96,11 +96,6 @@ struct iwl_hcmd_utils_ops { int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); }; -struct iwl_apm_ops { - int (*init)(struct iwl_priv *priv); - void (*config)(struct iwl_priv *priv); -}; - struct iwl_temp_ops { void (*temperature)(struct iwl_priv *priv); }; @@ -118,8 +113,8 @@ struct iwl_lib_ops { int (*is_valid_rtc_data_addr)(u32 addr); int (*set_channel_switch)(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch); - /* power management */ - struct iwl_apm_ops apm_ops; + /* device specific configuration */ + void (*nic_config)(struct iwl_priv *priv); /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 768d0ee276f..eab2834fc0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -449,7 +449,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) } e = (__le16 *)priv->eeprom; - priv->cfg->ops->lib->apm_ops.init(priv); + iwl_apm_init(priv); ret = iwl_eeprom_verify_signature(priv); if (ret < 0) { -- cgit v1.2.3-70-g09d2 From 70e3e8a6e831bf58a7eb98187c186221f01d5b64 Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Fri, 8 Jul 2011 08:46:19 -0700 Subject: iwlagn: remove indirection for eeprom_query_addr Not needed since the driver split. Eliminate redundant routine. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 -- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 - 9 files changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5be27672eb9..a558df953df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -182,7 +182,6 @@ static struct iwl_lib_ops iwl1000_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REGULATORY_BAND_NO_HT40, }, - .query_addr = iwlagn_eeprom_query_addr, }, .temp_ops = { .temperature = iwlagn_temperature, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 2580dc36f47..28559941d26 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -182,7 +182,6 @@ static struct iwl_lib_ops iwl2000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REGULATORY_BAND_NO_HT40, }, - .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, .temp_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 1d9bae376d2..55972cfc47a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -335,7 +335,6 @@ static struct iwl_lib_ops iwl5000_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .query_addr = iwlagn_eeprom_query_addr, }, .temp_ops = { .temperature = iwlagn_temperature, @@ -359,7 +358,6 @@ static struct iwl_lib_ops iwl5150_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .query_addr = iwlagn_eeprom_query_addr, }, .temp_ops = { .temperature = iwl5150_temperature, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 73ea73eafc5..17dc3377518 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -275,7 +275,6 @@ static struct iwl_lib_ops iwl6000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, .temp_ops = { @@ -301,7 +300,6 @@ static struct iwl_lib_ops iwl6030_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, .temp_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 7745816eaff..b8347db850e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -150,7 +150,7 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv) void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) { - const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, + const u8 *addr = iwl_eeprom_query_addr(priv, EEPROM_MAC_ADDRESS); memcpy(mac, addr, ETH_ALEN); } @@ -245,10 +245,10 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); /* the length is in 16-bit words, but we want entries */ - txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); + txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; - txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS); + txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS); for (idx = 0; idx < entries; idx++) { txp = &txp_array[idx]; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f787ef5c9d4..94f6d606866 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -611,8 +611,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address) return (address & ADDRESS_MSK) + (offset << 1); } -const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, - size_t offset) +const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { u32 address = eeprom_indirect_address(priv, offset); BUG_ON(address >= priv->cfg->base_params->eeprom_size); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index ff0b2ed7123..bde03b4f386 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -180,8 +180,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); int iwlagn_send_tx_power(struct iwl_priv *priv); void iwlagn_temperature(struct iwl_priv *priv); u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); -const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, - size_t offset); int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); int iwlagn_hw_nic_init(struct iwl_priv *priv); int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index eab2834fc0c..eee97bcf980 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -407,11 +407,6 @@ static int iwl_find_otp_image(struct iwl_priv *priv, return -EINVAL; } -const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) -{ - return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); -} - u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) { if (!priv->eeprom) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 804f910c651..e4bf8ac5e64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -292,7 +292,6 @@ extern const u8 iwl_eeprom_band_1[14]; struct iwl_eeprom_ops { const u32 regulatory_bands[7]; - const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset); void (*update_enhanced_txpower) (struct iwl_priv *priv); }; -- cgit v1.2.3-70-g09d2 From 909fc3cba374560ada33a7dc3ab242d0f1d2a135 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:20 -0700 Subject: iwlagn: remove double level temperature indirect call No need to do double level indirect call after driver split no functional changes Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-5000.c | 8 ++------ drivers/net/wireless/iwlwifi/iwl-6000.c | 8 ++------ drivers/net/wireless/iwlwifi/iwl-core.h | 6 +----- drivers/net/wireless/iwlwifi/iwl-rx.c | 4 ++-- 6 files changed, 9 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index a558df953df..7795855ff8f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -183,9 +183,7 @@ static struct iwl_lib_ops iwl1000_lib = { EEPROM_REGULATORY_BAND_NO_HT40, }, }, - .temp_ops = { - .temperature = iwlagn_temperature, - }, + .temperature = iwlagn_temperature, }; static const struct iwl_ops iwl1000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 28559941d26..b2b054f6cd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -184,9 +184,7 @@ static struct iwl_lib_ops iwl2000_lib = { }, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .temp_ops = { - .temperature = iwlagn_temperature, - }, + .temperature = iwlagn_temperature, }; static const struct iwl_ops iwl2000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 55972cfc47a..30c2df6ec83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -336,9 +336,7 @@ static struct iwl_lib_ops iwl5000_lib = { EEPROM_REG_BAND_52_HT40_CHANNELS }, }, - .temp_ops = { - .temperature = iwlagn_temperature, - }, + .temperature = iwlagn_temperature, }; static struct iwl_lib_ops iwl5150_lib = { @@ -359,9 +357,7 @@ static struct iwl_lib_ops iwl5150_lib = { EEPROM_REG_BAND_52_HT40_CHANNELS }, }, - .temp_ops = { - .temperature = iwl5150_temperature, - }, + .temperature = iwl5150_temperature, }; static const struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 17dc3377518..57f31692894 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -277,9 +277,7 @@ static struct iwl_lib_ops iwl6000_lib = { }, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .temp_ops = { - .temperature = iwlagn_temperature, - }, + .temperature = iwlagn_temperature, }; static struct iwl_lib_ops iwl6030_lib = { @@ -302,9 +300,7 @@ static struct iwl_lib_ops iwl6030_lib = { }, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .temp_ops = { - .temperature = iwlagn_temperature, - }, + .temperature = iwlagn_temperature, }; static struct iwl_nic_ops iwl6050_nic_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 47cfbb9ddaf..2e3ea55cea7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -96,10 +96,6 @@ struct iwl_hcmd_utils_ops { int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); }; -struct iwl_temp_ops { - void (*temperature)(struct iwl_priv *priv); -}; - struct iwl_lib_ops { /* set hw dependent parameters */ int (*set_hw_params)(struct iwl_priv *priv); @@ -120,7 +116,7 @@ struct iwl_lib_ops { struct iwl_eeprom_ops eeprom_ops; /* temperature */ - struct iwl_temp_ops temp_ops; + void (*temperature)(struct iwl_priv *priv); }; /* NIC specific ops */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 87148bb3f62..1690b49bb13 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -624,8 +624,8 @@ static void iwl_rx_statistics(struct iwl_priv *priv, iwl_rx_calc_noise(priv); queue_work(priv->workqueue, &priv->run_time_calib_work); } - if (priv->cfg->ops->lib->temp_ops.temperature && change) - priv->cfg->ops->lib->temp_ops.temperature(priv); + if (priv->cfg->ops->lib->temperature && change) + priv->cfg->ops->lib->temperature(priv); } static void iwl_rx_reply_statistics(struct iwl_priv *priv, -- cgit v1.2.3-70-g09d2 From 0a49b2c2a6bf2f774675e472afe68951900596fb Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:21 -0700 Subject: iwlagn: use bt handler for 2030 and 135 series devices For bt combo devices, need to use bt enabled handlers and functions Reported-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-2000.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index b2b054f6cd6..21b68b2839c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -168,6 +168,27 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) static struct iwl_lib_ops iwl2000_lib = { .set_hw_params = iwl2000_hw_set_hw_params, .rx_handler_setup = iwlagn_rx_handler_setup, + .setup_deferred_work = iwlagn_setup_deferred_work, + .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, + .nic_config = iwl2000_nic_config, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + }, + .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, + }, + .temperature = iwlagn_temperature, +}; + +static struct iwl_lib_ops iwl2030_lib = { + .set_hw_params = iwl2000_hw_set_hw_params, + .rx_handler_setup = iwlagn_bt_rx_handler_setup, .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, @@ -193,7 +214,7 @@ static const struct iwl_ops iwl2000_ops = { }; static const struct iwl_ops iwl2030_ops = { - .lib = &iwl2000_lib, + .lib = &iwl2030_lib, .utils = &iwlagn_hcmd_utils, }; @@ -203,7 +224,7 @@ static const struct iwl_ops iwl105_ops = { }; static const struct iwl_ops iwl135_ops = { - .lib = &iwl2000_lib, + .lib = &iwl2030_lib, .utils = &iwlagn_hcmd_utils, }; -- cgit v1.2.3-70-g09d2 From 207ecc5eab908843449c167f7264a35d7d5d5e0b Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Fri, 8 Jul 2011 08:46:23 -0700 Subject: iwlagn: Enable/disable PS poll based on RSSI and BT coex traffic state WiFi throughput drops drastically when BT is turned on, BT and WiFi are simultaneously transmitting/receiving traffic. This is particularly true when BT has higher priority over WiFi, and hence the device defers TX frames. The AP assumes that the channel is bad and reduces the data rate, implying longer airtime, which exacerbates the problem further, resulting ultimately in what is popularly called the "death-spiral" phenomenon. The use of PS-poll in such scenarios guarantees a low but consistent throughput. Since the death-spiral phenomenon is observed only when the RSSI is low, use PS-poll only when RSSI is low and disable when high, with a known hysterisis. This feature specifies the high and low thresholds and implements the callbacks registered with mac80211, which will be called when threshold events occur. iwlwifi: dynamic pspoll: optimize rssi monitor code Signed-off-by: Meenakshi Venkataraman Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 106 +++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 + drivers/net/wireless/iwlwifi/iwl-agn.c | 36 ++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 + drivers/net/wireless/iwlwifi/iwl-commands.h | 3 + drivers/net/wireless/iwlwifi/iwl-dev.h | 3 + 6 files changed, 150 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 94f6d606866..eb2be0d3048 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1634,9 +1634,11 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) } else { basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << IWLAGN_BT_FLAG_COEX_MODE_SHIFT; - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_sco_disable) + + if (!priv->bt_enable_pspoll) basic.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE; + else + basic.flags &= ~IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE; if (priv->bt_ch_announce) basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; @@ -1671,6 +1673,84 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) } +void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena) +{ + struct iwl_rxon_context *ctx, *found_ctx = NULL; + bool found_ap = false; + + lockdep_assert_held(&priv->mutex); + + /* Check whether AP or GO mode is active. */ + if (rssi_ena) { + for_each_context(priv, ctx) { + if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_AP && + iwl_is_associated_ctx(ctx)) { + found_ap = true; + break; + } + } + } + + /* + * If disable was received or If GO/AP mode, disable RSSI + * measurements. + */ + if (!rssi_ena || found_ap) { + if (priv->cur_rssi_ctx) { + ctx = priv->cur_rssi_ctx; + ieee80211_disable_rssi_reports(ctx->vif); + priv->cur_rssi_ctx = NULL; + } + return; + } + + /* + * If rssi measurements need to be enabled, consider all cases now. + * Figure out how many contexts are active. + */ + for_each_context(priv, ctx) { + if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION && + iwl_is_associated_ctx(ctx)) { + found_ctx = ctx; + break; + } + } + + /* + * rssi monitor already enabled for the correct interface...nothing + * to do. + */ + if (found_ctx == priv->cur_rssi_ctx) + return; + + /* + * Figure out if rssi monitor is currently enabled, and needs + * to be changed. If rssi monitor is already enabled, disable + * it first else just enable rssi measurements on the + * interface found above. + */ + if (priv->cur_rssi_ctx) { + ctx = priv->cur_rssi_ctx; + if (ctx->vif) + ieee80211_disable_rssi_reports(ctx->vif); + } + + priv->cur_rssi_ctx = found_ctx; + + if (!found_ctx) + return; + + ieee80211_enable_rssi_reports(found_ctx->vif, + IWLAGN_BT_PSP_MIN_RSSI_THRESHOLD, + IWLAGN_BT_PSP_MAX_RSSI_THRESHOLD); +} + +static bool iwlagn_bt_traffic_is_sco(struct iwl_bt_uart_msg *uart_msg) +{ + return BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3 >> + BT_UART_MSG_FRAME3SCOESCO_POS; +} + static void iwlagn_bt_traffic_change_work(struct work_struct *work) { struct iwl_priv *priv = @@ -1732,10 +1812,30 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) ieee80211_request_smps(ctx->vif, smps_request); } } + + /* + * Dynamic PS poll related functionality. Adjust RSSI measurements if + * necessary. + */ + iwlagn_bt_coex_rssi_monitor(priv); out: mutex_unlock(&priv->mutex); } +/* + * If BT sco traffic, and RSSI monitor is enabled, move measurements to the + * correct interface or disable it if this is the last interface to be + * removed. + */ +void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv) +{ + if (priv->bt_is_sco && + priv->bt_traffic_load == IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS) + iwlagn_bt_adjust_rssi_monitor(priv, true); + else + iwlagn_bt_adjust_rssi_monitor(priv, false); +} + static void iwlagn_print_uartmsg(struct iwl_priv *priv, struct iwl_bt_uart_msg *uart_msg) { @@ -1851,6 +1951,8 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, iwlagn_print_uartmsg(priv, uart_msg); priv->last_bt_traffic_load = priv->bt_traffic_load; + priv->bt_is_sco = iwlagn_bt_traffic_is_sco(uart_msg); + if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { if (priv->bt_status != coex->bt_status || priv->last_bt_traffic_load != coex->bt_traffic_load) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index d32cee1a758..fca376e9154 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -731,6 +731,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, } ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } + + iwlagn_bt_coex_rssi_monitor(priv); } if (ctx->ht.enabled) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3a4fca14fef..cbd8d101f6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2015,11 +2015,18 @@ int iwl_alive_start(struct iwl_priv *priv) if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) { /* Configure Bluetooth device coexistence support */ + if (priv->cfg->bt_params->bt_sco_disable) + priv->bt_enable_pspoll = false; + else + priv->bt_enable_pspoll = true; + priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; iwlagn_send_advance_bt_config(priv); priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; + priv->cur_rssi_ctx = NULL; + iwlagn_send_prio_tbl(priv); /* FIXME: w/a to force change uCode BT state machine */ @@ -2102,6 +2109,8 @@ static void __iwl_down(struct iwl_priv *priv) /* reset BT coex data */ priv->bt_status = 0; + priv->cur_rssi_ctx = NULL; + priv->bt_is_sco = 0; if (priv->cfg->bt_params) priv->bt_traffic_load = priv->cfg->bt_params->bt_init_traffic_load; @@ -2277,6 +2286,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv) u8 bt_ci_compliance; u8 bt_load; u8 bt_status; + bool bt_is_sco; lockdep_assert_held(&priv->mutex); @@ -2297,6 +2307,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv) bt_ci_compliance = priv->bt_ci_compliance; bt_load = priv->bt_traffic_load; bt_status = priv->bt_status; + bt_is_sco = priv->bt_is_sco; __iwl_down(priv); @@ -2304,6 +2315,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv) priv->bt_ci_compliance = bt_ci_compliance; priv->bt_traffic_load = bt_load; priv->bt_status = bt_status; + priv->bt_is_sco = bt_is_sco; } static void iwl_bg_restart(struct work_struct *data) @@ -3330,6 +3342,29 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->beacon_cmd); } +void iwl_mac_rssi_callback(struct ieee80211_hw *hw, + enum ieee80211_rssi_event rssi_event) +{ + struct iwl_priv *priv = hw->priv; + + mutex_lock(&priv->mutex); + + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + if (rssi_event == RSSI_EVENT_LOW) + priv->bt_enable_pspoll = true; + else if (rssi_event == RSSI_EVENT_HIGH) + priv->bt_enable_pspoll = false; + + iwlagn_send_advance_bt_config(priv); + } else { + IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled," + "ignoring RSSI callback\n"); + } + + mutex_unlock(&priv->mutex); +} + struct ieee80211_ops iwlagn_hw_ops = { .tx = iwlagn_mac_tx, .start = iwlagn_mac_start, @@ -3355,6 +3390,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, .offchannel_tx = iwl_mac_offchannel_tx, .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, + .rssi_callback = iwl_mac_rssi_callback, CFG80211_TESTMODE_CMD(iwl_testmode_cmd) CFG80211_TESTMODE_DUMP(iwl_testmode_dump) }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index bde03b4f386..81a009bdd67 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -261,6 +261,8 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); +void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv); +void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena); #ifdef CONFIG_IWLWIFI_DEBUG const char *iwl_get_tx_fail_reason(u32 status); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 8a2edf8dce3..ee2563777e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1931,6 +1931,9 @@ struct iwl_bt_cmd { /* Disable Sync PSPoll on SCO/eSCO */ #define IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE BIT(7) +#define IWLAGN_BT_PSP_MIN_RSSI_THRESHOLD -75 /* dBm */ +#define IWLAGN_BT_PSP_MAX_RSSI_THRESHOLD -65 /* dBm */ + #define IWLAGN_BT_PRIO_BOOST_MAX 0xFF #define IWLAGN_BT_PRIO_BOOST_MIN 0x00 #define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0 diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 92f8ce9d5a4..29eb41dcb9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1525,6 +1525,9 @@ struct iwl_priv { u16 dynamic_frag_thresh; u8 bt_ci_compliance; struct work_struct bt_traffic_change_work; + bool bt_enable_pspoll; + struct iwl_rxon_context *cur_rssi_ctx; + bool bt_is_sco; struct iwl_hw_params hw_params; -- cgit v1.2.3-70-g09d2 From 3a3b14c26cd285b4f4700bf10ea634bbbe73eac6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:24 -0700 Subject: iwlagn: declare static Declare iwl_mac_rssi_callback as "static" Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index cbd8d101f6f..3f2b9d6d257 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3342,7 +3342,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->beacon_cmd); } -void iwl_mac_rssi_callback(struct ieee80211_hw *hw, +static void iwl_mac_rssi_callback(struct ieee80211_hw *hw, enum ieee80211_rssi_event rssi_event) { struct iwl_priv *priv = hw->priv; -- cgit v1.2.3-70-g09d2 From c7c1115b8ff485d3a48b70bb7135776a696778ad Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:25 -0700 Subject: iwlagn: add CMD_ON_DEMAND flag for host command from testmode For all the hist command request from testmode, set the CMD_ON_DEMAND flag. this flag will be used later to control the uCode behavior Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-sv-open.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 29eb41dcb9c..b7e9fd1efb6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -261,6 +261,7 @@ enum { CMD_SYNC = 0, CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), + CMD_ON_DEMAND = BIT(2), }; #define DEF_CMD_PAYLOAD_SIZE 320 diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 81108be841c..653b7870adc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -232,6 +232,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) return -ENOMSG; } + cmd.flags = CMD_ON_DEMAND; cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); -- cgit v1.2.3-70-g09d2 From e98a1939a2d75354631487328339fe8d2117fce9 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:26 -0700 Subject: iwlagn: allow application own the uCode operation Since we open the door to allow application control the device behavior through testmode, add command to allow application request the ownership of the uCode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 8 ++++++ drivers/net/wireless/iwlwifi/iwl-sv-open.c | 42 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-testmode.h | 14 ++++++++-- 3 files changed, 62 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index b7e9fd1efb6..fa0827f4d24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1263,6 +1263,10 @@ struct iwl_trans { const struct iwl_trans_ops *ops; }; +/* uCode ownership */ +#define IWL_OWNERSHIP_DRIVER 0 +#define IWL_OWNERSHIP_TM 1 + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1351,6 +1355,10 @@ struct iwl_priv { int fw_index; /* firmware we're trying to load */ u32 ucode_ver; /* version of ucode, copy of iwl_ucode.ver */ + + /* uCode owner: default: IWL_OWNERSHIP_DRIVER */ + u8 ucode_owner; + struct fw_img ucode_rt; struct fw_img ucode_init; diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 653b7870adc..ed9bd91ece7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -105,6 +105,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, }, }; /* @@ -587,6 +588,42 @@ static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, return -ENOBUFS; } +/* + * This function handles the user application switch ucode ownership. + * + * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and + * decide who the current owner of the uCode + * + * If the current owner is OWNERSHIP_TM, then the only host command + * can deliver to uCode is from testmode, all the other host commands + * will dropped. + * + * default driver is the owner of uCode in normal operational mode + * + * @hw: ieee80211_hw object that represents the device + * @tb: gnl message fields from the user space + */ +static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) +{ + struct iwl_priv *priv = hw->priv; + u8 owner; + + if (!tb[IWL_TM_ATTR_UCODE_OWNER]) { + IWL_DEBUG_INFO(priv, "Error finding ucode owner\n"); + return -ENOMSG; + } + + owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); + if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM)) + priv->ucode_owner = owner; + else { + IWL_DEBUG_INFO(priv, "Invalid owner\n"); + return -EINVAL; + } + return 0; +} + + /* The testmode gnl message handler that takes the gnl message from the * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then * invoke the corresponding handlers. @@ -656,6 +693,11 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) result = iwl_testmode_trace(hw, tb); break; + case IWL_TM_CMD_APP2DEV_OWNERSHIP: + IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n"); + result = iwl_testmode_ownership(hw, tb); + break; + default: IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); result = -ENOSYS; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index d825188e521..b980bda4b0f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -103,6 +103,10 @@ * @IWL_TM_CMD_DEV2APP_EEPROM_RSP: * commands from kernel space to carry the eeprom response * to user application + * @IWL_TM_CMD_APP2DEV_OWNERSHIP: + * commands from user application to own change the ownership of the uCode + * if application has the ownership, the only host command from + * testmode will deliver to uCode. Default owner is driver */ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_UCODE = 1, @@ -121,7 +125,8 @@ enum iwl_tm_cmd_t { IWL_TM_CMD_DEV2APP_SYNC_RSP = 14, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT = 15, IWL_TM_CMD_DEV2APP_EEPROM_RSP = 16, - IWL_TM_CMD_MAX = 17, + IWL_TM_CMD_APP2DEV_OWNERSHIP = 17, + IWL_TM_CMD_MAX = 18, }; /* @@ -187,6 +192,10 @@ enum iwl_tm_cmd_t { * The mandatory fields are: * IWL_TM_ATTR_FIXRATE for the fixed rate * + * @IWL_TM_ATTR_UCODE_OWNER: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP, + * The mandatory fields are: + * IWL_TM_ATTR_UCODE_OWNER for the new owner */ enum iwl_tm_attr_t { IWL_TM_ATTR_NOT_APPLICABLE = 0, @@ -203,7 +212,8 @@ enum iwl_tm_attr_t { IWL_TM_ATTR_TRACE_SIZE = 11, IWL_TM_ATTR_TRACE_DUMP = 12, IWL_TM_ATTR_FIXRATE = 13, - IWL_TM_ATTR_MAX = 14, + IWL_TM_ATTR_UCODE_OWNER = 14, + IWL_TM_ATTR_MAX = 15, }; /* uCode trace buffer */ -- cgit v1.2.3-70-g09d2 From eedb6e357a4b1bd3d7e4544e77fbd71718492547 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:27 -0700 Subject: iwlagn: block regular host commands if driver don't own uCode The only host command allow to send to uCode is the one initiated from testmode if testmode is the owner of uCode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-tx.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index b62d03235b8..9b07e07f168 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -328,6 +328,12 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } + if ((priv->ucode_owner == IWL_OWNERSHIP_TM) && + !(cmd->flags & CMD_ON_DEMAND)) { + IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); + return -EIO; + } + copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); -- cgit v1.2.3-70-g09d2 From 4e308119771573f949203f9f4732bcbfb9628279 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Jul 2011 08:46:28 -0700 Subject: iwlagn: separate and enhance the fixed rate from For testing purpose, we need better control of msc from user application. Separate the fixed_rate between debugfs and testmode and enforce it. Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 28 ++++++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-sv-open.c | 2 +- 4 files changed, 30 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 85e082830c1..ebcd13bc10d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -336,6 +336,12 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data, } #ifdef CONFIG_MAC80211_DEBUGFS +/** + * Program the device to use fixed rate for frame transmit + * This is for debugging/testing only + * once the device start use fixed rate, we need to reload the module + * to being back the normal operation. + */ static void rs_program_fix_rate(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta) { @@ -348,13 +354,15 @@ static void rs_program_fix_rate(struct iwl_priv *priv, lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ - lq_sta->dbg_fixed_rate = priv->dbg_fixed_rate; + /* testmode has higher priority to overwirte the fixed rate */ + if (priv->tm_fixed_rate) + lq_sta->dbg_fixed_rate = priv->tm_fixed_rate; IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", - lq_sta->lq.sta_id, priv->dbg_fixed_rate); + lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); - if (priv->dbg_fixed_rate) { - rs_fill_link_cmd(NULL, lq_sta, priv->dbg_fixed_rate); + if (lq_sta->dbg_fixed_rate) { + rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, false); } @@ -1073,7 +1081,8 @@ done: if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); #ifdef CONFIG_MAC80211_DEBUGFS - if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate) + if ((priv->tm_fixed_rate) && + (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) rs_program_fix_rate(priv, lq_sta); #endif if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) @@ -2896,7 +2905,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; lq_sta->is_agg = 0; - priv->dbg_fixed_rate = 0; + priv->tm_fixed_rate = 0; #ifdef CONFIG_MAC80211_DEBUGFS lq_sta->dbg_fixed_rate = 0; #endif @@ -3095,7 +3104,6 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, IWL_DEBUG_RATE(priv, "Fixed rate ON\n"); } else { lq_sta->dbg_fixed_rate = 0; - priv->dbg_fixed_rate = 0; IWL_ERR(priv, "Invalid antenna selection 0x%X, Valid is 0x%X\n", ant_sel_tx, valid_tx_ant); @@ -3123,9 +3131,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, return -EFAULT; if (sscanf(buf, "%x", &parsed_rate) == 1) - priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = parsed_rate; + lq_sta->dbg_fixed_rate = parsed_rate; else - priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = 0; + lq_sta->dbg_fixed_rate = 0; rs_program_fix_rate(priv, lq_sta); @@ -3155,7 +3163,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, lq_sta->total_failed, lq_sta->total_success, lq_sta->active_legacy_rate); desc += sprintf(buff+desc, "fixed rate 0x%X\n", - priv->dbg_fixed_rate); + lq_sta->dbg_fixed_rate); desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index db3ec7aaf94..07c1242599f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -436,6 +436,16 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, if (ieee80211_is_data(fc)) { tx_cmd->initial_rate_index = 0; tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; + if (priv->tm_fixed_rate) { + /* + * rate overwrite by testmode + * we not only send lq command to change rate + * we also re-enforce per data pkt base. + */ + tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK; + memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate, + sizeof(tx_cmd->rate_n_flags)); + } return; } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index fa0827f4d24..a0cca02032e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1605,7 +1605,7 @@ struct iwl_priv { #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL struct iwl_testmode_trace testmode_trace; #endif - u32 dbg_fixed_rate; + u32 tm_fixed_rate; }; /*iwl_priv */ diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index ed9bd91ece7..a322f5e8075 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -454,7 +454,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) "Error finding fixrate setting\n"); return -ENOMSG; } - priv->dbg_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); + priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); break; default: -- cgit v1.2.3-70-g09d2 From 5c3d29fc0d083e674c09407f1bc78e9dbf4ae8a5 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Fri, 8 Jul 2011 08:46:29 -0700 Subject: iwlagn: remove iwlagn_hcmd_utils structure and call directly Not needed since the driver split. Move single use routines to calling location and keep static where possible. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 4 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 - drivers/net/wireless/iwlwifi/iwl-6000.c | 4 -- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.h | 7 -- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 104 +-------------------------- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 35 ++++++++- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 +++- drivers/net/wireless/iwlwifi/iwl-agn.h | 9 ++- drivers/net/wireless/iwlwifi/iwl-core.h | 17 ----- drivers/net/wireless/iwlwifi/iwl-rx.c | 43 ++++++++++- drivers/net/wireless/iwlwifi/iwl-scan.c | 5 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 13 +++- 14 files changed, 109 insertions(+), 151 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 7795855ff8f..2f56b343e86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -188,7 +188,6 @@ static struct iwl_lib_ops iwl1000_lib = { static const struct iwl_ops iwl1000_ops = { .lib = &iwl1000_lib, - .utils = &iwlagn_hcmd_utils, }; static struct iwl_base_params iwl1000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 21b68b2839c..32ac8654b79 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -210,22 +210,18 @@ static struct iwl_lib_ops iwl2030_lib = { static const struct iwl_ops iwl2000_ops = { .lib = &iwl2000_lib, - .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl2030_ops = { .lib = &iwl2030_lib, - .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl105_ops = { .lib = &iwl2000_lib, - .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl135_ops = { .lib = &iwl2030_lib, - .utils = &iwlagn_hcmd_utils, }; static struct iwl_base_params iwl2000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 30c2df6ec83..556489302da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -362,12 +362,10 @@ static struct iwl_lib_ops iwl5150_lib = { static const struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, - .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl5150_ops = { .lib = &iwl5150_lib, - .utils = &iwlagn_hcmd_utils, }; static struct iwl_base_params iwl5000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 57f31692894..80f1ef61a3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -313,24 +313,20 @@ static struct iwl_nic_ops iwl6150_nic_ops = { static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, - .utils = &iwlagn_hcmd_utils, }; static const struct iwl_ops iwl6050_ops = { .lib = &iwl6000_lib, - .utils = &iwlagn_hcmd_utils, .nic = &iwl6050_nic_ops, }; static const struct iwl_ops iwl6150_ops = { .lib = &iwl6000_lib, - .utils = &iwlagn_hcmd_utils, .nic = &iwl6150_nic_ops, }; static const struct iwl_ops iwl6030_ops = { .lib = &iwl6030_lib, - .utils = &iwlagn_hcmd_utils, }; static struct iwl_base_params iwl6000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 710ada9c413..02c7c65ee86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -67,6 +67,7 @@ #include "iwl-core.h" #include "iwl-agn-calib.h" #include "iwl-trans.h" +#include "iwl-agn.h" /***************************************************************************** * INIT calibrations framework @@ -993,8 +994,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n", min_average_noise, min_average_noise_antenna_i); - if (priv->cfg->ops->utils->gain_computation) - priv->cfg->ops->utils->gain_computation(priv, average_noise, + iwlagn_gain_computation(priv, average_noise, min_average_noise_antenna_i, min_average_noise, find_first_chain(priv->cfg->valid_rx_ant)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index 4ef4dd93425..a869fc9205d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -71,13 +71,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv); void iwl_init_sensitivity(struct iwl_priv *priv); void iwl_reset_run_time_calib(struct iwl_priv *priv); -static inline void iwl_chain_noise_reset(struct iwl_priv *priv) -{ - - if (!priv->disable_chain_noise_cal && - priv->cfg->ops->utils->chain_noise_reset) - priv->cfg->ops->utils->chain_noise_reset(priv); -} int iwl_send_calib_results(struct iwl_priv *priv); int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 4d7674c0c72..f0f5f5eada7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -57,17 +57,7 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) } } -static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) -{ - u16 size = (u16)sizeof(struct iwl_addsta_cmd); - struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data; - memcpy(addsta, cmd, size); - /* resrved in 5000 */ - addsta->rate_n_flags = cpu_to_le16(0); - return size; -} - -static void iwlagn_gain_computation(struct iwl_priv *priv, +void iwlagn_gain_computation(struct iwl_priv *priv, u32 average_noise[NUM_RX_CHAINS], u16 min_average_noise_antenna_i, u32 min_average_noise, @@ -126,89 +116,6 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, } } -static void iwlagn_chain_noise_reset(struct iwl_priv *priv) -{ - struct iwl_chain_noise_data *data = &priv->chain_noise_data; - int ret; - - if ((data->state == IWL_CHAIN_NOISE_ALIVE) && - iwl_is_any_associated(priv)) { - struct iwl_calib_chain_noise_reset_cmd cmd; - - /* clear data for chain noise calibration algorithm */ - data->chain_noise_a = 0; - data->chain_noise_b = 0; - data->chain_noise_c = 0; - data->chain_signal_a = 0; - data->chain_signal_b = 0; - data->chain_signal_c = 0; - data->beacon_count = 0; - - memset(&cmd, 0, sizeof(cmd)); - iwl_set_calib_hdr(&cmd.hdr, - priv->_agn.phy_calib_chain_noise_reset_cmd); - ret = trans_send_cmd_pdu(priv, - REPLY_PHY_CALIBRATION_CMD, - CMD_SYNC, sizeof(cmd), &cmd); - if (ret) - IWL_ERR(priv, - "Could not send REPLY_PHY_CALIBRATION_CMD\n"); - data->state = IWL_CHAIN_NOISE_ACCUMULATE; - IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n"); - } -} - -static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags) -{ - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS || - info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT || - info->flags & IEEE80211_TX_CTL_AMPDU) - *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; -} - -/* Calc max signal level (dBm) among 3 possible receivers */ -static int iwlagn_calc_rssi(struct iwl_priv *priv, - struct iwl_rx_phy_res *rx_resp) -{ - /* data from PHY/DSP regarding signal strength, etc., - * contents are always there, not configurable by host - */ - struct iwlagn_non_cfg_phy *ncphy = - (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf; - u32 val, rssi_a, rssi_b, rssi_c, max_rssi; - u8 agc; - - val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]); - agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS; - - /* Find max rssi among 3 possible receivers. - * These values are measured by the digital signal processor (DSP). - * They should stay fairly constant even as the signal strength varies, - * if the radio's automatic gain control (AGC) is working right. - * AGC value (see below) will provide the "interesting" info. - */ - val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]); - rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >> - IWLAGN_OFDM_RSSI_A_BIT_POS; - rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >> - IWLAGN_OFDM_RSSI_B_BIT_POS; - val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]); - rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >> - IWLAGN_OFDM_RSSI_C_BIT_POS; - - max_rssi = max_t(u32, rssi_a, rssi_b); - max_rssi = max_t(u32, max_rssi, rssi_c); - - IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", - rssi_a, rssi_b, rssi_c, max_rssi, agc); - - /* dBm = max_rssi dB - agc dB - constant. - * Higher AGC (higher radio gain) means lower signal. */ - return max_rssi - agc - IWLAGN_RSSI_OFFSET; -} - int iwlagn_set_pan_params(struct iwl_priv *priv) { struct iwl_wipan_params_cmd cmd; @@ -301,12 +208,3 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) return ret; } - -struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { - .build_addsta_hcmd = iwlagn_build_addsta_hcmd, - .gain_computation = iwlagn_gain_computation, - .chain_noise_reset = iwlagn_chain_noise_reset, - .tx_cmd_protection = iwlagn_tx_cmd_protection, - .calc_rssi = iwlagn_calc_rssi, - .request_scan = iwlagn_request_scan, -}; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index fca376e9154..dc64f251535 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -674,6 +674,38 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, ht_conf->single_chain_sufficient = !need_multiple; } +static void iwlagn_chain_noise_reset(struct iwl_priv *priv) +{ + struct iwl_chain_noise_data *data = &priv->chain_noise_data; + int ret; + + if ((data->state == IWL_CHAIN_NOISE_ALIVE) && + iwl_is_any_associated(priv)) { + struct iwl_calib_chain_noise_reset_cmd cmd; + + /* clear data for chain noise calibration algorithm */ + data->chain_noise_a = 0; + data->chain_noise_b = 0; + data->chain_noise_c = 0; + data->chain_signal_a = 0; + data->chain_signal_b = 0; + data->chain_signal_c = 0; + data->beacon_count = 0; + + memset(&cmd, 0, sizeof(cmd)); + iwl_set_calib_hdr(&cmd.hdr, + priv->_agn.phy_calib_chain_noise_reset_cmd); + ret = trans_send_cmd_pdu(priv, + REPLY_PHY_CALIBRATION_CMD, + CMD_SYNC, sizeof(cmd), &cmd); + if (ret) + IWL_ERR(priv, + "Could not send REPLY_PHY_CALIBRATION_CMD\n"); + data->state = IWL_CHAIN_NOISE_ACCUMULATE; + IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n"); + } +} + void iwlagn_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, @@ -782,7 +814,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, iwl_power_update_mode(priv, false); /* Enable RX differential gain and sensitivity calibrations */ - iwl_chain_noise_reset(priv); + if (!priv->disable_chain_noise_cal) + iwlagn_chain_noise_reset(priv); priv->start_calib = 1; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 07c1242599f..7d3aad83e0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -339,6 +339,16 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask) iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask); } +static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + __le16 fc, __le32 *tx_flags) +{ + if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS || + info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT || + info->flags & IEEE80211_TX_CTL_AMPDU) + *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; +} + /* * handle build REPLY_TX command notification. */ @@ -388,7 +398,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; } - priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags); + iwlagn_tx_cmd_protection(priv, info, fc, &tx_flags); tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); if (ieee80211_is_mgmt(fc)) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 81a009bdd67..5f58b44bb2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -109,9 +109,6 @@ extern struct iwl_cfg iwl135_bg_cfg; extern struct iwl_cfg iwl135_bgn_cfg; extern struct iwl_mod_params iwlagn_mod_params; -extern struct iwl_hcmd_ops iwlagn_hcmd; -extern struct iwl_hcmd_ops iwlagn_bt_hcmd; -extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; extern struct ieee80211_ops iwlagn_hw_ops; @@ -253,6 +250,12 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); int iwlagn_send_beacon_cmd(struct iwl_priv *priv); int iwlagn_set_pan_params(struct iwl_priv *priv); +void iwlagn_gain_computation(struct iwl_priv *priv, + u32 average_noise[NUM_RX_CHAINS], + u16 min_average_noise_antenna_i, + u32 min_average_noise, + u8 default_chain); + /* bt coex */ void iwlagn_send_advance_bt_config(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2e3ea55cea7..692c30cb2fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -80,22 +80,6 @@ struct iwl_cmd; #define IWL_CMD(x) case x: return #x -struct iwl_hcmd_utils_ops { - u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); - void (*gain_computation)(struct iwl_priv *priv, - u32 *average_noise, - u16 min_average_noise_antennat_i, - u32 min_average_noise, - u8 default_chain); - void (*chain_noise_reset)(struct iwl_priv *priv); - void (*tx_cmd_protection)(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags); - int (*calc_rssi)(struct iwl_priv *priv, - struct iwl_rx_phy_res *rx_resp); - int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); -}; - struct iwl_lib_ops { /* set hw dependent parameters */ int (*set_hw_params)(struct iwl_priv *priv); @@ -126,7 +110,6 @@ struct iwl_nic_ops { struct iwl_ops { const struct iwl_lib_ops *lib; - const struct iwl_hcmd_utils_ops *utils; const struct iwl_nic_ops *nic; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 1690b49bb13..f3f3efe38ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -902,6 +902,47 @@ static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) return decrypt_out; } +/* Calc max signal level (dBm) among 3 possible receivers */ +static int iwlagn_calc_rssi(struct iwl_priv *priv, + struct iwl_rx_phy_res *rx_resp) +{ + /* data from PHY/DSP regarding signal strength, etc., + * contents are always there, not configurable by host + */ + struct iwlagn_non_cfg_phy *ncphy = + (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf; + u32 val, rssi_a, rssi_b, rssi_c, max_rssi; + u8 agc; + + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]); + agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS; + + /* Find max rssi among 3 possible receivers. + * These values are measured by the digital signal processor (DSP). + * They should stay fairly constant even as the signal strength varies, + * if the radio's automatic gain control (AGC) is working right. + * AGC value (see below) will provide the "interesting" info. + */ + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]); + rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >> + IWLAGN_OFDM_RSSI_A_BIT_POS; + rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >> + IWLAGN_OFDM_RSSI_B_BIT_POS; + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]); + rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >> + IWLAGN_OFDM_RSSI_C_BIT_POS; + + max_rssi = max_t(u32, rssi_a, rssi_b); + max_rssi = max_t(u32, max_rssi, rssi_c); + + IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", + rssi_a, rssi_b, rssi_c, max_rssi, agc); + + /* dBm = max_rssi dB - agc dB - constant. + * Higher AGC (higher radio gain) means lower signal. */ + return max_rssi - agc - IWLAGN_RSSI_OFFSET; +} + /* Called for REPLY_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ static void iwl_rx_reply_rx(struct iwl_priv *priv, @@ -983,7 +1024,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv, priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); /* Find max signal strength (dBm) among 3 antenna/receiver chains */ - rx_status.signal = priv->cfg->ops->utils->calc_rssi(priv, phy_res); + rx_status.signal = iwlagn_calc_rssi(priv, phy_res); iwl_dbg_log_rx_data_frame(priv, len, header); IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 077d023ab7e..f6ebe29eb79 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -350,9 +350,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, lockdep_assert_held(&priv->mutex); - if (WARN_ON(!priv->cfg->ops->utils->request_scan)) - return -EOPNOTSUPP; - cancel_delayed_work(&priv->scan_check); if (!iwl_is_ready_rf(priv)) { @@ -381,7 +378,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, priv->scan_start = jiffies; priv->scan_band = band; - ret = priv->cfg->ops->utils->request_scan(priv, vif); + ret = iwlagn_request_scan(priv, vif); if (ret) { clear_bit(STATUS_SCANNING, &priv->status); priv->scan_type = IWL_SCAN_NORMAL; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 78cf1076c03..65386e575b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -36,6 +36,7 @@ #include "iwl-core.h" #include "iwl-sta.h" #include "iwl-trans.h" +#include "iwl-agn.h" /* priv->sta_lock must be held */ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) @@ -133,6 +134,16 @@ static void iwl_add_sta_callback(struct iwl_priv *priv, } +static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) +{ + u16 size = (u16)sizeof(struct iwl_addsta_cmd); + struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data; + memcpy(addsta, cmd, size); + /* resrved in 5000 */ + addsta->rate_n_flags = cpu_to_le16(0); + return size; +} + int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags) { @@ -156,7 +167,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, might_sleep(); } - cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); + cmd.len[0] = iwlagn_build_addsta_hcmd(sta, data); ret = trans_send_cmd(priv, &cmd); if (ret || (flags & CMD_ASYNC)) -- cgit v1.2.3-70-g09d2 From cd27bc3c3efb95ee20e5b627c483eb9513cd0350 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Fri, 8 Jul 2011 20:40:30 -0700 Subject: mwifiex: 11n specific configuration for transmit Currently device is not able to transmit in 40MHz in spite of enabling 40MHz support in HTCapInfo IE in assoc req, because 11n specific FW capabilities for transmission are not initialized. This patch adds code to initilize these capabilities. Signed-off-by: Amitkumar Karwar Signed-off-by: Yogesh Ashok Powar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 11 +++++++++++ drivers/net/wireless/mwifiex/sta_cmd.c | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index afdd145dff0..4fee0993b18 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -157,6 +157,17 @@ enum MWIFIEX_802_11_WEP_STATUS { #define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) +/* httxcfg bitmap + * 0 reserved + * 1 20/40 Mhz enable(1)/disable(0) + * 2-3 reserved + * 4 green field enable(1)/disable(0) + * 5 short GI in 20 Mhz enable(1)/disable(0) + * 6 short GI in 40 Mhz enable(1)/disable(0) + * 7-15 reserved + */ +#define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6)) + #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) #define SETHT_MCS32(x) (x[4] |= 1) diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 49b9c1309f7..c54ee287b87 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -1113,6 +1113,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; struct mwifiex_ds_auto_ds auto_ds; enum state_11d_t state_11d; + struct mwifiex_ds_11n_tx_cfg tx_cfg; if (first_sta) { @@ -1198,8 +1199,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (ret) dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); + /* Send cmd to FW to configure 11n specific configuration + * (Short GI, Channel BW, Green field support etc.) for transmit + */ + tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG; + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_CFG, + HostCmd_ACT_GEN_SET, 0, &tx_cfg); + /* set last_init_cmd */ - priv->adapter->last_init_cmd = HostCmd_CMD_802_11_SNMP_MIB; + priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG; ret = -EINPROGRESS; return ret; -- cgit v1.2.3-70-g09d2 From 804f6acb7cea1ea5b3e0ded1bf037f9bf02f1124 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:46 +0700 Subject: ath9k_hw: remove hardcoded PLL overrides for AR9280 Use the proper masks for the register instead. Fixes adding the (still unused) half/quarter PLL flags. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 2fe0a34cbab..abc2cc8cefb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -447,26 +447,27 @@ static void ar9002_olc_init(struct ath_hw *ah) static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah, struct ath9k_channel *chan) { + int ref_div = 5; + int pll_div = 0x2c; u32 pll; - pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); + if (chan && IS_CHAN_5GHZ(chan) && !IS_CHAN_A_FAST_CLOCK(ah, chan)) { + if (AR_SREV_9280_20(ah)) { + ref_div = 10; + pll_div = 0x50; + } else { + pll_div = 0x28; + } + } + + pll = SM(ref_div, AR_RTC_9160_PLL_REFDIV); + pll |= SM(pll_div, AR_RTC_9160_PLL_DIV); if (chan && IS_CHAN_HALF_RATE(chan)) pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); else if (chan && IS_CHAN_QUARTER_RATE(chan)) pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); - if (chan && IS_CHAN_5GHZ(chan)) { - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - pll = 0x142c; - else if (AR_SREV_9280_20(ah)) - pll = 0x2850; - else - pll |= SM(0x28, AR_RTC_9160_PLL_DIV); - } else { - pll |= SM(0x2c, AR_RTC_9160_PLL_DIV); - } - return pll; } -- cgit v1.2.3-70-g09d2 From a949b1725c38775fb869d24433f13d2d104de145 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:47 +0700 Subject: ath9k_hw: always enable 5 GHz fast clock for AR9280 All devices support this, but some disable it using an EEPROM flag for some reason. Improves 5 GHz performance on those devices. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 07827b55e84..a6bb9c4f8a8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2079,10 +2079,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; } else { pCap->tx_desc_len = sizeof(struct ath_desc); - if (AR_SREV_9280_20(ah) && - ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <= - AR5416_EEP_MINOR_VER_16) || - ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G))) + if (AR_SREV_9280_20(ah)) pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK; } -- cgit v1.2.3-70-g09d2 From 906c720527b23ba8c99683ea5f9ea1f9d7749e8c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:48 +0700 Subject: ath9k_hw: fix MAC clock for half/quarter rate Enabling half/quarter rate makes the MAC run at half/quarter clock speed. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a6bb9c4f8a8..f69c62e36ed 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -99,6 +99,13 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah) if (conf_is_ht40(conf)) clockrate *= 2; + if (ah->curchan) { + if (IS_CHAN_HALF_RATE(ah->curchan)) + clockrate /= 2; + if (IS_CHAN_QUARTER_RATE(ah->curchan)) + clockrate /= 4; + } + common->clockrate = clockrate; } -- cgit v1.2.3-70-g09d2 From 087b6ff682ff62c49c9a36ddfd24fc781367b1d1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:49 +0700 Subject: ath9k_hw: fix MAC clock rate for AR9287 v1.3+ This chip uses the async FIFO feature and runs the MAC at 117 MHz Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f69c62e36ed..d4084d89c6f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -87,7 +87,10 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); unsigned int clockrate; - if (!ah->curchan) /* should really check for CCK instead */ + /* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */ + if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) + clockrate = 117; + else if (!ah->curchan) /* should really check for CCK instead */ clockrate = ATH9K_CLOCK_RATE_CCK; else if (conf->channel->band == IEEE80211_BAND_2GHZ) clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; -- cgit v1.2.3-70-g09d2 From b6ba41bb27eb9810d54e2301355ce56fd0e94a1a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:50 +0700 Subject: ath9k_hw: initialize more timing related registers for half/quarter channels Initialize the the clock-to-TSF field of AR_USEC and the SIFS and EIFS time registers based on the clock rate instead of relying on initvals. With those changes, some of the hardcoded AR9287 1.3+ specific overrides can be dropped. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 67 ++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index d4084d89c6f..279d73ac908 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -905,6 +905,13 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, } } +static void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us) +{ + u32 val = ath9k_hw_mac_to_clks(ah, us - 2); + val = min(val, (u32) 0xFFFF); + REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val); +} + static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) { u32 val = ath9k_hw_mac_to_clks(ah, us); @@ -942,25 +949,60 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) void ath9k_hw_init_global_settings(struct ath_hw *ah) { - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &common->hw->conf; + const struct ath9k_channel *chan = ah->curchan; int acktimeout; int slottime; int sifstime; + int rx_lat = 0, tx_lat = 0, eifs = 0; + u32 reg; ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", ah->misc_mode); + if (!chan) + return; + if (ah->misc_mode != 0) REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode); - if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) - sifstime = 16; - else - sifstime = 10; + rx_lat = 37; + tx_lat = 54; + + if (IS_CHAN_HALF_RATE(chan)) { + eifs = 175; + rx_lat *= 2; + tx_lat *= 2; + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + tx_lat += 11; + + slottime = 13; + sifstime = 32; + } else if (IS_CHAN_QUARTER_RATE(chan)) { + eifs = 340; + rx_lat *= 4; + tx_lat *= 4; + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + tx_lat += 22; + + slottime = 21; + sifstime = 64; + } else { + eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS); + reg = REG_READ(ah, AR_USEC); + rx_lat = MS(reg, AR_USEC_RX_LAT); + tx_lat = MS(reg, AR_USEC_TX_LAT); + + slottime = ah->slottime; + if (IS_CHAN_5GHZ(chan)) + sifstime = 16; + else + sifstime = 10; + } /* As defined by IEEE 802.11-2007 17.3.8.6 */ - slottime = ah->slottime + 3 * ah->coverage_class; - acktimeout = slottime + sifstime; + acktimeout = slottime + sifstime + 3 * ah->coverage_class; /* * Workaround for early ACK timeouts, add an offset to match the @@ -972,11 +1014,20 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) acktimeout += 64 - sifstime - ah->slottime; - ath9k_hw_setslottime(ah, ah->slottime); + ath9k_hw_set_sifs_time(ah, sifstime); + ath9k_hw_setslottime(ah, slottime); ath9k_hw_set_ack_timeout(ah, acktimeout); ath9k_hw_set_cts_timeout(ah, acktimeout); if (ah->globaltxtimeout != (u32) -1) ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); + + REG_WRITE(ah, AR_D_GBL_IFS_EIFS, ath9k_hw_mac_to_clks(ah, eifs)); + REG_RMW(ah, AR_USEC, + (common->clockrate - 1) | + SM(rx_lat, AR_USEC_RX_LAT) | + SM(tx_lat, AR_USEC_TX_LAT), + AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC); + } EXPORT_SYMBOL(ath9k_hw_init_global_settings); -- cgit v1.2.3-70-g09d2 From fe2b6afbce05abe90d31651d3b92c88e0abc5ecb Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:51 +0700 Subject: ath9k_hw: remove ar9287 v1.3+ specific hardcoded register hacks Now that the clock rate is initialized properly and SIFS, EIFS, USEC, slot time and ACK timeout are properly calculated by the generic code, the 'async FIFO' register hacks are no longer necessary. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 39 ------------------------------ drivers/net/wireless/ath/ath9k/hw.c | 10 +++++--- drivers/net/wireless/ath/ath9k/hw.h | 2 -- drivers/net/wireless/ath/ath9k/reg.h | 5 ---- 4 files changed, 7 insertions(+), 49 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f344cc2b3d5..9ff7c30573b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -499,45 +499,6 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah) } } -/* - * If Async FIFO is enabled, the following counters change as MAC now runs - * at 117 Mhz instead of 88/44MHz when async FIFO is disabled. - * - * The values below tested for ht40 2 chain. - * Overwrite the delay/timeouts initialized in process ini. - */ -void ar9002_hw_update_async_fifo(struct ath_hw *ah) -{ - if (AR_SREV_9287_13_OR_LATER(ah)) { - REG_WRITE(ah, AR_D_GBL_IFS_SIFS, - AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); - REG_WRITE(ah, AR_D_GBL_IFS_SLOT, - AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR); - REG_WRITE(ah, AR_D_GBL_IFS_EIFS, - AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR); - - REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR); - REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR); - - REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER, - AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768); - REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN, - AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL); - } -} - -/* - * We don't enable WEP aggregation on mac80211 but we keep this - * around for HAL unification purposes. - */ -void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah) -{ - if (AR_SREV_9287_13_OR_LATER(ah)) { - REG_SET_BIT(ah, AR_PCU_MISC_MODE2, - AR_PCU_MISC_MODE2_ENABLE_AGGWEP); - } -} - /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ void ar9002_hw_attach_ops(struct ath_hw *ah) { diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 279d73ac908..2a5f908d803 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1631,9 +1631,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_init_global_settings(ah); - if (!AR_SREV_9300_20_OR_LATER(ah)) { - ar9002_hw_update_async_fifo(ah); - ar9002_hw_enable_wep_aggregation(ah); + if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { + REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER, + AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768); + REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN, + AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL); + REG_SET_BIT(ah, AR_PCU_MISC_MODE2, + AR_PCU_MISC_MODE2_ENABLE_AGGWEP); } REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a1c317455bc..6acd0f975ae 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -985,8 +985,6 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); int ar9002_hw_rf_claim(struct ath_hw *ah); void ar9002_hw_enable_async_fifo(struct ath_hw *ah); -void ar9002_hw_update_async_fifo(struct ath_hw *ah); -void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah); /* * Code specific to AR9003, we stuff these here to avoid callbacks diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index a4833880acc..759b72cca3c 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -600,7 +600,6 @@ #define AR_D_GBL_IFS_SIFS 0x1030 #define AR_D_GBL_IFS_SIFS_M 0x0000FFFF -#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB #define AR_D_GBL_IFS_SIFS_RESV0 0xFFFFFFFF #define AR_D_TXBLK_BASE 0x1038 @@ -616,12 +615,10 @@ #define AR_D_GBL_IFS_SLOT 0x1070 #define AR_D_GBL_IFS_SLOT_M 0x0000FFFF #define AR_D_GBL_IFS_SLOT_RESV0 0xFFFF0000 -#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420 #define AR_D_GBL_IFS_EIFS 0x10b0 #define AR_D_GBL_IFS_EIFS_M 0x0000FFFF #define AR_D_GBL_IFS_EIFS_RESV0 0xFFFF0000 -#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000A5EB #define AR_D_GBL_IFS_MISC 0x10f0 #define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007 @@ -1477,7 +1474,6 @@ enum { #define AR_TIME_OUT_ACK_S 0 #define AR_TIME_OUT_CTS 0x3FFF0000 #define AR_TIME_OUT_CTS_S 16 -#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001D56 #define AR_RSSI_THR 0x8018 #define AR_RSSI_THR_MASK 0x000000FF @@ -1493,7 +1489,6 @@ enum { #define AR_USEC_TX_LAT_S 14 #define AR_USEC_RX_LAT 0x1F800000 #define AR_USEC_RX_LAT_S 23 -#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074 #define AR_RESET_TSF 0x8020 #define AR_RESET_TSF_ONCE 0x01000000 -- cgit v1.2.3-70-g09d2 From 0407cf1c7f0fdbecab7efbd8214ac2d1196a67f9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:52 +0700 Subject: ath9k_hw: set 5 GHz half/quarter channels on AR9002 using fractional mode The radio seems to perform better that way Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index abc2cc8cefb..ac8b35c5fa0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -111,7 +111,9 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) { case 0: - if ((freq % 20) == 0) + if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) + aModeRefSel = 0; + else if ((freq % 20) == 0) aModeRefSel = 3; else if ((freq % 10) == 0) aModeRefSel = 2; -- cgit v1.2.3-70-g09d2 From 7d865c7080b3cb9d95eaf7d40343712e582fc3e7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:53 +0700 Subject: ath9k_hw: fix synth delay for half/quarter channels The radio needs twice / four times as much time to stabilize for half/quarter channels. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 441bb33f17a..fac2c6da6ca 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -627,6 +627,11 @@ static void ar5008_hw_init_bb(struct ath_hw *ah, else synthDelay /= 10; + if (IS_CHAN_HALF_RATE(chan)) + synthDelay *= 2; + else if (IS_CHAN_QUARTER_RATE(chan)) + synthDelay *= 4; + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); udelay(synthDelay + BASE_ACTIVATE_DELAY); -- cgit v1.2.3-70-g09d2 From 21394754bcca59aeb4a0b74c95c0220bb727808f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Jul 2011 11:12:54 +0700 Subject: ath9k_hw: add a missing delay for an analog register AR_AN_SYNTH9 is in the analog shift register range and thus needs to be written using the ath9k_hw_analog_shift_rmw function. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index ac8b35c5fa0..3cbbb033fce 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -131,8 +131,9 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) channelSel = CHANSEL_5G(freq); /* RefDivA setting */ - REG_RMW_FIELD(ah, AR_AN_SYNTH9, - AR_AN_SYNTH9_REFDIVA, refDivA); + ath9k_hw_analog_shift_rmw(ah, AR_AN_SYNTH9, + AR_AN_SYNTH9_REFDIVA, + AR_AN_SYNTH9_REFDIVA_S, refDivA); } -- cgit v1.2.3-70-g09d2 From 86fbe17d7f0856f4111e1ceaf3f5c399315fb4e7 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sat, 9 Jul 2011 00:17:45 -0400 Subject: ath5k: validate mode in ath5k_ani_init() before trying to set it Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ani.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index a08f17318e6..b88d10c3b9e 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -630,6 +630,11 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode) if (ah->ah_version < AR5K_AR5212) return; + if (mode < ATH5K_ANI_MODE_OFF || mode > ATH5K_ANI_MODE_AUTO) { + ATH5K_ERR(ah->ah_sc, "ANI mode %d out of range", mode); + return; + } + /* clear old state information */ memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state)); -- cgit v1.2.3-70-g09d2 From 6a2a0e738225fc9ec063f84b79f0adf5c0ed176c Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sat, 9 Jul 2011 00:17:51 -0400 Subject: ath5k: fix typos, bad comment formatting and GHz in place of MHz Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ani.c | 2 +- drivers/net/wireless/ath/ath5k/ath5k.h | 26 ++++++++--------- drivers/net/wireless/ath/ath5k/attach.c | 4 +-- drivers/net/wireless/ath/ath5k/base.c | 14 ++++----- drivers/net/wireless/ath/ath5k/base.h | 4 +-- drivers/net/wireless/ath/ath5k/caps.c | 4 +-- drivers/net/wireless/ath/ath5k/desc.h | 4 +-- drivers/net/wireless/ath/ath5k/dma.c | 6 ++-- drivers/net/wireless/ath/ath5k/eeprom.c | 8 ++--- drivers/net/wireless/ath/ath5k/eeprom.h | 10 +++---- drivers/net/wireless/ath/ath5k/initvals.c | 2 +- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 4 +-- drivers/net/wireless/ath/ath5k/pci.c | 12 ++++---- drivers/net/wireless/ath/ath5k/pcu.c | 12 ++++---- drivers/net/wireless/ath/ath5k/phy.c | 18 ++++++------ drivers/net/wireless/ath/ath5k/reg.h | 42 +++++++++++++-------------- drivers/net/wireless/ath/ath5k/reset.c | 10 +++---- drivers/net/wireless/ath/ath5k/rfgain.h | 6 ++-- 18 files changed, 94 insertions(+), 94 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index b88d10c3b9e..2f0b967a6d8 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -74,7 +74,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) static const s8 fr[] = { -78, -80 }; #endif if (level < 0 || level >= ARRAY_SIZE(sz)) { - ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range", + ATH5K_ERR(ah->ah_sc, "noise immunity level %d out of range", level); return; } diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index b1de4a09c8c..50d75803612 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -18,9 +18,9 @@ #ifndef _ATH5K_H #define _ATH5K_H -/* TODO: Clean up channel debuging -doesn't work anyway- and start +/* TODO: Clean up channel debugging (doesn't work anyway) and start * working on reg. control code using all available eeprom information - * -rev. engineering needed- */ + * (rev. engineering needed) */ #define CHAN_DEBUG 0 #include @@ -156,7 +156,7 @@ } while (0) /* - * Some tuneable values (these should be changeable by the user) + * Some tunable values (these should be changeable by the user) * TODO: Make use of them and add more options OR use debug/configfs */ #define AR5K_TUNE_DMA_BEACON_RESP 2 @@ -171,8 +171,8 @@ #define AR5K_TUNE_RSSI_THRES 129 /* This must be set when setting the RSSI threshold otherwise it can * prevent a reset. If AR5K_RSSI_THR is read after writing to it - * the BMISS_THRES will be seen as 0, seems harware doesn't keep - * track of it. Max value depends on harware. For AR5210 this is just 7. + * the BMISS_THRES will be seen as 0, seems hardware doesn't keep + * track of it. Max value depends on hardware. For AR5210 this is just 7. * For AR5211+ this seems to be up to 255. */ #define AR5K_TUNE_BMISS_THRES 7 #define AR5K_TUNE_REGISTER_DWELL_TIME 20000 @@ -380,7 +380,7 @@ struct ath5k_srev_name { * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s * signaling rate achieved through the bonding of two 54Mbit/s 802.11g - * channels. To use this feature your Access Point must also suport it. + * channels. To use this feature your Access Point must also support it. * There is also a distinction between "static" and "dynamic" turbo modes: * * - Static: is the dumb version: devices set to this mode stick to it until @@ -496,7 +496,7 @@ enum ath5k_tx_queue { */ enum ath5k_tx_queue_subtype { AR5K_WME_AC_BK = 0, /*Background traffic*/ - AR5K_WME_AC_BE, /*Best-effort (normal) traffic)*/ + AR5K_WME_AC_BE, /*Best-effort (normal) traffic*/ AR5K_WME_AC_VI, /*Video traffic*/ AR5K_WME_AC_VO, /*Voice traffic*/ }; @@ -690,7 +690,7 @@ struct ath5k_gain { #define CHANNEL_MODES CHANNEL_ALL /* - * Used internaly for reset_tx_queue). + * Used internally for ath5k_hw_reset_tx_queue(). * Also see struct struct ieee80211_channel. */ #define IS_CHAN_XR(_c) ((_c->hw_value & CHANNEL_XR) != 0) @@ -712,7 +712,7 @@ struct ath5k_athchan_2ghz { \******************/ /** - * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32. + * Seems the ar5xxx hardware supports up to 32 rates, indexed by 1-32. * * The rate code is used to get the RX rate or set the TX rate on the * hardware descriptors. It is also used for internal modulation control @@ -802,7 +802,7 @@ extern int ath5k_modparam_nohwcrypt; * http://www.freepatentsonline.com/20030225739.html * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors). * Note that Rx overrun is not always fatal, on some chips we can continue - * operation without reseting the card, that's why int_fatal is not + * operation without resetting the card, that's why int_fatal is not * common for all chips. * @AR5K_INT_TX: mask to identify received frame interrupts, of type * AR5K_ISR_TXOK or AR5K_ISR_TXERR @@ -832,13 +832,13 @@ extern int ath5k_modparam_nohwcrypt; * AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR. * @AR5K_INT_GLOBAL: Used to clear and set the IER * @AR5K_INT_NOCARD: signals the card has been removed - * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same + * @AR5K_INT_COMMON: common interrupts shared among MACs with the same * bit value * * These are mapped to take advantage of some common bits * between the MACs, to be able to set intr properties * easier. Some of them are not used yet inside hw.c. Most map - * to the respective hw interrupt value as they are common amogst different + * to the respective hw interrupt value as they are common among different * MACs. */ enum ath5k_int { @@ -1358,7 +1358,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 mode, bool fast); /* - * Functions used internaly + * Functions used internally */ static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah) diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index d6fbb57a5d9..14dc52e4b50 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -244,7 +244,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) } - /* Return on unsuported chips (unsupported eeprom etc) */ + /* Return on unsupported chips (unsupported eeprom etc) */ if ((srev >= AR5K_SREV_AR5416) && (srev < AR5K_SREV_AR2425)) { ATH5K_ERR(sc, "Device not yet supported.\n"); ret = -ENODEV; @@ -285,7 +285,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES); ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES); - /* If serdes programing is enabled, increase PCI-E + /* If serdes programming is enabled, increase PCI-E * tx power for systems with long trace from host * to minicard connector. */ if (ee->ee_serdes) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 28113e023c6..3e5e9b73f1a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -531,7 +531,7 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, if (iter_data.n_stas > 1) { /* If you have multiple STA interfaces connected to * different APs, ARPs are not received (most of the time?) - * Enabling PROMISC appears to fix that probem. + * Enabling PROMISC appears to fix that problem. */ sc->filter_flags |= AR5K_RX_FILTER_PROM; } @@ -1349,7 +1349,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, * timestamp (beginning of phy frame, data frame, end of rx?). * The only thing we know is that it is hardware specific... * On AR5213 it seems the rx timestamp is at the end of the - * frame, but i'm not sure. + * frame, but I'm not sure. * * NOTE: mac80211 defines mactime at the beginning of the first * data symbol. Since we don't have any time references it's @@ -1764,7 +1764,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) * 4 beacons to make sure everybody hears our AP. * When a client tries to associate, hw will keep * track of the tx antenna to be used for this client - * automaticaly, based on ACKed packets. + * automatically, based on ACKed packets. * * Note: AP still listens and transmits RTS on the * default antenna which is supposed to be an omni. @@ -2099,11 +2099,11 @@ static void ath5k_tasklet_beacon(unsigned long data) * * In IBSS mode we use this interrupt just to * keep track of the next TBTT (target beacon - * transmission time) in order to detect wether + * transmission time) in order to detect whether * automatic TSF updates happened. */ if (sc->opmode == NL80211_IFTYPE_ADHOC) { - /* XXX: only if VEOL suppported */ + /* XXX: only if VEOL supported */ u64 tsf = ath5k_hw_get_tsf64(sc->ah); sc->nexttbtt += sc->bintval; ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, @@ -2466,7 +2466,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) sc->ah->ah_radio_5ghz_revision), sc->ah->ah_radio_5ghz_revision); /* No 2GHz support (5110 and some - * 5Ghz only cards) -> report 5Ghz radio */ + * 5GHz only cards) -> report 5GHz radio */ } else if (!test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) { ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", @@ -2796,7 +2796,7 @@ ath5k_init(struct ieee80211_hw *hw) /* * Collect the channel list. The 802.11 layer - * is resposible for filtering this list based + * is responsible for filtering this list based * on settings like the phy mode and regulatory * domain restrictions. */ diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index e71494ee329..0a98777b937 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -121,7 +121,7 @@ struct ath5k_statistics { /* frame errors */ unsigned int rx_all_count; /* all RX frames, including errors */ unsigned int tx_all_count; /* all TX frames, including errors */ - unsigned int rx_bytes_count; /* all RX bytes, including errored pks + unsigned int rx_bytes_count; /* all RX bytes, including errored pkts * and the MAC headers for each packet */ unsigned int tx_bytes_count; /* all TX bytes, including errored pkts @@ -250,7 +250,7 @@ struct ath5k_softc { unsigned int nexttbtt; /* next beacon time in TU */ struct ath5k_txq *cabq; /* content after beacon */ - int power_level; /* Requested tx power in dbm */ + int power_level; /* Requested tx power in dBm */ bool assoc; /* associate state */ bool enable_beacon; /* true if beacons are on */ diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index 7dd88e1c3ff..c752982aec0 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c @@ -52,8 +52,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) __set_bit(AR5K_MODE_11A, caps->cap_mode); } else { /* - * XXX The tranceiver supports frequencies from 4920 to 6100GHz - * XXX and from 2312 to 2732GHz. There are problems with the + * XXX The transceiver supports frequencies from 4920 to 6100MHz + * XXX and from 2312 to 2732MHz. There are problems with the * XXX current ieee80211 implementation because the IEEE * XXX channel mapping does not support negative channel * XXX numbers (2312MHz is channel -19). Of course, this diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h index 2509d0bf037..cfd529b548f 100644 --- a/drivers/net/wireless/ath/ath5k/desc.h +++ b/drivers/net/wireless/ath/ath5k/desc.h @@ -58,11 +58,11 @@ struct ath5k_hw_rx_status { #define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 /* reception success */ #define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 /* CRC error */ #define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210 0x00000008 /* [5210] FIFO overrun */ -#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 /* decyption CRC failure */ +#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 /* decryption CRC failure */ #define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 /* PHY error */ #define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5 #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 /* key index valid */ -#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 /* decyption key index */ +#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 /* decryption key index */ #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9 #define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 /* 13 bit of TSF */ #define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15 diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 02e2e3f71b0..b788ecfbdaf 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -25,7 +25,7 @@ * * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and * handle queue setup for 5210 chipset (rest are handled on qcu.c). - * Also we setup interrupt mask register (IMR) and read the various iterrupt + * Also we setup interrupt mask register (IMR) and read the various interrupt * status registers (ISR). * * TODO: Handle SISR on 5211+ and introduce a function to return the queue @@ -726,7 +726,7 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask) int_mask |= AR5K_IMR_RXDOPPLER; /* Note: Per queue interrupt masks - * are set via reset_tx_queue (qcu.c) */ + * are set via ath5k_hw_reset_tx_queue() (qcu.c) */ ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR); ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2); @@ -783,7 +783,7 @@ void ath5k_hw_dma_init(struct ath5k_hw *ah) * for all PCI-E cards to be safe). * * XXX: need to check 5210 for this - * TODO: Check out tx triger level, it's always 64 on dumps but I + * TODO: Check out tx trigger level, it's always 64 on dumps but I * guess we can tweak it and see how it goes ;-) */ if (ah->ah_version != AR5K_AR5210) { diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index f97a540e219..d9e605e3700 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -634,7 +634,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) /* Used to match PCDAC steps with power values on RF5111 chips * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC * steps that match with the power values we read from eeprom. On - * older eeprom versions (< 3.2) these steps are equaly spaced at + * older eeprom versions (< 3.2) these steps are equally spaced at * 10% of the pcdac curve -until the curve reaches its maximum- * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) * these 11 steps are spaced in a different way. This function returns @@ -764,7 +764,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, /* Fill raw dataset * (convert power to 0.25dB units - * for RF5112 combatibility) */ + * for RF5112 compatibility) */ for (point = 0; point < pd->pd_points; point++) { /* Absolute values */ @@ -884,7 +884,7 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) * Read power calibration for RF5112 chips * * For RF5112 we have 4 XPD -eXternal Power Detector- curves - * for each calibrated channel on 0, -6, -12 and -18dbm but we only + * for each calibrated channel on 0, -6, -12 and -18dBm but we only * use the higher (3) and the lower (0) curves. Each curve has 0.5dB * power steps on x axis and PCDAC steps on y axis and looks like a * linear function. To recreate the curve and pass the power values @@ -1241,7 +1241,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, /* Fill raw dataset * convert all pwr levels to - * quarter dB for RF5112 combatibility */ + * quarter dB for RF5112 compatibility */ pd->pd_step[0] = pcinfo->pddac_i[pdg]; pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg]; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 6d440e0ba14..dc2bcfeadeb 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -50,7 +50,7 @@ #define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */ #define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */ -#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */ +#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2GHz (ar5211_rfregs) */ #define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */ #define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */ #define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */ @@ -75,11 +75,11 @@ #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) -#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz */ +#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2GHz */ #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for < 2W power consumption */ #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) /* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */ #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ -#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ +#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5GHz */ /* Newer EEPROMs are using a different offset */ #define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \ @@ -120,7 +120,7 @@ #define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) /* disable fast frames */ #define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) /* disable bursting */ #define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) /* max number of QCUs. defaults to 10 */ -#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heayy clipping */ +#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heavy clipping */ #define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) /* key cache size. defaults to 128 */ #define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) @@ -270,7 +270,7 @@ enum ath5k_ctl_mode { /* Per channel calibration data, used for power table setup */ struct ath5k_chan_pcal_info_rf5111 { - /* Power levels in half dbm units + /* Power levels in half dBm units * for one power curve. */ u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111]; /* PCDAC table steps diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c index 4bfdc2e20df..855d1af3e71 100644 --- a/drivers/net/wireless/ath/ath5k/initvals.c +++ b/drivers/net/wireless/ath/ath5k/initvals.c @@ -1409,7 +1409,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu) * Write initial register settings */ - /* For AR5212 and combatible */ + /* For AR5212 and compatible */ if (ah->ah_version == AR5K_AR5212) { /* First set of mode-specific settings */ diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 493908299bb..0d5ab3428be 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -348,7 +348,7 @@ ath5k_prepare_multicast(struct ieee80211_hw *hw, mfilt[pos / 32] |= (1 << (pos % 32)); /* XXX: we might be able to just do this instead, * but not sure, needs testing, if we do use this we'd - * neet to inform below to not reset the mcast */ + * need to inform below not to reset the mcast */ /* ath5k_hw_set_mcast_filterindex(ah, * ha->addr[5]); */ } @@ -471,7 +471,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, if (iter_data.n_stas > 1) { /* If you have multiple STA interfaces connected to * different APs, ARPs are not received (most of the time?) - * Enabling PROMISC appears to fix that probem. + * Enabling PROMISC appears to fix that problem. */ rfilt |= AR5K_RX_FILTER_PROM; } diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index cd60f0a2f0e..aac5b783194 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -34,12 +34,12 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */ { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */ { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */ - { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 compatible */ + { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 compatible */ + { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 compatible */ + { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 compatible */ + { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 compatible */ + { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 compatible */ { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index aecd7241749..618ee54d5fe 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -32,7 +32,7 @@ #include "base.h" /* - * AR5212+ can use higher rates for ack transmition + * AR5212+ can use higher rates for ack transmission * based on current tx rate instead of the base rate. * It does this to better utilize channel usage. * This is a mapping between G rates (that cover both @@ -643,14 +643,14 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) /* Flush any pending BMISS interrupts on ISR by * performing a clear-on-write operation on PISR * register for the BMISS bit (writing a bit on - * ISR togles a reset for that bit and leaves - * the rest bits intact) */ + * ISR toggles a reset for that bit and leaves + * the remaining bits intact) */ if (ah->ah_version == AR5K_AR5210) ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR); else ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR); - /* TODO: Set enchanced sleep registers on AR5212 + /* TODO: Set enhanced sleep registers on AR5212 * based on vif->bss_conf params, until then * disable power save reporting.*/ AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV); @@ -738,7 +738,7 @@ ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval) dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3; /* NOTE: SWBA is different. Having a wrong window there does not - * stop us from sending data and this condition is catched thru + * stop us from sending data and this condition is caught by * other means (SWBA interrupt) */ if (ath5k_check_timer_win(nbtt, atim, 1, intval) && @@ -896,7 +896,7 @@ void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* Set RSSI/BRSSI thresholds * * Note: If we decide to set this value - * dynamicaly, have in mind that when AR5K_RSSI_THR + * dynamically, have in mind that when AR5K_RSSI_THR * register is read it might return 0x40 if we haven't * wrote anything to it plus BMISS RSSI threshold is zeroed. * So doing a save/restore procedure here isn't the right diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 7e2867689e1..e00ab5a6694 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -363,7 +363,7 @@ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah) return 0; } -/* Schedule a gain probe check on the next transmited packet. +/* Schedule a gain probe check on the next transmitted packet. * That means our next packet is going to be sent with lower * tx power and a Peak to Average Power Detector (PAPD) will try * to measure the gain. @@ -620,7 +620,7 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) /* Check if measurement is ok and if we need * to adjust gain, schedule a gain adjustment, - * else switch back to the acive state */ + * else switch back to the active state */ if (ath5k_hw_rf_check_gainf_readback(ah) && AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) && ath5k_hw_rf_gainf_adjust(ah)) { @@ -807,7 +807,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, * use b_OB and b_DB parameters stored * in eeprom on ee->ee_ob[ee_mode][0] * - * For all other chips we use OB/DB for 2Ghz + * For all other chips we use OB/DB for 2GHz * stored in the b/g modal section just like * 802.11a on ee->ee_ob[ee_mode][1] */ if ((ah->ah_radio == AR5K_RF5111) || @@ -1259,7 +1259,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah, { int ret; /* - * Check bounds supported by the PHY (we don't care about regultory + * Check bounds supported by the PHY (we don't care about regulatory * restrictions at this point). Note: hw_value already has the band * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok() * of the band by that */ @@ -1815,7 +1815,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_SPUR_FILT_EN) { - /* Clean up spur mitigation settings and disable fliter */ + /* Clean up spur mitigation settings and disable filter */ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL, AR5K_PHY_BIN_MASK_CTL_RATE, 0); AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ, @@ -2510,8 +2510,8 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, s16 max_pwr_idx; s16 min_pwr_idx; s16 mid_pwr_idx = 0; - /* Edge flag turs on the 7nth bit on the PCDAC - * to delcare the higher power curve (force values + /* Edge flag turns on the 7nth bit on the PCDAC + * to declare the higher power curve (force values * to be greater than 64). If we only have one curve * we don't need to set this, if we have 2 curves and * fill the table backwards this can also be used to @@ -2568,7 +2568,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, } /* Don't go below 1, extrapolate below if we have - * already swithced to the lower power curve -or + * already switched to the lower power curve -or * we only have one curve and edge_flag is zero * anyway */ if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) { @@ -2805,7 +2805,7 @@ ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) /* * This is the main function that uses all of the above * to set PCDAC/PDADC table on hw for the current channel. - * This table is used for tx power calibration on the basband, + * This table is used for tx power calibration on the baseband, * without it we get weird tx power levels and in some cases * distorted spectral mask */ diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 994d29ace34..f5c1000045d 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -170,7 +170,7 @@ #define AR5K_TXCFG_SDMAMR_S 0 #define AR5K_TXCFG_B_MODE 0x00000008 /* Set b mode for 5111 (enable 2111) */ #define AR5K_TXCFG_TXFSTP 0x00000008 /* TX DMA full Stop [5210] */ -#define AR5K_TXCFG_TXFULL 0x000003f0 /* TX Triger level mask */ +#define AR5K_TXCFG_TXFULL 0x000003f0 /* TX Trigger level mask */ #define AR5K_TXCFG_TXFULL_S 4 #define AR5K_TXCFG_TXFULL_0B 0x00000000 #define AR5K_TXCFG_TXFULL_64B 0x00000010 @@ -283,16 +283,16 @@ */ #define AR5K_ISR 0x001c /* Register Address [5210] */ #define AR5K_PISR 0x0080 /* Register Address [5211+] */ -#define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly received */ +#define AR5K_ISR_RXOK 0x00000001 /* Frame successfully received */ #define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */ #define AR5K_ISR_RXERR 0x00000004 /* Receive error */ #define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */ #define AR5K_ISR_RXEOL 0x00000010 /* Empty RX descriptor */ #define AR5K_ISR_RXORN 0x00000020 /* Receive FIFO overrun */ -#define AR5K_ISR_TXOK 0x00000040 /* Frame successfuly transmited */ +#define AR5K_ISR_TXOK 0x00000040 /* Frame successfully transmitted */ #define AR5K_ISR_TXDESC 0x00000080 /* TX descriptor request */ #define AR5K_ISR_TXERR 0x00000100 /* Transmit error */ -#define AR5K_ISR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout) */ +#define AR5K_ISR_TXNOFRM 0x00000200 /* No frame transmitted (transmit timeout) */ #define AR5K_ISR_TXEOL 0x00000400 /* Empty TX descriptor */ #define AR5K_ISR_TXURN 0x00000800 /* Transmit FIFO underrun */ #define AR5K_ISR_MIB 0x00001000 /* Update MIB counters */ @@ -377,16 +377,16 @@ */ #define AR5K_IMR 0x0020 /* Register Address [5210] */ #define AR5K_PIMR 0x00a0 /* Register Address [5211+] */ -#define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly received*/ +#define AR5K_IMR_RXOK 0x00000001 /* Frame successfully received*/ #define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/ #define AR5K_IMR_RXERR 0x00000004 /* Receive error*/ #define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/ #define AR5K_IMR_RXEOL 0x00000010 /* Empty RX descriptor*/ #define AR5K_IMR_RXORN 0x00000020 /* Receive FIFO overrun*/ -#define AR5K_IMR_TXOK 0x00000040 /* Frame successfuly transmited*/ +#define AR5K_IMR_TXOK 0x00000040 /* Frame successfully transmitted*/ #define AR5K_IMR_TXDESC 0x00000080 /* TX descriptor request*/ #define AR5K_IMR_TXERR 0x00000100 /* Transmit error*/ -#define AR5K_IMR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout)*/ +#define AR5K_IMR_TXNOFRM 0x00000200 /* No frame transmitted (transmit timeout)*/ #define AR5K_IMR_TXEOL 0x00000400 /* Empty TX descriptor*/ #define AR5K_IMR_TXURN 0x00000800 /* Transmit FIFO underrun*/ #define AR5K_IMR_MIB 0x00001000 /* Update MIB counters*/ @@ -601,7 +601,7 @@ * QCU misc registers */ #define AR5K_QCU_MISC_BASE 0x09c0 /* Register Address -Queue0 MISC */ -#define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */ +#define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame scheduling mask */ #define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */ #define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */ #define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated */ @@ -653,13 +653,13 @@ * registers [5211+] * * These registers control the various characteristics of each queue - * for 802.11e (WME) combatibility so they go together with + * for 802.11e (WME) compatibility so they go together with * QCU registers in pairs. For each queue we have a QCU mask register, * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c), * a retry limit register (0x1080 - 0x10ac), a channel time register * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and * a sequence number register (0x1140 - 0x116c). It seems that "global" - * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k). + * registers here affect all queues (see use of DCU_GBL_IFS_SLOT in ar5k). * We use the same macros here for easier register access. * */ @@ -779,7 +779,7 @@ * and it's used for generating pseudo-random * number sequences. * - * (If i understand corectly, random numbers are + * (If i understand correctly, random numbers are * used for idle sensing -multiplied with cwmin/max etc-) */ #define AR5K_DCU_GBL_IFS_MISC 0x10f0 /* Register Address */ @@ -1007,7 +1007,7 @@ #define AR5K_PCIE_WAEN 0x407c /* - * PCI-E Serializer/Desirializer + * PCI-E Serializer/Deserializer * registers */ #define AR5K_PCIE_SERDES 0x4080 @@ -1227,7 +1227,7 @@ AR5K_USEC_5210 : AR5K_USEC_5211) #define AR5K_USEC_1 0x0000007f /* clock cycles for 1us */ #define AR5K_USEC_1_S 0 -#define AR5K_USEC_32 0x00003f80 /* clock cycles for 1us while on 32Mhz clock */ +#define AR5K_USEC_32 0x00003f80 /* clock cycles for 1us while on 32MHz clock */ #define AR5K_USEC_32_S 7 #define AR5K_USEC_TX_LATENCY_5211 0x007fc000 #define AR5K_USEC_TX_LATENCY_5211_S 14 @@ -1632,7 +1632,7 @@ #define AR5K_SLEEP0_NEXT_DTIM 0x0007ffff /* Mask for next DTIM (?) */ #define AR5K_SLEEP0_NEXT_DTIM_S 0 #define AR5K_SLEEP0_ASSUME_DTIM 0x00080000 /* Assume DTIM */ -#define AR5K_SLEEP0_ENH_SLEEP_EN 0x00100000 /* Enable enchanced sleep control */ +#define AR5K_SLEEP0_ENH_SLEEP_EN 0x00100000 /* Enable enhanced sleep control */ #define AR5K_SLEEP0_CABTO 0xff000000 /* Mask for CAB Time Out */ #define AR5K_SLEEP0_CABTO_S 24 @@ -1657,7 +1657,7 @@ /* * TX power control (TPC) register * - * XXX: PCDAC steps (0.5dbm) or DBM ? + * XXX: PCDAC steps (0.5dBm) or dBm ? * */ #define AR5K_TXPC 0x80e8 /* Register Address */ @@ -1673,7 +1673,7 @@ /* * Profile count registers * - * These registers can be cleared and freezed with ATH5K_MIBC, but they do not + * These registers can be cleared and frozen with ATH5K_MIBC, but they do not * generate a MIB interrupt. * Instead of overflowing, they shift by one bit to the right. All registers * shift together, i.e. when one reaches the max, all shift at the same time by @@ -1838,7 +1838,7 @@ #define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/ #define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */ #define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */ -#define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */ +#define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32kHz external) */ #define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */ #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */ #define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */ @@ -2002,7 +2002,7 @@ #define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */ #define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ #define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */ -#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ +#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automatically */ /* * PHY noise floor status register (CCA = Clear Channel Assessment) @@ -2089,7 +2089,7 @@ * * It's obvious from the code that 0x989c is the buffer register but * for the other special registers that we write to after sending each - * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers + * packet, i have no idea. So I'll name them BUFFER_CONTROL_X registers * for now. It's interesting that they are also used for some other operations. */ @@ -2340,7 +2340,7 @@ #define AR5K_PHY_RESTART_DIV_GC_S 18 /* - * RF Bus access request register (for synth-oly channel switching) + * RF Bus access request register (for synth-only channel switching) */ #define AR5K_PHY_RFBUS_REQ 0x997C #define AR5K_PHY_RFBUS_REQ_REQUEST 0x00000001 @@ -2382,7 +2382,7 @@ */ #define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */ #define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2)) -#define AR5K_RF_GAIN_BASE 0x9a00 /* RF Amplrifier Gain table base address */ +#define AR5K_RF_GAIN_BASE 0x9a00 /* RF Amplifier Gain table base address */ #define AR5K_RF_GAIN(_n) (AR5K_RF_GAIN_BASE + ((_n) << 2)) /* diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 19aefdb7541..57f2e56bc06 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -213,7 +213,7 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) usec_reg = (usec | sclock | txlat | rxlat); ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC); - /* On 5112 set tx frane to tx data start delay */ + /* On 5112 set tx frame to tx data start delay */ if (ah->ah_radio == AR5K_RF5112) { AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2, AR5K_PHY_RF_CTL2_TXF2TXD_START, @@ -539,7 +539,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) * * Note: putting PCI core on warm reset on PCI-E cards * results card to hang and always return 0xffff... so - * we ingore that flag for PCI-E cards. On PCI cards + * we ignore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. */ bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI; @@ -596,7 +596,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) * * Note: putting PCI core on warm reset on PCI-E cards * results card to hang and always return 0xffff... so - * we ingore that flag for PCI-E cards. On PCI cards + * we ignore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. */ bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI; @@ -627,7 +627,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) return ret; } - /* ...reset configuration regiter on Wisoc ... + /* ...reset configuration register on Wisoc ... * ...clear reset control register and pull device out of * warm reset on others */ if (ath5k_get_bus_type(ah) == ATH_AHB) @@ -704,7 +704,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) /*XXX: Can bwmode be used with dynamic mode ? * (I don't think it supports 44MHz) */ - /* On 2425 initvals TURBO_SHORT is not pressent */ + /* On 2425 initvals TURBO_SHORT is not present */ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { turbo = AR5K_PHY_TURBO_MODE | (ah->ah_radio == AR5K_RF2425) ? 0 : diff --git a/drivers/net/wireless/ath/ath5k/rfgain.h b/drivers/net/wireless/ath/ath5k/rfgain.h index 70c9a45609f..ebfae052d89 100644 --- a/drivers/net/wireless/ath/ath5k/rfgain.h +++ b/drivers/net/wireless/ath/ath5k/rfgain.h @@ -30,7 +30,7 @@ struct ath5k_ini_rfgain { /* Initial RF Gain settings for RF5111 */ static const struct ath5k_ini_rfgain rfgain_5111[] = { - /* 5Ghz 2Ghz */ + /* 5GHz 2GHz */ { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } }, { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } }, { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } }, @@ -99,7 +99,7 @@ static const struct ath5k_ini_rfgain rfgain_5111[] = { /* Initial RF Gain settings for RF5112 */ static const struct ath5k_ini_rfgain rfgain_5112[] = { - /* 5Ghz 2Ghz */ + /* 5GHz 2GHz */ { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } }, { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } }, { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } }, @@ -305,7 +305,7 @@ static const struct ath5k_ini_rfgain rfgain_2316[] = { /* Initial RF Gain settings for RF5413 */ static const struct ath5k_ini_rfgain rfgain_5413[] = { - /* 5Ghz 2Ghz */ + /* 5GHz 2GHz */ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } }, { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } }, -- cgit v1.2.3-70-g09d2 From edcc3604805b37344d0569b61a34dbe22943ba9f Mon Sep 17 00:00:00 2001 From: Olivier Sobrie Date: Sat, 9 Jul 2011 12:57:05 +0200 Subject: libertas: fix errors in functions accessing module registers Problems located in the two functions lbs_set_reg() and lbs_get_reg(): - The offset field of struct cmd_ds_reg_access was not filled in - The test on the return code of lbs_cmd_with_response() in function lbs_get_reg() was inverted Signed-off-by: Olivier Sobrie Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 71c8f3fccfa..3e8123cbb94 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -873,6 +873,7 @@ int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) memset(&cmd, 0, sizeof(cmd)); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_GET); + cmd.offset = cpu_to_le16(offset); if (reg != CMD_MAC_REG_ACCESS && reg != CMD_BBP_REG_ACCESS && @@ -882,7 +883,7 @@ int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) } ret = lbs_cmd_with_response(priv, reg, &cmd); - if (ret) { + if (!ret) { if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) *value = cmd.value.bbp_rf; else if (reg == CMD_MAC_REG_ACCESS) @@ -915,6 +916,7 @@ int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) memset(&cmd, 0, sizeof(cmd)); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_SET); + cmd.offset = cpu_to_le16(offset); if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) cmd.value.bbp_rf = (u8) (value & 0xFF); -- cgit v1.2.3-70-g09d2 From df90d84382b03faf81637db31b6be14f477482c7 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Sat, 9 Jul 2011 15:41:25 +0100 Subject: libertas: fix handling of command timeout, completion and interruption When commands time out, corruption ensues. As lbs_complete_command() is called without locking, the command node is mistakenly freed twice. Also fixed up locking here in a few other places. The nature of command timeout may be that the card didn't even acknowledge receipt of the request. Detect this case and reset dnld_sent so that other commands don't hang forever. When cmdnodes are moved between the free list and the pending list, their list heads should be reinitialized. Fixed this. Sometimes commands are completed without actually submitting them or removing them from cmdpendingq. We must remember to remove them from cmdpendingq in these cases, so handle this in lbs_complete_command(). Harmless signals generated during suspend/resume were interrupting lbs_cmd. Convert to an uninterruptible sleep to avoid this. lbs_thread must be woken up every time there is some new work to do. I found that when 2 commands are queued, ther completion of the first command would not wake up lbs_thread to submit the second. Poke lbs_thread at the end of lbs_complete_command() to fix this. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 42 +++++++++++++++++++++++---------- drivers/net/wireless/libertas/cmd.h | 2 ++ drivers/net/wireless/libertas/cmdresp.c | 6 ++--- drivers/net/wireless/libertas/main.c | 12 ++++++++-- 4 files changed, 45 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 3e8123cbb94..a515a8fd02a 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1069,16 +1069,34 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv, spin_unlock_irqrestore(&priv->driver_lock, flags); } -void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, - int result) +void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, + int result) { + /* + * Normally, commands are removed from cmdpendingq before being + * submitted. However, we can arrive here on alternative codepaths + * where the command is still pending. Make sure the command really + * isn't part of a list at this point. + */ + list_del_init(&cmd->list); + cmd->result = result; cmd->cmdwaitqwoken = 1; - wake_up_interruptible(&cmd->cmdwait_q); + wake_up(&cmd->cmdwait_q); if (!cmd->callback || cmd->callback == lbs_cmd_async_callback) __lbs_cleanup_and_insert_cmd(priv, cmd); priv->cur_cmd = NULL; + wake_up_interruptible(&priv->waitq); +} + +void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, + int result) +{ + unsigned long flags; + spin_lock_irqsave(&priv->driver_lock, flags); + __lbs_complete_command(priv, cmd, result); + spin_unlock_irqrestore(&priv->driver_lock, flags); } int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on) @@ -1250,7 +1268,7 @@ static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) if (!list_empty(&priv->cmdfreeq)) { tempnode = list_first_entry(&priv->cmdfreeq, struct cmd_ctrl_node, list); - list_del(&tempnode->list); + list_del_init(&tempnode->list); } else { lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n"); tempnode = NULL; @@ -1358,10 +1376,7 @@ int lbs_execute_next_command(struct lbs_private *priv) cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { lbs_deb_host( "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); - spin_lock_irqsave(&priv->driver_lock, flags); - list_del(&cmdnode->list); lbs_complete_command(priv, cmdnode, 0); - spin_unlock_irqrestore(&priv->driver_lock, flags); ret = 0; goto done; @@ -1371,10 +1386,7 @@ int lbs_execute_next_command(struct lbs_private *priv) (priv->psstate == PS_STATE_PRE_SLEEP)) { lbs_deb_host( "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n"); - spin_lock_irqsave(&priv->driver_lock, flags); - list_del(&cmdnode->list); lbs_complete_command(priv, cmdnode, 0); - spin_unlock_irqrestore(&priv->driver_lock, flags); priv->needtowakeup = 1; ret = 0; @@ -1386,7 +1398,7 @@ int lbs_execute_next_command(struct lbs_private *priv) } } spin_lock_irqsave(&priv->driver_lock, flags); - list_del(&cmdnode->list); + list_del_init(&cmdnode->list); spin_unlock_irqrestore(&priv->driver_lock, flags); lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", le16_to_cpu(cmd->command)); @@ -1669,7 +1681,13 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command, } might_sleep(); - wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); + + /* + * Be careful with signals here. A signal may be received as the system + * goes into suspend or resume. We do not want this to interrupt the + * command, so we perform an uninterruptible sleep. + */ + wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); spin_lock_irqsave(&priv->driver_lock, flags); ret = cmdnode->result; diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index 7109d6b717e..b280ef7a0ae 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h @@ -59,6 +59,8 @@ int lbs_allocate_cmd_buffer(struct lbs_private *priv); int lbs_free_cmd_buffer(struct lbs_private *priv); int lbs_execute_next_command(struct lbs_private *priv); +void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, + int result); void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, int result); int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len); diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 207fc361db8..7da8949b051 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -165,7 +165,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) lbs_deb_host("CMD_RESP: PS action 0x%X\n", action); } - lbs_complete_command(priv, priv->cur_cmd, result); + __lbs_complete_command(priv, priv->cur_cmd, result); spin_unlock_irqrestore(&priv->driver_lock, flags); ret = 0; @@ -186,7 +186,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) break; } - lbs_complete_command(priv, priv->cur_cmd, result); + __lbs_complete_command(priv, priv->cur_cmd, result); spin_unlock_irqrestore(&priv->driver_lock, flags); ret = -1; @@ -204,7 +204,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) if (priv->cur_cmd) { /* Clean up and Put current command back to cmdfreeq */ - lbs_complete_command(priv, priv->cur_cmd, result); + __lbs_complete_command(priv, priv->cur_cmd, result); } spin_unlock_irqrestore(&priv->driver_lock, flags); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 8c40949cb07..a839de06fa6 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -638,6 +638,14 @@ static void lbs_cmd_timeout_handler(unsigned long data) le16_to_cpu(priv->cur_cmd->cmdbuf->command)); priv->cmd_timed_out = 1; + + /* + * If the device didn't even acknowledge the command, reset the state + * so that we don't block all future commands due to this one timeout. + */ + if (priv->dnld_sent == DNLD_CMD_SENT) + priv->dnld_sent = DNLD_RES_RECEIVED; + wake_up_interruptible(&priv->waitq); out: spin_unlock_irqrestore(&priv->driver_lock, flags); @@ -994,7 +1002,7 @@ void lbs_stop_card(struct lbs_private *priv) list_for_each_entry(cmdnode, &priv->cmdpendingq, list) { cmdnode->result = -ENOENT; cmdnode->cmdwaitqwoken = 1; - wake_up_interruptible(&cmdnode->cmdwait_q); + wake_up(&cmdnode->cmdwait_q); } /* Flush the command the card is currently processing */ @@ -1002,7 +1010,7 @@ void lbs_stop_card(struct lbs_private *priv) lbs_deb_main("clearing current command\n"); priv->cur_cmd->result = -ENOENT; priv->cur_cmd->cmdwaitqwoken = 1; - wake_up_interruptible(&priv->cur_cmd->cmdwait_q); + wake_up(&priv->cur_cmd->cmdwait_q); } lbs_deb_main("done clearing commands\n"); spin_unlock_irqrestore(&priv->driver_lock, flags); -- cgit v1.2.3-70-g09d2 From 1288aa4e80145d9f4196df32f717b4c1cf6aab61 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 9 Jul 2011 13:15:58 -0500 Subject: rtlwifi: rtl8192cu: Fix duplicate if test A typo causes routine rtl92cu_phy_rf6052_set_cck_txpower() to test the same condition twice. The problem was found using cppcheck-1.49, and the proper fix was verified against the pre-mac80211 version of the code. Reported-by: David Binderman Signed-off-by: Larry Finger Cc: stable [back to 2.6.39] Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 1e851aae58d..17a8e962851 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -104,7 +104,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, tx_agc[RF90_PATH_A] = 0x10101010; tx_agc[RF90_PATH_B] = 0x10101010; } else if (rtlpriv->dm.dynamic_txhighpower_lvl == - TXHIGHPWRLEVEL_LEVEL1) { + TXHIGHPWRLEVEL_LEVEL2) { tx_agc[RF90_PATH_A] = 0x00000000; tx_agc[RF90_PATH_B] = 0x00000000; } else{ -- cgit v1.2.3-70-g09d2 From 3ffca4fc404f056ecd79e57515dd7c2670db1fbf Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 10 Jul 2011 02:28:26 -0700 Subject: ath5k: Add missing breaks in switch/case Signed-off-by: Joe Perches Acked-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 62172d58572..f82383b3ed3 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -107,10 +107,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, case AR5K_PKT_TYPE_BEACON: case AR5K_PKT_TYPE_PROBE_RESP: frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; + break; case AR5K_PKT_TYPE_PIFS: frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; + break; default: frame_type = type; + break; } tx_ctl->tx_control_0 |= -- cgit v1.2.3-70-g09d2 From 43bf8c245237b8309153aa39d4e8f1586cf56af0 Mon Sep 17 00:00:00 2001 From: Eduardo Bacchi Kienetz Date: Sun, 10 Jul 2011 17:05:14 +0200 Subject: rt2800usb: Add new device ID for Belkin Belkin's Connect N150 Wireless USB Adapter, model F7D1101 version 2, uses ID 0x945b. Chipset info: rt: 3390, rf: 000b, rev: 3213. I have just bought one, which started to work perfectly after the ID was added through this patch. Signed-off-by: Eduardo Bacchi Kienetz Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 59e77797c0f..507559361d8 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1054,6 +1054,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0586, 0x341e) }, { USB_DEVICE(0x0586, 0x343e) }, #ifdef CONFIG_RT2800USB_RT33XX + /* Belkin */ + { USB_DEVICE(0x050d, 0x945b) }, /* Ralink */ { USB_DEVICE(0x148f, 0x3370) }, { USB_DEVICE(0x148f, 0x8070) }, -- cgit v1.2.3-70-g09d2 From 9dff387046ef20547236b75dd0d095904e4c0779 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 11 Jul 2011 20:14:14 +0530 Subject: ath9k: remove an unnecessary function declaration Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 50 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index e7fe4d9aee7..c04a6c3cac7 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -379,7 +379,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = { }; static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, - struct ieee80211_tx_rate *rate); + struct ieee80211_tx_rate *rate) +{ + int rix = 0, i = 0; + static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; + + if (!(rate->flags & IEEE80211_TX_RC_MCS)) + return rate->idx; + + while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { + rix++; i++; + } + + rix += rate->idx + rate_table->mcs_start; + + if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && + (rate->flags & IEEE80211_TX_RC_SHORT_GI)) + rix = rate_table->info[rix].ht_index; + else if (rate->flags & IEEE80211_TX_RC_SHORT_GI) + rix = rate_table->info[rix].sgi_index; + else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + rix = rate_table->info[rix].cw40index; + + return rix; +} static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, struct ath_rate_priv *ath_rc_priv) @@ -1080,31 +1103,6 @@ static void ath_rc_update_ht(struct ath_softc *sc, } -static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, - struct ieee80211_tx_rate *rate) -{ - int rix = 0, i = 0; - static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; - - if (!(rate->flags & IEEE80211_TX_RC_MCS)) - return rate->idx; - - while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { - rix++; i++; - } - - rix += rate->idx + rate_table->mcs_start; - - if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && - (rate->flags & IEEE80211_TX_RC_SHORT_GI)) - rix = rate_table->info[rix].ht_index; - else if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - rix = rate_table->info[rix].sgi_index; - else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - rix = rate_table->info[rix].cw40index; - - return rix; -} static void ath_rc_tx_status(struct ath_softc *sc, struct ath_rate_priv *ath_rc_priv, -- cgit v1.2.3-70-g09d2 From a67792789868d95d14e46a7b6e0c1f214a6fcfb1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 11 Jul 2011 10:47:39 -0700 Subject: iwlagn: fix warning in testmode attribute table Fix the compile warning cause by [IWL_TM_ATTR_MAX - 1] Reported-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-sv-open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index a322f5e8075..77ed1c295da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -645,7 +645,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) */ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) { - struct nlattr *tb[IWL_TM_ATTR_MAX - 1]; + struct nlattr *tb[IWL_TM_ATTR_MAX]; struct iwl_priv *priv = hw->priv; int result; -- cgit v1.2.3-70-g09d2 From 064b43304ed8ede8e13ff7b4338d09fd37bcffb1 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Sat, 25 Jun 2011 13:18:12 +0000 Subject: igb: Fix lack of flush after register write and before delay Register writes followed by a delay are required to have a flush before the delay in order to commit the values to the register. Without the flush, the code following the delay may not function correctly. Reported-by: Tong Ho Reported-by: Guenter Roeck Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 0f563c8c5ff..493e331d706 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -1735,6 +1735,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) ctrl |= E1000_CTRL_RST; wr32(E1000_CTRL, ctrl); + wrfl(); /* Add delay to insure DEV_RST has time to complete */ if (global_device_reset) -- cgit v1.2.3-70-g09d2 From 4297f99b846942c6068f4ec80585c05ac94e612e Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Wed, 29 Jun 2011 01:16:10 +0000 Subject: igb: Update copyright on all igb driver files. This patch updates the copyright on the igb driver files to 2011. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/Makefile | 2 +- drivers/net/igb/e1000_82575.c | 2 +- drivers/net/igb/e1000_82575.h | 2 +- drivers/net/igb/e1000_defines.h | 2 +- drivers/net/igb/e1000_hw.h | 2 +- drivers/net/igb/e1000_mac.c | 2 +- drivers/net/igb/e1000_mac.h | 2 +- drivers/net/igb/e1000_mbx.c | 2 +- drivers/net/igb/e1000_mbx.h | 2 +- drivers/net/igb/e1000_nvm.c | 2 +- drivers/net/igb/e1000_nvm.h | 2 +- drivers/net/igb/e1000_phy.c | 2 +- drivers/net/igb/e1000_phy.h | 2 +- drivers/net/igb/e1000_regs.h | 2 +- drivers/net/igb/igb.h | 2 +- drivers/net/igb/igb_ethtool.c | 2 +- drivers/net/igb/igb_main.c | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/Makefile b/drivers/net/igb/Makefile index 8372cb9a8c1..c6e4621b626 100644 --- a/drivers/net/igb/Makefile +++ b/drivers/net/igb/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel 82575 PCI-Express Ethernet Linux driver -# Copyright(c) 1999 - 2009 Intel Corporation. +# Copyright(c) 1999 - 2011 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 493e331d706..7b7e1571fa5 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index dd6df349899..fd28d62470e 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 6b80d40110c..446eb5cb25e 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 27153e8d7b1..4519a136717 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index c822904d8a0..2b5ef761d2a 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h index 601be99711c..4927f61fbbc 100644 --- a/drivers/net/igb/e1000_mac.h +++ b/drivers/net/igb/e1000_mac.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c index 78d48c7fa85..74f2f11ac29 100644 --- a/drivers/net/igb/e1000_mbx.c +++ b/drivers/net/igb/e1000_mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_mbx.h b/drivers/net/igb/e1000_mbx.h index bb112fb6c3a..eddb0f83dce 100644 --- a/drivers/net/igb/e1000_mbx.h +++ b/drivers/net/igb/e1000_mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c index 75bf36a4bae..7dcd65cede5 100644 --- a/drivers/net/igb/e1000_nvm.c +++ b/drivers/net/igb/e1000_nvm.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_nvm.h b/drivers/net/igb/e1000_nvm.h index 7f43564c4bc..a2a7ca9fa73 100644 --- a/drivers/net/igb/e1000_nvm.h +++ b/drivers/net/igb/e1000_nvm.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007 Intel Corporation. + Copyright(c) 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index d639706eb3f..e662554c62d 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h index 2cc117705a3..8510797b9d8 100644 --- a/drivers/net/igb/e1000_phy.h +++ b/drivers/net/igb/e1000_phy.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index 958ca3bda48..0990f6d860c 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index f4fa4b1751c..0389ff6ea69 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 1862c97508e..ed63ff4cf6d 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index d6c4bd8438e..f4d82b2859d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2009 Intel Corporation. + Copyright(c) 2007-2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- cgit v1.2.3-70-g09d2 From 2c670b5bd794ef93c81bf8797b7d6393c8453fc6 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Tue, 24 May 2011 06:52:51 +0000 Subject: igb: Add support of SerDes Forced mode for certain hardware This patch changes the serdes link code to support a forced mode for some hardware, based on bit set in EEPROM. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 19 +++++++++++++++++-- drivers/net/igb/e1000_82575.h | 2 ++ drivers/net/igb/e1000_defines.h | 5 +++-- 3 files changed, 22 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 7b7e1571fa5..c0857bdfb03 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -1156,10 +1156,13 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) { u32 ctrl_ext, ctrl_reg, reg; bool pcs_autoneg; + s32 ret_val = E1000_SUCCESS; + u16 data; if ((hw->phy.media_type != e1000_media_type_internal_serdes) && !igb_sgmii_active_82575(hw)) - return 0; + return ret_val; + /* * On the 82575, SerDes loopback mode persists until it is @@ -1203,6 +1206,18 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) /* disable PCS autoneg and support parallel detect only */ pcs_autoneg = false; default: + if (hw->mac.type == e1000_82575 || + hw->mac.type == e1000_82576) { + ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data); + if (ret_val) { + printk(KERN_DEBUG "NVM Read Error\n\n"); + return ret_val; + } + + if (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT) + pcs_autoneg = false; + } + /* * non-SGMII modes only supports a speed of 1000/Full for the * link so it is best to just force the MAC and let the pcs @@ -1250,7 +1265,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) if (!igb_sgmii_active_82575(hw)) igb_force_mac_fc(hw); - return 0; + return ret_val; } /** diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index fd28d62470e..786e110011a 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -243,6 +243,8 @@ struct e1000_adv_tx_context_desc { #define E1000_DTXCTL_MDP_EN 0x0020 #define E1000_DTXCTL_SPOOF_INT 0x0040 +#define E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT (1 << 14) + #define ALL_QUEUES 0xFFFF /* RX packet buffer size defines */ diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 446eb5cb25e..2cd4082c86c 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -437,6 +437,7 @@ #define E1000_RAH_POOL_1 0x00040000 /* Error Codes */ +#define E1000_SUCCESS 0 #define E1000_ERR_NVM 1 #define E1000_ERR_PHY 2 #define E1000_ERR_CONFIG 3 @@ -587,8 +588,8 @@ #define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */ /* NVM Word Offsets */ -#define NVM_ID_LED_SETTINGS 0x0004 -/* For SERDES output amplitude adjustment. */ +#define NVM_COMPAT 0x0003 +#define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */ #define NVM_INIT_CONTROL2_REG 0x000F #define NVM_INIT_CONTROL3_PORT_B 0x0014 #define NVM_INIT_CONTROL3_PORT_A 0x0024 -- cgit v1.2.3-70-g09d2 From 1fc5f0386461dcb3fcbda7a8bcac87f7a822bc56 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 2 Jun 2011 04:28:39 +0000 Subject: ixgbe: Make certain to initialize the fdir_perfect_lock in all cases This fix makes it so that the fdir_perfect_lock is initialized in all cases. This is necessary as the fdir_filter_exit routine will always attempt to take the lock before inspecting the filter table. Reported-by: Ben Greear Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fa671ae0ab6..de307965dfe 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5155,8 +5155,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM) adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; - /* n-tuple support exists, always init our spinlock */ - spin_lock_init(&adapter->fdir_perfect_lock); /* Flow Director hash filters enabled */ adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->atr_sample_rate = 20; @@ -5177,6 +5175,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) break; } + /* n-tuple support exists, always init our spinlock */ + spin_lock_init(&adapter->fdir_perfect_lock); + #ifdef CONFIG_IXGBE_DCB /* Configure DCB traffic classes */ for (j = 0; j < MAX_TRAFFIC_CLASS; j++) { -- cgit v1.2.3-70-g09d2 From 995181b9529adbfecd6882c734ee702b5ed9226c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Jul 2011 10:00:40 +0000 Subject: e1000e: remove e1000_queue_stats struct e1000_queue_stats is not used, lets remove it Signed-off-by: Eric Dumazet Acked-by: Bruce Allan Signed-off-by: David S. Miller --- drivers/net/e1000e/e1000.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index c1e7f943054..e9d6e0ada54 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -199,11 +199,6 @@ enum e1000_boards { board_pch2lan, }; -struct e1000_queue_stats { - u64 packets; - u64 bytes; -}; - struct e1000_ps_page { struct page *page; u64 dma; /* must be u64 - written to hw */ @@ -257,8 +252,6 @@ struct e1000_ring { int set_itr; struct sk_buff *rx_skb_top; - - struct e1000_queue_stats stats; }; /* PHY register snapshot values */ -- cgit v1.2.3-70-g09d2 From bd0d7aa6b20a9e78def76a0ba8c414daf253c295 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 11 Jul 2011 22:15:02 -0700 Subject: drivers/net: static should be at beginning of declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the 'static' keywork is at the beginning of declaration for drivers/net/usb/kalmia.c This gets rid of warnings like warning: ‘static’ is not at beginning of declaration when building with -Wold-style-declaration (and/or -Wextra which also enables it). Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/usb/kalmia.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index a9b6c63d54e..5a6d0f88f43 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -100,13 +100,13 @@ kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len, static int kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr) { - const static char init_msg_1[] = + static const char init_msg_1[] = { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00 }; - const static char init_msg_2[] = + static const char init_msg_2[] = { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x00 }; - const static int buflen = 28; + static const int buflen = 28; char *usb_buf; int status; @@ -239,11 +239,11 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb) * Our task here is to strip off framing, leaving skb with one * data frame for the usbnet framework code to process. */ - const static u8 HEADER_END_OF_USB_PACKET[] = + static const u8 HEADER_END_OF_USB_PACKET[] = { 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 }; - const static u8 EXPECTED_UNKNOWN_HEADER_1[] = + static const u8 EXPECTED_UNKNOWN_HEADER_1[] = { 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 }; - const static u8 EXPECTED_UNKNOWN_HEADER_2[] = + static const u8 EXPECTED_UNKNOWN_HEADER_2[] = { 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 }; int i = 0; -- cgit v1.2.3-70-g09d2 From e2270ea62ae4d7a47d6d72942cdb8c669be6357a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Jul 2011 10:37:21 -0700 Subject: netdevice: Kill 'feature' test macros. Almost all of these have long outstayed their welcome. And for every one of these macros, there are 10 features for which we didn't add macros. Let's just delete them all, and get out of habit of doing things this way. Signed-off-by: David S. Miller Acked-by: Stephen Hemminger Acked-by: Arnd Bergmann --- drivers/net/cxgb4vf/cxgb4vf_main.c | 17 ----------------- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 9 --------- drivers/staging/wlags49_h2/wl_internal.h | 7 ------- include/linux/netdevice.h | 12 ------------ net/batman-adv/soft-interface.c | 16 ---------------- 5 files changed, 61 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 8a6f8911bc5..3942a825b3d 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2421,7 +2421,6 @@ static int __devinit enable_msix(struct adapter *adapter) return err; } -#ifdef HAVE_NET_DEVICE_OPS static const struct net_device_ops cxgb4vf_netdev_ops = { .ndo_open = cxgb4vf_open, .ndo_stop = cxgb4vf_stop, @@ -2437,7 +2436,6 @@ static const struct net_device_ops cxgb4vf_netdev_ops = { .ndo_poll_controller = cxgb4vf_poll_controller, #endif }; -#endif /* * "Probe" a device: initialize a device and construct all kernel and driver @@ -2611,22 +2609,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; -#ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops = &cxgb4vf_netdev_ops; -#else - netdev->vlan_rx_register = cxgb4vf_vlan_rx_register; - netdev->open = cxgb4vf_open; - netdev->stop = cxgb4vf_stop; - netdev->hard_start_xmit = t4vf_eth_xmit; - netdev->get_stats = cxgb4vf_get_stats; - netdev->set_rx_mode = cxgb4vf_set_rxmode; - netdev->do_ioctl = cxgb4vf_do_ioctl; - netdev->change_mtu = cxgb4vf_change_mtu; - netdev->set_mac_address = cxgb4vf_set_mac_addr; -#ifdef CONFIG_NET_POLL_CONTROLLER - netdev->poll_controller = cxgb4vf_poll_controller; -#endif -#endif SET_ETHTOOL_OPS(netdev, &cxgb4vf_ethtool_ops); /* diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index b0a4211f43a..3f303ea1433 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -671,7 +671,6 @@ static int ft1000_reset_card(struct net_device *dev) return TRUE; } -#ifdef HAVE_NET_DEVICE_OPS static const struct net_device_ops ftnet_ops = { .ndo_open = &ft1000_open, @@ -679,7 +678,6 @@ static const struct net_device_ops ftnet_ops = .ndo_start_xmit = &ft1000_start_xmit, .ndo_get_stats = &ft1000_netdev_stats, }; -#endif //--------------------------------------------------------------------------- @@ -764,14 +762,7 @@ int init_ft1000_netdev(struct ft1000_device *ft1000dev) INIT_LIST_HEAD(&pInfo->nodes.list); -#ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops = &ftnet_ops; -#else - netdev->hard_start_xmit = &ft1000_start_xmit; - netdev->get_stats = &ft1000_netdev_stats; - netdev->open = &ft1000_open; - netdev->stop = &ft1000_close; -#endif ft1000dev->net = netdev; diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h index cd129b3ee6c..e86aad53b53 100644 --- a/drivers/staging/wlags49_h2/wl_internal.h +++ b/drivers/staging/wlags49_h2/wl_internal.h @@ -990,14 +990,7 @@ struct wl_private #endif // USE_WDS }; // wl_private -#ifdef HAVE_NETDEV_PRIV #define wl_priv(dev) ((struct wl_private *) netdev_priv(dev)) -#else -extern inline struct wl_private *wl_priv(struct net_device *dev) -{ - return dev->priv; -} -#endif /********************************************************************/ /* Locking and synchronization functions */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 011eb89e958..30f17e42c30 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -60,11 +60,6 @@ struct wireless_dev; #define SET_ETHTOOL_OPS(netdev,ops) \ ( (netdev)->ethtool_ops = (ops) ) -#define HAVE_ALLOC_NETDEV /* feature macro: alloc_xxxdev - functions are available. */ -#define HAVE_FREE_NETDEV /* free_netdev() */ -#define HAVE_NETDEV_PRIV /* netdev_priv() */ - /* hardware address assignment types */ #define NET_ADDR_PERM 0 /* address is permanent (default) */ #define NET_ADDR_RANDOM 1 /* address is generated randomly */ @@ -313,7 +308,6 @@ struct header_ops { const void *saddr, unsigned len); int (*parse)(const struct sk_buff *skb, unsigned char *haddr); int (*rebuild)(struct sk_buff *skb); -#define HAVE_HEADER_CACHE int (*cache)(const struct neighbour *neigh, struct hh_cache *hh); void (*cache_update)(struct hh_cache *hh, const struct net_device *dev, @@ -887,7 +881,6 @@ struct netdev_tc_txq { * Must return >0 or -errno if it changed dev->features itself. * */ -#define HAVE_NET_DEVICE_OPS struct net_device_ops { int (*ndo_init)(struct net_device *dev); void (*ndo_uninit)(struct net_device *dev); @@ -1781,8 +1774,6 @@ static inline void input_queue_tail_incr_save(struct softnet_data *sd, DECLARE_PER_CPU_ALIGNED(struct softnet_data, softnet_data); -#define HAVE_NETIF_QUEUE - extern void __netif_schedule(struct Qdisc *q); static inline void netif_schedule_queue(struct netdev_queue *txq) @@ -2058,10 +2049,8 @@ extern void dev_kfree_skb_irq(struct sk_buff *skb); */ extern void dev_kfree_skb_any(struct sk_buff *skb); -#define HAVE_NETIF_RX 1 extern int netif_rx(struct sk_buff *skb); extern int netif_rx_ni(struct sk_buff *skb); -#define HAVE_NETIF_RECEIVE_SKB 1 extern int netif_receive_skb(struct sk_buff *skb); extern gro_result_t dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb); @@ -2241,7 +2230,6 @@ extern void netif_device_attach(struct net_device *dev); /* * Network interface message level settings */ -#define HAVE_NETIF_MSG 1 enum { NETIF_MSG_DRV = 0x0001, diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 3f20332e1d3..3e2f91ffa4e 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -750,7 +750,6 @@ out: return; } -#ifdef HAVE_NET_DEVICE_OPS static const struct net_device_ops bat_netdev_ops = { .ndo_open = interface_open, .ndo_stop = interface_release, @@ -760,7 +759,6 @@ static const struct net_device_ops bat_netdev_ops = { .ndo_start_xmit = interface_tx, .ndo_validate_addr = eth_validate_addr }; -#endif static void interface_setup(struct net_device *dev) { @@ -769,16 +767,7 @@ static void interface_setup(struct net_device *dev) ether_setup(dev); -#ifdef HAVE_NET_DEVICE_OPS dev->netdev_ops = &bat_netdev_ops; -#else - dev->open = interface_open; - dev->stop = interface_release; - dev->get_stats = interface_stats; - dev->set_mac_address = interface_set_mac_addr; - dev->change_mtu = interface_change_mtu; - dev->hard_start_xmit = interface_tx; -#endif dev->destructor = free_netdev; dev->tx_queue_len = 0; @@ -885,13 +874,8 @@ void softif_destroy(struct net_device *soft_iface) int softif_is_valid(const struct net_device *net_dev) { -#ifdef HAVE_NET_DEVICE_OPS if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) return 1; -#else - if (net_dev->hard_start_xmit == interface_tx) - return 1; -#endif return 0; } -- cgit v1.2.3-70-g09d2 From a3d72d5d01b82a86f3b16ca1918d2040b1acba8c Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Tue, 12 Jul 2011 16:10:11 +0000 Subject: e1000e: Add Jumbo Frame support to 82583 devices This patch adds support for the Jumbo Frames feature on 82583 devices. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/82571.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 8295f219243..480f2592f8a 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -431,8 +431,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) adapter->flags &= ~FLAG_HAS_WOL; break; case e1000_82573: - case e1000_82574: - case e1000_82583: if (pdev->device == E1000_DEV_ID_82573L) { adapter->flags |= FLAG_HAS_JUMBO_FRAMES; adapter->max_hw_frame_size = DEFAULT_JUMBO; @@ -2104,10 +2102,11 @@ struct e1000_info e1000_82583_info = { | FLAG_RX_CSUM_ENABLED | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT + | FLAG_HAS_JUMBO_FRAMES | FLAG_HAS_CTRLEXT_ON_LOAD, .flags2 = FLAG2_DISABLE_ASPM_L0S, .pba = 32, - .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, + .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_bm, -- cgit v1.2.3-70-g09d2 From c2fed9965c60e1f989f57889357c557f7b907ab7 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Tue, 12 Jul 2011 16:10:12 +0000 Subject: e1000e: use GFP_KERNEL allocations at init time In process and sleep allowed context, favor GFP_KERNEL allocations over GFP_ATOMIC ones. -v2: fixed checkpatch.pl warnings CC: Eric Dumazet CC: Ben Greear CC: Bruce Allan Signed-off-by: Jeff Kirsher Tested-by: Aaron Brown Signed-off-by: David S. Miller --- drivers/net/e1000e/e1000.h | 2 +- drivers/net/e1000e/netdev.c | 37 +++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index e9d6e0ada54..638d175792c 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -334,7 +334,7 @@ struct e1000_adapter { int *work_done, int work_to_do) ____cacheline_aligned_in_smp; void (*alloc_rx_buf) (struct e1000_adapter *adapter, - int cleaned_count); + int cleaned_count, gfp_t gfp); struct e1000_ring *rx_ring; u32 rx_int_delay; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index ed7a93d356f..4353ad56cf1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -523,7 +523,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, * @adapter: address of board private structure **/ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, - int cleaned_count) + int cleaned_count, gfp_t gfp) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -544,7 +544,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, goto map_skb; } - skb = netdev_alloc_skb_ip_align(netdev, bufsz); + skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp); if (!skb) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; @@ -589,7 +589,7 @@ map_skb: * @adapter: address of board private structure **/ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, - int cleaned_count) + int cleaned_count, gfp_t gfp) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -615,7 +615,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, continue; } if (!ps_page->page) { - ps_page->page = alloc_page(GFP_ATOMIC); + ps_page->page = alloc_page(gfp); if (!ps_page->page) { adapter->alloc_rx_buff_failed++; goto no_buffers; @@ -641,8 +641,9 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, cpu_to_le64(ps_page->dma); } - skb = netdev_alloc_skb_ip_align(netdev, - adapter->rx_ps_bsize0); + skb = __netdev_alloc_skb_ip_align(netdev, + adapter->rx_ps_bsize0, + gfp); if (!skb) { adapter->alloc_rx_buff_failed++; @@ -692,7 +693,7 @@ no_buffers: **/ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, - int cleaned_count) + int cleaned_count, gfp_t gfp) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -713,7 +714,7 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, goto check_page; } - skb = netdev_alloc_skb_ip_align(netdev, bufsz); + skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp); if (unlikely(!skb)) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; @@ -724,7 +725,7 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, check_page: /* allocate a new page if necessary */ if (!buffer_info->page) { - buffer_info->page = alloc_page(GFP_ATOMIC); + buffer_info->page = alloc_page(gfp); if (unlikely(!buffer_info->page)) { adapter->alloc_rx_buff_failed++; break; @@ -888,7 +889,8 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, + GFP_ATOMIC); cleaned_count = 0; } @@ -900,7 +902,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1230,7 +1232,8 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, + GFP_ATOMIC); cleaned_count = 0; } @@ -1244,7 +1247,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1411,7 +1414,8 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, + GFP_ATOMIC); cleaned_count = 0; } @@ -1423,7 +1427,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count); + adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -3105,7 +3109,8 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000_configure_tx(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring)); + adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring), + GFP_KERNEL); } /** -- cgit v1.2.3-70-g09d2 From 1e75896294d282ecd5b1717fcb3f6aa2908d5946 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 12 Jul 2011 22:09:18 -0700 Subject: be2net: account for skb allocation failures If we cannot allocate new skbs in RX completion handler, we should increase netdevice rx_dropped counter, not spam console messages. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_ethtool.c | 1 + drivers/net/benet/be_main.c | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 9aa1534c7d8..72ec00f2d03 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -199,6 +199,7 @@ struct be_rx_stats { u32 rx_polls; /* number of times NAPI called poll function */ u32 rx_events; /* number of ucast rx completion events */ u32 rx_compl; /* number of rx completion entries processed */ + ulong rx_dropped; /* number of skb allocation errors */ ulong rx_jiffies; u64 rx_bytes; u64 rx_bytes_prev; diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 30c1386027f..7fd8130d86e 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -102,6 +102,7 @@ static const struct be_ethtool_stat et_rx_stats[] = { {DRVSTAT_RX_INFO(rx_compl)}, {DRVSTAT_RX_INFO(rx_mcast_pkts)}, {DRVSTAT_RX_INFO(rx_post_fail)}, + {DRVSTAT_RX_INFO(rx_dropped)}, {ERXSTAT_INFO(rx_drops_no_fragments)} }; #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 4ebd7000b0c..f7d6d9de6a0 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -431,6 +431,7 @@ void netdev_stats_update(struct be_adapter *adapter) pkts += rx_stats(rxo)->rx_pkts; bytes += rx_stats(rxo)->rx_bytes; mcast += rx_stats(rxo)->rx_mcast_pkts; + drops += rx_stats(rxo)->rx_dropped; /* no space in linux buffers: best possible approximation */ if (adapter->generation == BE_GEN3) { if (!(lancer_chip(adapter))) { @@ -1181,8 +1182,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN); if (unlikely(!skb)) { - if (net_ratelimit()) - dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); + rxo->stats.rx_dropped++; be_rx_compl_discard(adapter, rxo, rxcp); return; } -- cgit v1.2.3-70-g09d2 From 4c5102f94c175d81790a3a288e85efd4a8a1649a Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Tue, 12 Jul 2011 22:10:01 -0700 Subject: be2net: move to new vlan model Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 - drivers/net/benet/be_main.c | 34 +++++++++------------------------- 2 files changed, 9 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 72ec00f2d03..c85768cd1b1 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -333,7 +333,6 @@ struct be_adapter { u8 eq_next_idx; struct be_drv_stats drv_stats; - struct vlan_group *vlan_grp; u16 vlans_added; u16 max_vlans; /* Number of vlans supported */ u8 vlan_tag[VLAN_N_VID]; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index f7d6d9de6a0..ae2d2622a18 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -654,7 +654,7 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); } - if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); vlan_tag = vlan_tx_tag_get(skb); vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; @@ -847,13 +847,6 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) return status; } -static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - adapter->vlan_grp = grp; -} - static void be_vlan_add_vid(struct net_device *netdev, u16 vid) { struct be_adapter *adapter = netdev_priv(netdev); @@ -872,7 +865,6 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) struct be_adapter *adapter = netdev_priv(netdev); adapter->vlans_added--; - vlan_group_set_device(adapter->vlan_grp, vid, NULL); if (!be_physfn(adapter)) return; @@ -1200,16 +1192,10 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb->rxhash = rxcp->rss_hash; - if (unlikely(rxcp->vlanf)) { - if (!adapter->vlan_grp || adapter->vlans_added == 0) { - kfree_skb(skb); - return; - } - vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, - rxcp->vlan_tag); - } else { - netif_receive_skb(skb); - } + if (unlikely(rxcp->vlanf)) + __vlan_hwaccel_put_tag(skb, rxcp->vlan_tag); + + netif_receive_skb(skb); } /* Process the RX completion indicated by rxcp when GRO is enabled */ @@ -1263,11 +1249,10 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, if (adapter->netdev->features & NETIF_F_RXHASH) skb->rxhash = rxcp->rss_hash; - if (likely(!rxcp->vlanf)) - napi_gro_frags(&eq_obj->napi); - else - vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, - rxcp->vlan_tag); + if (unlikely(rxcp->vlanf)) + __vlan_hwaccel_put_tag(skb, rxcp->vlan_tag); + + napi_gro_frags(&eq_obj->napi); } static void be_parse_rx_compl_v1(struct be_adapter *adapter, @@ -2950,7 +2935,6 @@ static struct net_device_ops be_netdev_ops = { .ndo_set_mac_address = be_mac_addr_set, .ndo_change_mtu = be_change_mtu, .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = be_vlan_register, .ndo_vlan_rx_add_vid = be_vlan_add_vid, .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, .ndo_set_vf_mac = be_set_vf_mac, -- cgit v1.2.3-70-g09d2 From e69dd336ee3a05a589629b505b18ba5e7a5b4c54 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Jul 2011 23:28:12 -0700 Subject: net: Push protocol type directly down to header_ops->cache() Signed-off-by: David S. Miller --- drivers/firewire/net.c | 6 +++--- drivers/isdn/i4l/isdn_net.c | 5 +++-- drivers/net/plip.c | 6 +++--- include/linux/etherdevice.h | 2 +- include/linux/netdevice.h | 2 +- net/core/neighbour.c | 2 +- net/ethernet/eth.c | 3 +-- 7 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index b9762d07198..eced1c25bf5 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -261,16 +261,16 @@ static int fwnet_header_rebuild(struct sk_buff *skb) } static int fwnet_header_cache(const struct neighbour *neigh, - struct hh_cache *hh) + struct hh_cache *hh, __be16 type) { struct net_device *net; struct fwnet_header *h; - if (hh->hh_type == cpu_to_be16(ETH_P_802_3)) + if (type == cpu_to_be16(ETH_P_802_3)) return -1; net = neigh->dev; h = (struct fwnet_header *)((u8 *)hh->hh_data + 16 - sizeof(*h)); - h->h_proto = hh->hh_type; + h->h_proto = type; memcpy(h->h_dest, neigh->ha, net->addr_len); hh->hh_len = FWNET_HLEN; diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 97988111e45..48e9cc0369b 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -1983,13 +1983,14 @@ isdn_net_rebuild_header(struct sk_buff *skb) return ret; } -static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh) +static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh, + __be16 type) { const struct net_device *dev = neigh->dev; isdn_net_local *lp = netdev_priv(dev); if (lp->p_encap == ISDN_NET_ENCAP_ETHER) - return eth_header_cache(neigh, hh); + return eth_header_cache(neigh, hh, type); return -1; } diff --git a/drivers/net/plip.c b/drivers/net/plip.c index ca4df7f4cf2..a9e9ca8a86e 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -152,7 +152,7 @@ static int plip_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, unsigned len); static int plip_hard_header_cache(const struct neighbour *neigh, - struct hh_cache *hh); + struct hh_cache *hh, __be16 type); static int plip_open(struct net_device *dev); static int plip_close(struct net_device *dev); static int plip_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); @@ -1026,11 +1026,11 @@ plip_hard_header(struct sk_buff *skb, struct net_device *dev, } static int plip_hard_header_cache(const struct neighbour *neigh, - struct hh_cache *hh) + struct hh_cache *hh, __be16 type) { int ret; - ret = eth_header_cache(neigh, hh); + ret = eth_header_cache(neigh, hh, type); if (ret == 0) { struct ethhdr *eth; diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index ab68f785fd1..05955cf0993 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -38,7 +38,7 @@ extern int eth_header(struct sk_buff *skb, struct net_device *dev, const void *daddr, const void *saddr, unsigned len); extern int eth_rebuild_header(struct sk_buff *skb); extern int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); -extern int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh); +extern int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type); extern void eth_header_cache_update(struct hh_cache *hh, const struct net_device *dev, const unsigned char *haddr); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 30f17e42c30..564d89fdddd 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -308,7 +308,7 @@ struct header_ops { const void *saddr, unsigned len); int (*parse)(const struct sk_buff *skb, unsigned char *haddr); int (*rebuild)(struct sk_buff *skb); - int (*cache)(const struct neighbour *neigh, struct hh_cache *hh); + int (*cache)(const struct neighbour *neigh, struct hh_cache *hh, __be16 type); void (*cache_update)(struct hh_cache *hh, const struct net_device *dev, const unsigned char *haddr); diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 50bd960983e..8f7e1d8d92a 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1247,7 +1247,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, hh->hh_type = protocol; atomic_set(&hh->hh_refcnt, 2); - if (dev->header_ops->cache(n, hh)) { + if (dev->header_ops->cache(n, hh, protocol)) { kfree(hh); return; } diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 44d2b42fda5..5cffb63f481 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -233,9 +233,8 @@ EXPORT_SYMBOL(eth_header_parse); * @hh: destination cache entry * Create an Ethernet header template from the neighbour. */ -int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh) +int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type) { - __be16 type = hh->hh_type; struct ethhdr *eth; const struct net_device *dev = neigh->dev; -- cgit v1.2.3-70-g09d2 From 30c5f8ecf246997d16ba5b11becc5f10f9deaf7a Mon Sep 17 00:00:00 2001 From: Matvejchikov Ilya Date: Tue, 12 Jul 2011 21:45:37 +0000 Subject: slip: remove redundant NULL-pointer check before calling slhc_free Signed-off-by: Matvejchikov Ilya Signed-off-by: David S. Miller --- drivers/net/slip.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8ec1a9a0bb9..e8c4582d956 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -194,8 +194,7 @@ static int sl_alloc_bufs(struct slip *sl, int mtu) err_exit: #ifdef SL_INCLUDE_CSLIP kfree(cbuff); - if (slcomp) - slhc_free(slcomp); + slhc_free(slcomp); #endif kfree(xbuff); kfree(rbuff); -- cgit v1.2.3-70-g09d2 From e28634d6b229dec216596298c765c203d6b6fa4c Mon Sep 17 00:00:00 2001 From: Matvejchikov Ilya Date: Tue, 12 Jul 2011 21:46:17 +0000 Subject: slip: fix MTU comparation operation when reallocating buffers In sl_realloc_bufs() there is no reason to check if the requested MTU greater than or equal to the current MTU value as this function called only when requested MTU not equals to the current value. So, the ">=" operation can be safely replaced with the ">". Signed-off-by: Matvejchikov Ilya Signed-off-by: David S. Miller --- drivers/net/slip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/slip.c b/drivers/net/slip.c index e8c4582d956..d724d47d254 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -247,7 +247,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) #else if (xbuff == NULL || rbuff == NULL) { #endif - if (mtu >= sl->mtu) { + if (mtu > sl->mtu) { printk(KERN_WARNING "%s: unable to grow slip buffers, MTU change cancelled.\n", dev->name); err = -ENOBUFS; -- cgit v1.2.3-70-g09d2 From 9173a88f46bf53e2fa85337563b39e13c43c7f2e Mon Sep 17 00:00:00 2001 From: Matvejchikov Ilya Date: Tue, 12 Jul 2011 21:46:57 +0000 Subject: slip: remove redundant check slip_devs for NULL As slip_devs is initialized on module load stage there is no reason to check it for NULL anywhere instead of the deinitialization routine because if we can't get enough memory on startup we don't run at all. Signed-off-by: Matvejchikov Ilya Signed-off-by: David S. Miller --- drivers/net/slip.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/slip.c b/drivers/net/slip.c index d724d47d254..6f97c5983c5 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -726,9 +726,6 @@ static struct slip *sl_alloc(dev_t line) struct net_device *dev = NULL; struct slip *sl; - if (slip_devs == NULL) - return NULL; /* Master array missing ! */ - for (i = 0; i < slip_maxdev; i++) { dev = slip_devs[i]; if (dev == NULL) -- cgit v1.2.3-70-g09d2 From 390fd0b388e4f85549e5d60bdeb21364b344d9b9 Mon Sep 17 00:00:00 2001 From: Matvejchikov Ilya Date: Tue, 12 Jul 2011 21:47:38 +0000 Subject: slip: remove dead code within the slip initialization This following code contains a dead "if (dev).." block: ... for (i = 0; i < slip_maxdev; i++) { dev = slip_devs[i]; if (dev == NULL) break; } /* Sorry, too many, all slots in use */ if (i >= slip_maxdev) return NULL; if (dev) { sl = netdev_priv(dev); if (test_bit(SLF_INUSE, &sl->flags)) { unregister_netdevice(dev); dev = NULL; slip_devs[i] = NULL; } } ... The reason is that the code starting with "if (dev).." is never called as when we found an empty slot (dev == NULL) we break the loop and "if (dev).." not works eiter the loop ends and we get out with "i >= slip_maxdev". Signed-off-by: Matvejchikov Ilya Signed-off-by: David S. Miller --- drivers/net/slip.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 6f97c5983c5..11c9ab3b1e1 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -723,6 +723,7 @@ static void sl_sync(void) static struct slip *sl_alloc(dev_t line) { int i; + char name[IFNAMSIZ]; struct net_device *dev = NULL; struct slip *sl; @@ -735,25 +736,12 @@ static struct slip *sl_alloc(dev_t line) if (i >= slip_maxdev) return NULL; - if (dev) { - sl = netdev_priv(dev); - if (test_bit(SLF_INUSE, &sl->flags)) { - unregister_netdevice(dev); - dev = NULL; - slip_devs[i] = NULL; - } - } - - if (!dev) { - char name[IFNAMSIZ]; - sprintf(name, "sl%d", i); - - dev = alloc_netdev(sizeof(*sl), name, sl_setup); - if (!dev) - return NULL; - dev->base_addr = i; - } + sprintf(name, "sl%d", i); + dev = alloc_netdev(sizeof(*sl), name, sl_setup); + if (!dev) + return NULL; + dev->base_addr = i; sl = netdev_priv(dev); /* Initialize channel control data */ -- cgit v1.2.3-70-g09d2 From 851f186835c850cf51001369e4e22c0f9241e745 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 13 Jul 2011 16:10:02 +0100 Subject: sfc: Remove 'Solarstorm' from Kconfig descriptions The 'Solarstorm' brand is being retired and it's redundant with the company name. Signed-off-by: Ben Hutchings --- drivers/net/sfc/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig index a65c9863839..db7b22eb686 100644 --- a/drivers/net/sfc/Kconfig +++ b/drivers/net/sfc/Kconfig @@ -1,5 +1,5 @@ config SFC - tristate "Solarflare Solarstorm SFC4000/SFC9000-family support" + tristate "Solarflare SFC4000/SFC9000-family support" depends on PCI && INET select MDIO select CRC32 @@ -7,13 +7,13 @@ config SFC select I2C_ALGOBIT help This driver supports 10-gigabit Ethernet cards based on - the Solarflare Communications Solarstorm SFC4000 and - SFC9000-family controllers. + the Solarflare Communications SFC4000 and SFC9000-family + controllers. To compile this driver as a module, choose M here. The module will be called sfc. config SFC_MTD - bool "Solarflare Solarstorm SFC4000/SFC9000-family MTD support" + bool "Solarflare SFC4000/SFC9000-family MTD support" depends on SFC && MTD && !(SFC=y && MTD=m) default y help -- cgit v1.2.3-70-g09d2 From 861d9c3f25d216ccbec71a45280eff17fb912434 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 8 Jul 2011 23:20:24 -0700 Subject: iwlegacy: Add missing comma between constant string array Multiple quoted strings are concatenated without comma separators. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl4965-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 46242d2aa5a..14334668034 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -1484,7 +1484,7 @@ static const char * const desc_lookup_text[] = { "NMI_INTERRUPT_DATA_ACTION_PT", "NMI_TRM_HW_ER", "NMI_INTERRUPT_TRM", - "NMI_INTERRUPT_BREAK_POINT" + "NMI_INTERRUPT_BREAK_POINT", "DEBUG_0", "DEBUG_1", "DEBUG_2", -- cgit v1.2.3-70-g09d2 From 2a897d41a30b0af2dbc61c18aa3d2edd9b80fe6a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 8 Jul 2011 23:20:25 -0700 Subject: iwlagn: Add missing comma between constant string array Multiple quoted strings are concatenated without comma separators. Make the array const while there. Signed-off-by: Joe Perches Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3f2b9d6d257..38a1e4f5882 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1565,7 +1565,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) release_firmware(ucode_raw); } -static const char *desc_lookup_text[] = { +static const char * const desc_lookup_text[] = { "OK", "FAIL", "BAD_PARAM", @@ -1589,7 +1589,7 @@ static const char *desc_lookup_text[] = { "NMI_INTERRUPT_DATA_ACTION_PT", "NMI_TRM_HW_ER", "NMI_INTERRUPT_TRM", - "NMI_INTERRUPT_BREAK_POINT" + "NMI_INTERRUPT_BREAK_POINT", "DEBUG_0", "DEBUG_1", "DEBUG_2", -- cgit v1.2.3-70-g09d2 From 0472ade031b5c0c69c21cf96acf64c50eb9ba3c2 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 12 Jul 2011 00:02:56 +0530 Subject: ath9k_hw: Fix incorrect key_miss handling Decryping frames on key_miss handling shouldn't be done for Michael MIC failed frames as h/w would have already decrypted such frames successfully anyway. Also leaving CRC and PHY error(where the frame is going to be dropped anyway), we are left to prcoess Decrypt error for which s/w decrypt is selected anway and so having key_miss as a separate check doesn't serve anything. So making key_miss handling mutually exlusive with other RX status handling makes much more sense. This patch addresses an issue with STA not reporting MIC failure events resulting in STA being disconnected immediately. Cc: stable@kernel.org Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 3 +-- drivers/net/wireless/ath/ath9k/mac.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 575e185f454..8ff0b88a29b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -625,8 +625,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_status |= ATH9K_RXERR_DECRYPT; else if (rxsp->status11 & AR_MichaelErr) rxs->rs_status |= ATH9K_RXERR_MIC; - - if (rxsp->status11 & AR_KeyMiss) + else if (rxsp->status11 & AR_KeyMiss) rxs->rs_status |= ATH9K_RXERR_DECRYPT; } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index c2091f1f409..b6b523a897e 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -645,8 +645,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_status |= ATH9K_RXERR_DECRYPT; else if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; - - if (ads.ds_rxstatus8 & AR_KeyMiss) + else if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_DECRYPT; } -- cgit v1.2.3-70-g09d2 From b613c7262dda30563bb1759573e39392a81524e6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:01:58 +0800 Subject: ath5k: add missing checks for rfgain probe rfgain probe is only necessary for OFDM operation on AR5111 and AR5112. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index e00ab5a6694..3f19e312203 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1604,11 +1604,13 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, int ret; if (ah->ah_radio == AR5K_RF5110) - ret = ath5k_hw_rf5110_calibrate(ah, channel); - else { - ret = ath5k_hw_rf511x_iq_calibrate(ah); + return ath5k_hw_rf5110_calibrate(ah, channel); + + ret = ath5k_hw_rf511x_iq_calibrate(ah); + + if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) && + (channel->hw_value & CHANNEL_OFDM)) ath5k_hw_request_rfgain_probe(ah); - } return ret; } -- cgit v1.2.3-70-g09d2 From ca8bfd94bbe5bd89ff6a4bbf5a050251950cce25 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:01:59 +0800 Subject: ath5k: apply the synth voltage tweak only on AR5112 rev 2 Might fix some stability issues on newer chips Signed-off-by: Felix Fietkau Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 3f19e312203..acf73a04211 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -970,17 +970,20 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, } /* Lower synth voltage on Rev 2 */ - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_HIGH_VC_CP, true); + if (ah->ah_radio == AR5K_RF5112 && + (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) { + ath5k_hw_rfb_op(ah, rf_regs, 2, + AR5K_RF_HIGH_VC_CP, true); - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_MID_VC_CP, true); + ath5k_hw_rfb_op(ah, rf_regs, 2, + AR5K_RF_MID_VC_CP, true); - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_LOW_VC_CP, true); + ath5k_hw_rfb_op(ah, rf_regs, 2, + AR5K_RF_LOW_VC_CP, true); - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_PUSH_UP, true); + ath5k_hw_rfb_op(ah, rf_regs, 2, + AR5K_RF_PUSH_UP, true); + } /* Decrease power consumption on 5213+ BaseBand */ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { -- cgit v1.2.3-70-g09d2 From 2d2cf471d51743c631f216f62a02a62b58126191 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:02:00 +0800 Subject: ath5k: fix reference clock frequency for spur mitigation on AR2413 AR2413 uses the same reference clock as AR5413 Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index acf73a04211..dd2b417729b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -105,6 +105,7 @@ bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, if ((ah->ah_radio == AR5K_RF5112) || (ah->ah_radio == AR5K_RF5413) || + (ah->ah_radio == AR5K_RF2413) || (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) refclk_freq = 40; else -- cgit v1.2.3-70-g09d2 From 26d16d23e621cdc679118ca2fe604752b3a36e9f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:02:01 +0800 Subject: ath5k: initialize common->clockrate Fixes a division by zero when setting distance before activating the device for the first time. Signed-off-by: Felix Fietkau Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3e5e9b73f1a..523bb085450 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2420,6 +2420,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) common->ah = sc->ah; common->hw = hw; common->priv = sc; + common->clockrate = 40; /* * Cache line size is used to size and align various -- cgit v1.2.3-70-g09d2 From fe00deb3e4b50eede61cc7d4ab9bce7911f0a074 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:02:02 +0800 Subject: ath5k: delay full calibration after reset During scans the full calibration usually does not make much sense, PAPD probing and IQ calibration should be deferred until there is enough time to complete them. Adding 100 ms to the initial full calibration delay should be enough to do this. Signed-off-by: Felix Fietkau Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 523bb085450..3b58e008329 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2725,7 +2725,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, ath5k_ani_init(ah, ani_mode); - ah->ah_cal_next_full = jiffies; + ah->ah_cal_next_full = jiffies + msecs_to_jiffies(100); ah->ah_cal_next_ani = jiffies; ah->ah_cal_next_nf = jiffies; ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8); -- cgit v1.2.3-70-g09d2 From f00643888ca435ce6934482243733cc140281d10 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:02:03 +0800 Subject: ath5k: fix reference clock usec duration setting restore enabling the sleep clock alters the AR5K_USEC_32 field, but disabling it didn't restore it. Signed-off-by: Felix Fietkau Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 57f2e56bc06..0e89fc9a75a 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -142,6 +142,7 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) /* Set 32MHz USEC counter */ if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF2413) || (ah->ah_radio == AR5K_RF5413) || (ah->ah_radio == AR5K_RF2316) || (ah->ah_radio == AR5K_RF2317)) @@ -233,7 +234,7 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 scal, spending; + u32 scal, spending, sclock; /* Only set 32KHz settings if we have an external * 32KHz crystal present */ @@ -317,6 +318,15 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) /* Set up tsf increment on each cycle */ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); + + if ((ah->ah_radio == AR5K_RF5112) || + (ah->ah_radio == AR5K_RF5413) || + (ah->ah_radio == AR5K_RF2316) || + (ah->ah_radio == AR5K_RF2317)) + sclock = 40 - 1; + else + sclock = 32 - 1; + AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock); } } -- cgit v1.2.3-70-g09d2 From 6340211c5f4775a52c98052fb5661565f79249fd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:02:04 +0800 Subject: ath5k: disable 32KHz sleep clock operation by default While 32 KHz sleep clock might provide some power saving benefits, it is also a major source of stability issues, on OpenWrt it produced some reproducible data bus errors on register accesses on several different MIPS platforms. All the Atheros drivers that I can find do not enable this feature, so it makes sense to leave it disabled in ath5k as well. Signed-off-by: Felix Fietkau Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 ++ drivers/net/wireless/ath/ath5k/debug.c | 3 +++ drivers/net/wireless/ath/ath5k/reset.c | 11 ++++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 50d75803612..8ff17941bb2 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1067,6 +1067,8 @@ struct ath5k_hw { u8 ah_retry_long; u8 ah_retry_short; + u32 ah_use_32khz_clock; + u8 ah_coverage_class; bool ah_ack_bitrate_high; u8 ah_bwmode; diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index ae1112bfa1c..4edca7072d5 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -922,6 +922,9 @@ ath5k_debug_init_device(struct ath5k_softc *sc) debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc, &fops_queue); + + debugfs_create_bool("32khz_clock", S_IWUSR | S_IRUSR, phydir, + &sc->ah->ah_use_32khz_clock); } /* functions used in other places */ diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 0e89fc9a75a..9f9c2ad3ca6 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -1287,11 +1287,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_dma_init(ah); - /* Enable 32KHz clock function for AR5212+ chips + /* + * Enable 32KHz clock function for AR5212+ chips * Set clocks to 32KHz operation and use an * external 32KHz crystal when sleeping if one - * exists */ - if (ah->ah_version == AR5K_AR5212 && + * exists. + * Disabled by default because it is also disabled in + * other drivers and it is known to cause stability + * issues on some devices + */ + if (ah->ah_use_32khz_clock && ah->ah_version == AR5K_AR5212 && op_mode != NL80211_IFTYPE_AP) ath5k_hw_set_sleep_clock(ah, true); -- cgit v1.2.3-70-g09d2 From 4e868796bbcbae2f2ea3a828c803686787392b71 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Jul 2011 09:02:05 +0800 Subject: ath5k: do not call ieee80211_stop_queue for queues not managed by mac80211 Instead of using ieee80211_stop_queue, check the configured tx queue limit before calling ieee80211_get_buffered_bc. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3b58e008329..5f055d69b22 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1554,7 +1554,8 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, goto drop_packet; } - if (txq->txq_len >= txq->txq_max) + if (txq->txq_len >= txq->txq_max && + txq->qnum <= AR5K_TX_QUEUE_ID_DATA_MAX) ieee80211_stop_queue(hw, txq->qnum); spin_lock_irqsave(&sc->txbuflock, flags); @@ -1930,6 +1931,10 @@ ath5k_beacon_send(struct ath5k_softc *sc) skb = ieee80211_get_buffered_bc(sc->hw, vif); while (skb) { ath5k_tx_queue(sc->hw, skb, sc->cabq); + + if (sc->cabq->txq_len >= sc->cabq->txq_max) + break; + skb = ieee80211_get_buffered_bc(sc->hw, vif); } -- cgit v1.2.3-70-g09d2 From 5d82c53a380ca96421a714481c9113ba54ede609 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 11 Jul 2011 20:04:44 -0700 Subject: mwifiex: add cfg80211 handler for set_bitrate_mask Currently, setting only legacy bitrates on 2.4GHz band are supported. Mode 802.11b/g/bg is enabled based on bitrates selection. If only CCK bitrates selected then 802.11b mode is enabled. If only OFDM bitrates are selected then 802.11g mode is enabled. For both: CCK and OFDM rates 802.11bg mixed mode is enabled. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4487d935654..352d2c5da1f 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -671,6 +671,59 @@ static const u32 mwifiex_cipher_suites[] = { WLAN_CIPHER_SUITE_CCMP, }; +/* + * CFG802.11 operation handler for setting bit rates. + * + * Function selects legacy bang B/G/BG from corresponding bitrates selection. + * Currently only 2.4GHz band is supported. + */ +static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, + const struct cfg80211_bitrate_mask *mask) +{ + struct mwifiex_ds_band_cfg band_cfg; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + int index = 0, mode = 0, i; + + /* Currently only 2.4GHz is supported */ + for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) { + /* + * Rates below 6 Mbps in the table are CCK rates; 802.11b + * and from 6 they are OFDM; 802.11G + */ + if (mwifiex_rates[i].bitrate == 60) { + index = 1 << i; + break; + } + } + + if (mask->control[IEEE80211_BAND_2GHZ].legacy < index) { + mode = BAND_B; + } else { + mode = BAND_G; + if (mask->control[IEEE80211_BAND_2GHZ].legacy % index) + mode |= BAND_B; + } + + memset(&band_cfg, 0, sizeof(band_cfg)); + band_cfg.config_bands = mode; + + if (priv->bss_mode == NL80211_IFTYPE_ADHOC) + band_cfg.adhoc_start_band = mode; + + band_cfg.sec_chan_offset = NO_SEC_CHANNEL; + + if (mwifiex_set_radio_band_cfg(priv, &band_cfg)) + return -EFAULT; + + wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", + (mode & BAND_B) ? "b" : "", + (mode & BAND_G) ? "g" : ""); + + return 0; +} + /* * CFG802.11 operation handler for disconnection request. * @@ -1225,6 +1278,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .set_default_key = mwifiex_cfg80211_set_default_key, .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, .set_tx_power = mwifiex_cfg80211_set_tx_power, + .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, }; /* -- cgit v1.2.3-70-g09d2 From ff79c8ac40a115adf5d94e1349f4a379ae156f55 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 13 Jul 2011 16:21:24 +0100 Subject: sfc: Remove 'Communications' after 'Solarflare' in references to hardware Branding can now be abbreviated. Signed-off-by: Ben Hutchings --- drivers/net/sfc/Kconfig | 3 +-- drivers/net/sfc/efx.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig index db7b22eb686..a3d5bb9e39d 100644 --- a/drivers/net/sfc/Kconfig +++ b/drivers/net/sfc/Kconfig @@ -7,8 +7,7 @@ config SFC select I2C_ALGOBIT help This driver supports 10-gigabit Ethernet cards based on - the Solarflare Communications SFC4000 and SFC9000-family - controllers. + the Solarflare SFC4000 and SFC9000-family controllers. To compile this driver as a module, choose M here. The module will be called sfc. diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index ff162df06bd..faca764aa21 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -2476,7 +2476,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, goto fail1; netif_info(efx, probe, efx->net_dev, - "Solarflare Communications NIC detected\n"); + "Solarflare NIC detected\n"); /* Set up basic I/O (BAR mappings etc) */ rc = efx_init_io(efx); -- cgit v1.2.3-70-g09d2 From c9cab24e954867a03ab833ea3b4c0e6e607eb0d6 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Jul 2011 09:27:27 +0000 Subject: tg3: Detect APE enabled devs earlier The following patch will require the driver to communicate with the APE much sooner than before. This patch make sure the APE registers are memory mapped and that the ENABLE_APE bit is set before the first use. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8211b9a29d6..01d3a271a04 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -13446,10 +13446,15 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) else return; - if (!tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || vpd_vers) + if (vpd_vers) goto done; - tg3_read_mgmtfw_ver(tp); + if (tg3_flag(tp, ENABLE_APE)) { + if (tg3_flag(tp, ENABLE_ASF)) + tg3_read_dash_ver(tp); + } else if (tg3_flag(tp, ENABLE_ASF)) { + tg3_read_mgmtfw_ver(tp); + } done: tp->fw_ver[TG3_VER_SIZE - 1] = 0; @@ -13971,6 +13976,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) PCISTATE_ALLOW_APE_PSPACE_WR; pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); + + tg3_ape_lock_init(tp); } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || @@ -15083,6 +15090,24 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_free_dev; } + if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761E || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761SE || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) { + tg3_flag_set(tp, ENABLE_APE); + tp->aperegs = pci_ioremap_bar(pdev, BAR_2); + if (!tp->aperegs) { + dev_err(&pdev->dev, + "Cannot map APE registers, aborting\n"); + err = -ENOMEM; + goto err_out_iounmap; + } + } + tp->rx_pending = TG3_DEF_RX_RING_PENDING; tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING; @@ -15095,7 +15120,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "Problem fetching invariants of chip, aborting\n"); - goto err_out_iounmap; + goto err_out_apeunmap; } /* The EPB bridge inside 5714, 5715, and 5780 and any @@ -15124,7 +15149,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if (err < 0) { dev_err(&pdev->dev, "Unable to obtain 64 bit " "DMA for consistent allocations\n"); - goto err_out_iounmap; + goto err_out_apeunmap; } } } @@ -15133,7 +15158,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "No usable DMA configuration, aborting\n"); - goto err_out_iounmap; + goto err_out_apeunmap; } } @@ -15198,22 +15223,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "Could not obtain valid ethernet address, aborting\n"); - goto err_out_iounmap; - } - - if (tg3_flag(tp, ENABLE_APE)) { - tp->aperegs = pci_ioremap_bar(pdev, BAR_2); - if (!tp->aperegs) { - dev_err(&pdev->dev, - "Cannot map APE registers, aborting\n"); - err = -ENOMEM; - goto err_out_iounmap; - } - - tg3_ape_lock_init(tp); - - if (tg3_flag(tp, ENABLE_ASF)) - tg3_read_dash_ver(tp); + goto err_out_apeunmap; } /* -- cgit v1.2.3-70-g09d2 From 168212858712b12c65e0fa1bec6c9c65808e7621 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Jul 2011 09:27:28 +0000 Subject: tg3: Move power state transitions to init_one The tg3 driver is going to require memory mapped register access much sooner than before. This patch makes sure the device is in the D0 power state as soon as possible, and moves the code that enables the memory arbiter outside tg3_get_eeprom_hw_cfg() where it can be more easily monitored. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 77 ++++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 43 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 01d3a271a04..ecbc10fed1a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12678,29 +12678,6 @@ static struct subsys_tbl_ent * __devinit tg3_lookup_by_subsys(struct tg3 *tp) static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) { u32 val; - u16 pmcsr; - - /* On some early chips the SRAM cannot be accessed in D3hot state, - * so need make sure we're in D0. - */ - pci_read_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, &pmcsr); - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pci_write_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, pmcsr); - msleep(1); - - /* Make sure register accesses (indirect or otherwise) - * will function correctly. - */ - pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, - tp->misc_host_ctrl); - - /* The memory arbiter has to be enabled in order for SRAM accesses - * to succeed. Normally on powerup the tg3 chip firmware will make - * sure it is enabled, but other entities such as system netboot - * code might disable it. - */ - val = tr32(MEMARB_MODE); - tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); tp->phy_id = TG3_PHY_ID_INVALID; tp->led_ctrl = LED_CTRL_MODE_PHY_1; @@ -13498,14 +13475,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) pci_cmd &= ~PCI_COMMAND_INVALIDATE; pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); - /* It is absolutely critical that TG3PCI_MISC_HOST_CTRL - * has the register indirect write enable bit set before - * we try to access any of the MMIO registers. It is also - * critical that the PCI-X hw workaround situation is decided - * before that as well. + /* Important! -- Make sure register accesses are byteswapped + * correctly. Also, for those chips that require it, make + * sure that indirect register accesses are enabled before + * the first operation. */ pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, &misc_ctrl_reg); + tp->misc_host_ctrl |= (misc_ctrl_reg & + MISC_HOST_CTRL_CHIPREV); + pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, + tp->misc_host_ctrl); tp->pci_chip_rev_id = (misc_ctrl_reg >> MISC_HOST_CTRL_CHIPREV_SHIFT); @@ -13661,12 +13641,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } while (bridge); } - /* Initialize misc host control in PCI block. */ - tp->misc_host_ctrl |= (misc_ctrl_reg & - MISC_HOST_CTRL_CHIPREV); - pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, - tp->misc_host_ctrl); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || @@ -13851,6 +13825,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->pci_lat_timer); } + /* Important! -- It is critical that the PCI-X hw workaround + * situation is decided before the first MMIO register access. + */ if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) { /* 5700 BX chips need to have their TX producer index * mailboxes written twice to workaround a bug. @@ -13957,6 +13934,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701))) tg3_flag_set(tp, SRAM_USE_CONFIG); + /* The memory arbiter has to be enabled in order for SRAM accesses + * to succeed. Normally on powerup the tg3 chip firmware will make + * sure it is enabled, but other entities such as system netboot + * code might disable it. + */ + val = tr32(MEMARB_MODE); + tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); + /* Get eeprom hw config before calling tg3_set_power_state(). * In particular, the TG3_FLAG_IS_NIC flag must be * determined before calling tg3_set_power_state() so that @@ -13987,8 +13972,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tg3_flag(tp, 57765_PLUS)) tg3_flag_set(tp, CPMU_PRESENT); - /* Set up tp->grc_local_ctrl before calling tg3_power_up(). - * GPIO1 driven high will bring 5700's external PHY out of reset. + /* Set up tp->grc_local_ctrl before calling + * tg3_pwrsrc_switch_to_vmain(). GPIO1 driven high + * will bring 5700's external PHY out of reset. * It is also used as eeprom write protect on LOMs. */ tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM; @@ -14017,12 +14003,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GRC_LCLCTRL_GPIO_OUTPUT0; } - /* Force the chip into D0. */ - err = tg3_power_up(tp); - if (err) { - dev_err(&tp->pdev->dev, "Transition to D0 failed\n"); - return err; - } + /* Switch out of Vaux if it is a NIC */ + tg3_pwrsrc_switch_to_vmain(tp); /* Derive initial jumbo mode from MTU assigned in * ether_setup() via the alloc_etherdev() call @@ -15037,11 +15019,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_free_res; } + err = pci_set_power_state(pdev, PCI_D0); + if (err) { + dev_err(&pdev->dev, "Transition to D0 failed, aborting\n"); + goto err_out_free_res; + } + dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS); if (!dev) { dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n"); err = -ENOMEM; - goto err_out_free_res; + goto err_out_power_down; } SET_NETDEV_DEV(dev, &pdev->dev); @@ -15356,6 +15344,9 @@ err_out_iounmap: err_out_free_dev: free_netdev(dev); +err_out_power_down: + pci_set_power_state(pdev, PCI_D3hot); + err_out_free_res: pci_release_regions(pdev); -- cgit v1.2.3-70-g09d2 From bed9829f3ec4b30d5cbec6511a11368ba5f169fb Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Jul 2011 09:27:29 +0000 Subject: tg3: Check transitions to D0 power state Currently pci_set_power_state() does not return useful return codes for transitions to the D0 power state. If a device refuses to go into D0, the PCI layer issues a warning but returns success. Entering into D0 is a requirement for correct operation of tg3 devices though. If the PCI layer should be changed to return an error code for this type of failure, the tg3 driver would be interested in catching it and reacting to it. This patch makes the necessary modifications. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ecbc10fed1a..5d4283e7be7 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2657,14 +2657,19 @@ static void tg3_enable_register_access(struct tg3 *tp) static int tg3_power_up(struct tg3 *tp) { - tg3_enable_register_access(tp); + int err; - pci_set_power_state(tp->pdev, PCI_D0); + tg3_enable_register_access(tp); - /* Switch out of Vaux if it is a NIC */ - tg3_pwrsrc_switch_to_vmain(tp); + err = pci_set_power_state(tp->pdev, PCI_D0); + if (!err) { + /* Switch out of Vaux if it is a NIC */ + tg3_pwrsrc_switch_to_vmain(tp); + } else { + netdev_err(tp->dev, "Transition to D0 failed\n"); + } - return 0; + return err; } static int tg3_power_down_prepare(struct tg3 *tp) @@ -11433,8 +11438,12 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, { struct tg3 *tp = netdev_priv(dev); - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) - tg3_power_up(tp); + if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) && + tg3_power_up(tp)) { + etest->flags |= ETH_TEST_FL_FAILED; + memset(data, 1, sizeof(u64) * TG3_NUM_TEST); + return; + } memset(data, 0, sizeof(u64) * TG3_NUM_TEST); @@ -15571,10 +15580,8 @@ static pci_ers_result_t tg3_io_slot_reset(struct pci_dev *pdev) } err = tg3_power_up(tp); - if (err) { - netdev_err(netdev, "Failed to restore register access.\n"); + if (err) goto done; - } rc = PCI_ERS_RESULT_RECOVERED; -- cgit v1.2.3-70-g09d2 From 69f11c9936ba310ed3620072983da6ed95e86cc0 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Jul 2011 09:27:30 +0000 Subject: tg3: Determine PCI function number in one place tg3 devices will need to know exactly what function number they are so that they can communicate their status to the other functions. In a KVM environment, the function number of a device presented by the kernel might not be the true function number, so an alternative method to determine the function number is needed. This patch used to contain an implementation for the alternative method, but recently we discovered a hardware bug that renders it incorrect. While new method is not yet known, it is still useful to consolidate the code that determines the PCI function to one location and use the results throughout the code. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 14 +++++++++++--- drivers/net/tg3.h | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5d4283e7be7..6f1f36c8905 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1170,7 +1170,7 @@ static int tg3_mdio_init(struct tg3 *tp) if (tg3_flag(tp, 5717_PLUS)) { u32 is_serdes; - tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1; + tp->phy_addr = tp->pci_fn + 1; if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES; @@ -13951,6 +13951,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) val = tr32(MEMARB_MODE); tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); + if (tg3_flag(tp, PCIX_MODE)) { + pci_read_config_dword(tp->pdev, + tp->pcix_cap + PCI_X_STATUS, &val); + tp->pci_fn = val & 0x7; + } else { + tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3; + } + /* Get eeprom hw config before calling tg3_set_power_state(). * In particular, the TG3_FLAG_IS_NIC flag must be * determined before calling tg3_set_power_state() so that @@ -14316,9 +14324,9 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) else tg3_nvram_unlock(tp); } else if (tg3_flag(tp, 5717_PLUS)) { - if (PCI_FUNC(tp->pdev->devfn) & 1) + if (tp->pci_fn & 1) mac_offset = 0xcc; - if (PCI_FUNC(tp->pdev->devfn) > 1) + if (tp->pci_fn > 1) mac_offset += 0x18c; } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) mac_offset = 0x10; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 5f250aef7c9..b4c003db69a 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -3020,6 +3020,7 @@ struct tg3 { u8 pci_cacheline_sz; u8 pci_lat_timer; + int pci_fn; int pm_cap; int msi_cap; int pcix_cap; -- cgit v1.2.3-70-g09d2 From 6f5c8f8317d37045ffc7ea21dab8319a53c1ae57 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Jul 2011 09:27:31 +0000 Subject: tg3: Create critical section around GPIO toggling The code that performs the power source switching will need to consider the status of the other devices before making any switches. The status updates and power source switching will need to be an atomic operation, so a critical section will be needed. This patch establishes the critical section through a CPMU mutex. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 63 +++++++++++++++++++++++++++++++++++++++++++++---------- drivers/net/tg3.h | 1 + 2 files changed, 53 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6f1f36c8905..4137e4e027a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -608,7 +608,7 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) static void tg3_ape_lock_init(struct tg3 *tp) { int i; - u32 regbase; + u32 regbase, bit; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) regbase = TG3_APE_LOCK_GRANT; @@ -616,20 +616,34 @@ static void tg3_ape_lock_init(struct tg3 *tp) regbase = TG3_APE_PER_LOCK_GRANT; /* Make sure the driver hasn't any stale locks. */ - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { + if (i == TG3_APE_LOCK_GPIO) + continue; tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER); + } + + /* Clear the correct bit of the GPIO lock too. */ + if (!tp->pci_fn) + bit = APE_LOCK_GRANT_DRIVER; + else + bit = 1 << tp->pci_fn; + + tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit); } static int tg3_ape_lock(struct tg3 *tp, int locknum) { int i, off; int ret = 0; - u32 status, req, gnt; + u32 status, req, gnt, bit; if (!tg3_flag(tp, ENABLE_APE)) return 0; switch (locknum) { + case TG3_APE_LOCK_GPIO: + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) + return 0; case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_MEM: break; @@ -647,21 +661,24 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) off = 4 * locknum; - tg3_ape_write32(tp, req + off, APE_LOCK_REQ_DRIVER); + if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn) + bit = APE_LOCK_REQ_DRIVER; + else + bit = 1 << tp->pci_fn; + + tg3_ape_write32(tp, req + off, bit); /* Wait for up to 1 millisecond to acquire lock. */ for (i = 0; i < 100; i++) { status = tg3_ape_read32(tp, gnt + off); - if (status == APE_LOCK_GRANT_DRIVER) + if (status == bit) break; udelay(10); } - if (status != APE_LOCK_GRANT_DRIVER) { + if (status != bit) { /* Revoke the lock request. */ - tg3_ape_write32(tp, gnt + off, - APE_LOCK_GRANT_DRIVER); - + tg3_ape_write32(tp, gnt + off, bit); ret = -EBUSY; } @@ -670,12 +687,15 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) static void tg3_ape_unlock(struct tg3 *tp, int locknum) { - u32 gnt; + u32 gnt, bit; if (!tg3_flag(tp, ENABLE_APE)) return; switch (locknum) { + case TG3_APE_LOCK_GPIO: + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) + return; case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_MEM: break; @@ -688,7 +708,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) else gnt = TG3_APE_PER_LOCK_GRANT; - tg3_ape_write32(tp, gnt + 4 * locknum, APE_LOCK_GRANT_DRIVER); + if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn) + bit = APE_LOCK_GRANT_DRIVER; + else + bit = 1 << tp->pci_fn; + + tg3_ape_write32(tp, gnt + 4 * locknum, bit); } static void tg3_disable_ints(struct tg3 *tp) @@ -2170,11 +2195,16 @@ out: static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp) { if (!tg3_flag(tp, IS_NIC)) + return; + + if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) return 0; tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, TG3_GRC_LCLCTL_PWRSW_DELAY); + tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); + return 0; } @@ -2187,6 +2217,10 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) return; + + if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) + return; + grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1; tw32_wait_f(GRC_LOCAL_CTRL, @@ -2200,6 +2234,8 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp) tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1, TG3_GRC_LCLCTL_PWRSW_DELAY); + + tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); } static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) @@ -2207,6 +2243,9 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) if (!tg3_flag(tp, IS_NIC)) return; + if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) + return; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | @@ -2277,6 +2316,8 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) TG3_GRC_LCLCTL_PWRSW_DELAY); } } + + tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); } static void tg3_frob_aux_power(struct tg3 *tp) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index b4c003db69a..e4444699fa9 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2339,6 +2339,7 @@ /* APE convenience enumerations. */ #define TG3_APE_LOCK_GRC 1 #define TG3_APE_LOCK_MEM 4 +#define TG3_APE_LOCK_GPIO 7 #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 -- cgit v1.2.3-70-g09d2 From 3a1e19d383c7b91c8af52e8938ab60c40e3d26b3 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Jul 2011 09:27:32 +0000 Subject: tg3: Add function status reporting This patch adds code to update the status of the function to a common location to the critical section added in the previous patch. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 111 ++++++++++++++++++++++++++++++++++++++++++------------ drivers/net/tg3.h | 4 ++ 2 files changed, 91 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4137e4e027a..0d1b0c0ef48 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2192,18 +2192,66 @@ out: return 0; } +#define TG3_GPIO_MSG_DRVR_PRES 0x00000001 +#define TG3_GPIO_MSG_NEED_VAUX 0x00000002 +#define TG3_GPIO_MSG_MASK (TG3_GPIO_MSG_DRVR_PRES | \ + TG3_GPIO_MSG_NEED_VAUX) +#define TG3_GPIO_MSG_ALL_DRVR_PRES_MASK \ + ((TG3_GPIO_MSG_DRVR_PRES << 0) | \ + (TG3_GPIO_MSG_DRVR_PRES << 4) | \ + (TG3_GPIO_MSG_DRVR_PRES << 8) | \ + (TG3_GPIO_MSG_DRVR_PRES << 12)) + +#define TG3_GPIO_MSG_ALL_NEED_VAUX_MASK \ + ((TG3_GPIO_MSG_NEED_VAUX << 0) | \ + (TG3_GPIO_MSG_NEED_VAUX << 4) | \ + (TG3_GPIO_MSG_NEED_VAUX << 8) | \ + (TG3_GPIO_MSG_NEED_VAUX << 12)) + +static inline u32 tg3_set_function_status(struct tg3 *tp, u32 newstat) +{ + u32 status, shift; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + status = tg3_ape_read32(tp, TG3_APE_GPIO_MSG); + else + status = tr32(TG3_CPMU_DRV_STATUS); + + shift = TG3_APE_GPIO_MSG_SHIFT + 4 * tp->pci_fn; + status &= ~(TG3_GPIO_MSG_MASK << shift); + status |= (newstat << shift); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + tg3_ape_write32(tp, TG3_APE_GPIO_MSG, status); + else + tw32(TG3_CPMU_DRV_STATUS, status); + + return status >> TG3_APE_GPIO_MSG_SHIFT; +} + static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp) { if (!tg3_flag(tp, IS_NIC)) - return; - - if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) return 0; - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, - TG3_GRC_LCLCTL_PWRSW_DELAY); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { + if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) + return -EIO; - tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); + tg3_set_function_status(tp, TG3_GPIO_MSG_DRVR_PRES); + + tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + + tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); + } else { + tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, + TG3_GRC_LCLCTL_PWRSW_DELAY); + } return 0; } @@ -2217,10 +2265,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) return; - - if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) - return; - grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1; tw32_wait_f(GRC_LOCAL_CTRL, @@ -2234,8 +2278,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp) tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1, TG3_GRC_LCLCTL_PWRSW_DELAY); - - tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); } static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) @@ -2243,9 +2285,6 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) if (!tg3_flag(tp, IS_NIC)) return; - if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) - return; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | @@ -2316,7 +2355,31 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) TG3_GRC_LCLCTL_PWRSW_DELAY); } } +} + +static void tg3_frob_aux_power_5717(struct tg3 *tp) +{ + u32 msg = 0; + + /* Serialize power state transitions */ + if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) + return; + + if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || + tg3_flag(tp, WOL_ENABLE)) + msg = TG3_GPIO_MSG_NEED_VAUX; + + msg = tg3_set_function_status(tp, msg); + + if (msg & TG3_GPIO_MSG_ALL_DRVR_PRES_MASK) + goto done; + if (msg & TG3_GPIO_MSG_ALL_NEED_VAUX_MASK) + tg3_pwrsrc_switch_to_vaux(tp); + else + tg3_pwrsrc_die_with_vmain(tp); + +done: tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); } @@ -2326,15 +2389,17 @@ static void tg3_frob_aux_power(struct tg3 *tp) /* The GPIOs do something completely different on 57765. */ if (!tg3_flag(tp, IS_NIC) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) return; - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) && - tp->pdev_peer != tp->pdev) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { + tg3_frob_aux_power_5717(tp); + return; + } + + if (tp->pdev_peer && tp->pdev_peer != tp->pdev) { struct net_device *dev_peer; dev_peer = pci_get_drvdata(tp->pdev_peer); @@ -13692,9 +13757,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) tp->pdev_peer = tg3_find_peer(tp); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index e4444699fa9..6a43fc51d87 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1065,6 +1065,8 @@ #define RCVLSC_STATUS_ERROR_ATTN 0x00000004 /* 0x3408 --> 0x3600 unused */ +#define TG3_CPMU_DRV_STATUS 0x0000344c + /* CPMU registers */ #define TG3_CPMU_CTRL 0x00003600 #define CPMU_CTRL_LINK_IDLE_MODE 0x00000200 @@ -2277,6 +2279,8 @@ /* APE registers. Accessible through BAR1 */ +#define TG3_APE_GPIO_MSG 0x0008 +#define TG3_APE_GPIO_MSG_SHIFT 4 #define TG3_APE_EVENT 0x000c #define APE_EVENT_1 0x00000001 #define TG3_APE_LOCK_REQ 0x002c -- cgit v1.2.3-70-g09d2 From cd0d7228b4f0279f219bc555fa0192dc072d79cd Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Jul 2011 09:27:33 +0000 Subject: tg3: Match power source to driver state Now that the driver state (and power source) is being more intensely scrutinized, we need to make sure it is correct 100% of the time. This patch finds and fixes all dangling power state transitions. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0d1b0c0ef48..a5ff82d3b75 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2357,7 +2357,7 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp) } } -static void tg3_frob_aux_power_5717(struct tg3 *tp) +static void tg3_frob_aux_power_5717(struct tg3 *tp, bool wol_enable) { u32 msg = 0; @@ -2365,8 +2365,7 @@ static void tg3_frob_aux_power_5717(struct tg3 *tp) if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO)) return; - if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || - tg3_flag(tp, WOL_ENABLE)) + if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || wol_enable) msg = TG3_GPIO_MSG_NEED_VAUX; msg = tg3_set_function_status(tp, msg); @@ -2383,7 +2382,7 @@ done: tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO); } -static void tg3_frob_aux_power(struct tg3 *tp) +static void tg3_frob_aux_power(struct tg3 *tp, bool include_wol) { bool need_vaux = false; @@ -2395,7 +2394,8 @@ static void tg3_frob_aux_power(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { - tg3_frob_aux_power_5717(tp); + tg3_frob_aux_power_5717(tp, include_wol ? + tg3_flag(tp, WOL_ENABLE) != 0 : 0); return; } @@ -2411,13 +2411,14 @@ static void tg3_frob_aux_power(struct tg3 *tp) if (tg3_flag(tp_peer, INIT_COMPLETE)) return; - if (tg3_flag(tp_peer, WOL_ENABLE) || + if ((include_wol && tg3_flag(tp_peer, WOL_ENABLE)) || tg3_flag(tp_peer, ENABLE_ASF)) need_vaux = true; } } - if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF)) + if ((include_wol && tg3_flag(tp, WOL_ENABLE)) || + tg3_flag(tp, ENABLE_ASF)) need_vaux = true; if (need_vaux) @@ -3000,7 +3001,7 @@ static int tg3_power_down_prepare(struct tg3 *tp) if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF)) tg3_power_down_phy(tp, do_low_power); - tg3_frob_aux_power(tp); + tg3_frob_aux_power(tp, true); /* Workaround for unstable PLL clock */ if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) || @@ -9556,6 +9557,8 @@ err_out2: err_out1: tg3_ints_fini(tp); + tg3_frob_aux_power(tp, false); + pci_set_power_state(tp->pdev, PCI_D3hot); return err; } @@ -15400,6 +15403,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); + if (tg3_flag(tp, 5717_PLUS)) { + /* Resume a low-power mode */ + tg3_frob_aux_power(tp, false); + } + err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Cannot register net device, aborting\n"); -- cgit v1.2.3-70-g09d2 From 973e574e26cc8f4704e5d7f112fd566386e37f04 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Jul 2011 17:24:17 +0000 Subject: cnic: Replace get_random_bytes() with random32() Suggested by Stephen Hemminger Signed-off-by: Michael Chan Reviewed-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/cnic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 5533b1526b1..23d6108c64c 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define BCM_VLAN 1 #endif @@ -3830,7 +3831,7 @@ static int cnic_cm_alloc_mem(struct cnic_dev *dev) if (!cp->csk_tbl) return -ENOMEM; - get_random_bytes(&port_id, sizeof(port_id)); + port_id = random32(); port_id %= CNIC_LOCAL_PORT_RANGE; if (cnic_init_id_tbl(&cp->csk_port_tbl, CNIC_LOCAL_PORT_RANGE, CNIC_LOCAL_PORT_MIN, port_id)) { @@ -3890,7 +3891,7 @@ static int cnic_cm_init_bnx2_hw(struct cnic_dev *dev) { u32 seed; - get_random_bytes(&seed, 4); + seed = random32(); cnic_ctx_wr(dev, 45, 0, seed); return 0; } -- cgit v1.2.3-70-g09d2 From b7d40315c9643034ac4b5c9dda480d0124416f89 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Jul 2011 17:24:18 +0000 Subject: cnic: Fix port_mode setting CHIP_2_PORT_MODE was not set correctly. Signed-off-by: Michael Chan Reviewed-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/cnic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 23d6108c64c..a881e42c0ad 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4834,7 +4834,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) cp->port_mode = CHIP_4_PORT_MODE; cp->pfid = func >> 1; } else { - cp->port_mode = CHIP_4_PORT_MODE; + cp->port_mode = CHIP_2_PORT_MODE; cp->pfid = func & 0x6; } } else { -- cgit v1.2.3-70-g09d2 From e1dd883cb15310dc2ded9995a1f1d8b1cb1e88f3 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Jul 2011 17:24:19 +0000 Subject: cnic: Fix ring setup/shutdown code Latest bnx2x driver uses different CID for the iSCSI rings, so we need to pass it in the ring init data. The rx ring is also zeroed out to prevent stale DMA addresses from being used after shutdown. The same cp local variable redefined inside the else branch is also eliminated. Signed-off-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/cnic.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index a881e42c0ad..bdfe15566ce 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4923,7 +4923,7 @@ static void cnic_init_rings(struct cnic_dev *dev) struct client_init_ramrod_data *data; union l5cm_specific_data l5_data; struct ustorm_eth_rx_producers rx_prods = {0}; - u32 off, i; + u32 off, i, *cid_ptr; rx_prods.bd_prod = 0; rx_prods.cqe_prod = BNX2X_MAX_RCQ_DESC_CNT; @@ -4942,6 +4942,7 @@ static void cnic_init_rings(struct cnic_dev *dev) set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); data = udev->l2_buf; + cid_ptr = udev->l2_buf + 12; memset(data, 0, sizeof(*data)); @@ -4966,12 +4967,15 @@ static void cnic_init_rings(struct cnic_dev *dev) "iSCSI CLIENT_SETUP did not complete\n"); cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); cnic_ring_ctl(dev, cid, cli, 1); + *cid_ptr = cid; } } static void cnic_shutdown_rings(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; + void *rx_ring; if (!test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) return; @@ -4979,7 +4983,6 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { cnic_shutdown_bnx2_rx_ring(dev); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { - struct cnic_local *cp = dev->cnic_priv; u32 cli = cp->ethdev->iscsi_l2_client_id; u32 cid = cp->ethdev->iscsi_l2_cid; union l5cm_specific_data l5_data; @@ -5009,6 +5012,8 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) msleep(10); } clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); + rx_ring = udev->l2_ring + BCM_PAGE_SIZE; + memset(rx_ring, 0, BCM_PAGE_SIZE); } static int cnic_register_netdev(struct cnic_dev *dev) -- cgit v1.2.3-70-g09d2 From 558e4c758c4c7bf209325f5865189c6558860b2b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Jul 2011 17:24:20 +0000 Subject: cnic: Return proper error code if we fail to send netlink message to allow iSCSI connection to fail faster instead of waiting for the long timeout. Update version to 2.5.6. Signed-off-by: Michael Chan Reviewed-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/cnic.c | 2 +- drivers/net/cnic_if.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index bdfe15566ce..ea75f65a179 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -328,7 +328,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, msleep(100); retry++; } - return 0; + return rc; } static void cnic_cm_upcall(struct cnic_local *, struct cnic_sock *, u8); diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index bc7000a2d4e..642b9d56a1c 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.5.3" -#define CNIC_MODULE_RELDATE "June 6, 2011" +#define CNIC_MODULE_VERSION "2.5.6" +#define CNIC_MODULE_RELDATE "July 12, 2011" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- cgit v1.2.3-70-g09d2 From ecdbf6e0d555d353188647d1b2dee9a79db69c68 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Wed, 13 Jul 2011 17:24:21 +0000 Subject: bnx2: Add MCP dump to help debug issues related to management firmware. Signed-off-by: Jeffrey Huang Signed-off-by: Michael Chan Reviewed-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 61 ++++++++++++++++++++++++++++++++++++++++++------------ drivers/net/bnx2.h | 8 +++++++ 2 files changed, 56 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7915d140457..d105f1f2339 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -2443,6 +2443,48 @@ bnx2_set_phy_loopback(struct bnx2 *bp) return 0; } +static void +bnx2_dump_mcp_state(struct bnx2 *bp) +{ + struct net_device *dev = bp->dev; + u32 mcp_p0, mcp_p1; + + netdev_err(dev, "<--- start MCP states dump --->\n"); + if (CHIP_NUM(bp) == CHIP_NUM_5709) { + mcp_p0 = BNX2_MCP_STATE_P0; + mcp_p1 = BNX2_MCP_STATE_P1; + } else { + mcp_p0 = BNX2_MCP_STATE_P0_5708; + mcp_p1 = BNX2_MCP_STATE_P1_5708; + } + netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n", + bnx2_reg_rd_ind(bp, mcp_p0), bnx2_reg_rd_ind(bp, mcp_p1)); + netdev_err(dev, "DEBUG: MCP mode[%08x] state[%08x] evt_mask[%08x]\n", + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_MODE), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_STATE), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_EVENT_MASK)); + netdev_err(dev, "DEBUG: pc[%08x] pc[%08x] instr[%08x]\n", + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_PROGRAM_COUNTER), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_PROGRAM_COUNTER), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_INSTRUCTION)); + netdev_err(dev, "DEBUG: shmem states:\n"); + netdev_err(dev, "DEBUG: drv_mb[%08x] fw_mb[%08x] link_status[%08x]", + bnx2_shmem_rd(bp, BNX2_DRV_MB), + bnx2_shmem_rd(bp, BNX2_FW_MB), + bnx2_shmem_rd(bp, BNX2_LINK_STATUS)); + pr_cont(" drv_pulse_mb[%08x]\n", bnx2_shmem_rd(bp, BNX2_DRV_PULSE_MB)); + netdev_err(dev, "DEBUG: dev_info_signature[%08x] reset_type[%08x]", + bnx2_shmem_rd(bp, BNX2_DEV_INFO_SIGNATURE), + bnx2_shmem_rd(bp, BNX2_BC_STATE_RESET_TYPE)); + pr_cont(" condition[%08x]\n", + bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION)); + DP_SHMEM_LINE(bp, 0x3cc); + DP_SHMEM_LINE(bp, 0x3dc); + DP_SHMEM_LINE(bp, 0x3ec); + netdev_err(dev, "DEBUG: 0x3fc[%08x]\n", bnx2_shmem_rd(bp, 0x3fc)); + netdev_err(dev, "<--- end MCP states dump --->\n"); +} + static int bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent) { @@ -2471,13 +2513,14 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent) /* If we timed out, inform the firmware that this is the case. */ if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) { - if (!silent) - pr_err("fw sync timeout, reset code = %x\n", msg_data); - msg_data &= ~BNX2_DRV_MSG_CODE; msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data); + if (!silent) { + pr_err("fw sync timeout, reset code = %x\n", msg_data); + bnx2_dump_mcp_state(bp); + } return -EBUSY; } @@ -6316,7 +6359,7 @@ static void bnx2_dump_state(struct bnx2 *bp) { struct net_device *dev = bp->dev; - u32 mcp_p0, mcp_p1, val1, val2; + u32 val1, val2; pci_read_config_dword(bp->pdev, PCI_COMMAND, &val1); netdev_err(dev, "DEBUG: intr_sem[%x] PCI_CMD[%08x]\n", @@ -6329,15 +6372,6 @@ bnx2_dump_state(struct bnx2 *bp) REG_RD(bp, BNX2_EMAC_RX_STATUS)); netdev_err(dev, "DEBUG: RPM_MGMT_PKT_CTRL[%08x]\n", REG_RD(bp, BNX2_RPM_MGMT_PKT_CTRL)); - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - mcp_p0 = BNX2_MCP_STATE_P0; - mcp_p1 = BNX2_MCP_STATE_P1; - } else { - mcp_p0 = BNX2_MCP_STATE_P0_5708; - mcp_p1 = BNX2_MCP_STATE_P1_5708; - } - netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n", - bnx2_reg_rd_ind(bp, mcp_p0), bnx2_reg_rd_ind(bp, mcp_p1)); netdev_err(dev, "DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n", REG_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS)); if (bp->flags & BNX2_FLAG_USING_MSIX) @@ -6351,6 +6385,7 @@ bnx2_tx_timeout(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); bnx2_dump_state(bp); + bnx2_dump_mcp_state(bp); /* This allows the netif to be shutdown gracefully before resetting */ schedule_work(&bp->reset_task); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index bf371f6fe15..0f0ad2b44c2 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -7370,4 +7370,12 @@ struct bnx2_rv2p_fw_file { #define HOST_VIEW_SHMEM_BASE 0x167c00 +#define DP_SHMEM_LINE(bp, offset) \ + netdev_err(bp->dev, "DEBUG: %08x: %08x %08x %08x %08x\n", \ + offset, \ + bnx2_shmem_rd(bp, offset), \ + bnx2_shmem_rd(bp, offset + 4), \ + bnx2_shmem_rd(bp, offset + 8), \ + bnx2_shmem_rd(bp, offset + 12)) + #endif -- cgit v1.2.3-70-g09d2 From 41c2178adce37b249147063624f8a27b064b471e Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Jul 2011 17:24:22 +0000 Subject: bnx2: Read iSCSI config from shared memory during ->probe() The scratchpad location that we were reading from has not been initialized yet during ->probe(), so we were getting inaccurate information. Update version to 2.1.10. Signed-off-by: Michael Chan Reviewed-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 13 +++++++++---- drivers/net/bnx2.h | 7 +++++++ 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d105f1f2339..4816d6a5fe6 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.1.6" -#define DRV_MODULE_RELDATE "Mar 7, 2011" +#define DRV_MODULE_VERSION "2.1.10" +#define DRV_MODULE_RELDATE "July 12, 2011" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1a.fw" @@ -385,6 +385,9 @@ static int bnx2_register_cnic(struct net_device *dev, struct cnic_ops *ops, if (cp->drv_state & CNIC_DRV_STATE_REGD) return -EBUSY; + if (!bnx2_reg_rd_ind(bp, BNX2_FW_MAX_ISCSI_CONN)) + return -ENODEV; + bp->cnic_data = data; rcu_assign_pointer(bp->cnic_ops, ops); @@ -8215,8 +8218,10 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->timer.function = bnx2_timer; #ifdef BCM_CNIC - bp->cnic_eth_dev.max_iscsi_conn = - bnx2_reg_rd_ind(bp, BNX2_FW_MAX_ISCSI_CONN); + if (bnx2_shmem_rd(bp, BNX2_ISCSI_INITIATOR) & BNX2_ISCSI_INITIATOR_EN) + bp->cnic_eth_dev.max_iscsi_conn = + (bnx2_shmem_rd(bp, BNX2_ISCSI_MAX_CONN) & + BNX2_ISCSI_MAX_CONN_MASK) >> BNX2_ISCSI_MAX_CONN_SHIFT; #endif pci_save_state(pdev); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 0f0ad2b44c2..fc50d4267df 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -7368,6 +7368,13 @@ struct bnx2_rv2p_fw_file { #define BNX2_RPHY_SERDES_LINK 0x374 #define BNX2_RPHY_COPPER_LINK 0x378 +#define BNX2_ISCSI_INITIATOR 0x3dc +#define BNX2_ISCSI_INITIATOR_EN 0x00080000 + +#define BNX2_ISCSI_MAX_CONN 0x3e4 +#define BNX2_ISCSI_MAX_CONN_MASK 0xffff0000 +#define BNX2_ISCSI_MAX_CONN_SHIFT 16 + #define HOST_VIEW_SHMEM_BASE 0x167c00 #define DP_SHMEM_LINE(bp, offset) \ -- cgit v1.2.3-70-g09d2 From 7b749ff4dfba109d25a6b4fd011ee78877831e86 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Thu, 14 Jul 2011 03:16:50 +0000 Subject: qlcnic: fix chip reset logic Chip reset logic (IDC logic) has changed with fw dump support. This broked compatibility with driver using older IDC logic. Changes to make it compatible with drivers using older IDC logic. Signed-off-by: Sritej Velaga Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 357436be801..6b646c65f2f 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2811,6 +2811,7 @@ qlcnic_fwinit_work(struct work_struct *work) struct qlcnic_adapter *adapter = container_of(work, struct qlcnic_adapter, fw_work.work); u32 dev_state = 0xf; + u32 val; if (qlcnic_api_lock(adapter)) goto err_ret; @@ -2837,11 +2838,6 @@ qlcnic_fwinit_work(struct work_struct *work) if (!qlcnic_check_drv_state(adapter)) { skip_ack_check: - if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) { - qlcnic_api_unlock(adapter); - goto wait_npar; - } - dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); if (dev_state == QLCNIC_DEV_NEED_RESET) { @@ -2850,17 +2846,22 @@ skip_ack_check: set_bit(__QLCNIC_START_FW, &adapter->state); QLCDB(adapter, DRV, "Restarting fw\n"); qlcnic_idc_debug_info(adapter, 0); + val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); + QLC_DEV_SET_RST_RDY(val, adapter->portnum); + QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); } qlcnic_api_unlock(adapter); rtnl_lock(); - if (adapter->ahw->fw_dump.enable) { + if (adapter->ahw->fw_dump.enable && + (adapter->flags & QLCNIC_FW_RESET_OWNER)) { QLCDB(adapter, DRV, "Take FW dump\n"); qlcnic_dump_fw(adapter); - adapter->flags &= ~QLCNIC_FW_RESET_OWNER; } rtnl_unlock(); + + adapter->flags &= ~QLCNIC_FW_RESET_OWNER; if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); adapter->fw_wait_cnt = 0; -- cgit v1.2.3-70-g09d2 From a941fef81b48179ea64728034f3ed5cda2336987 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Thu, 14 Jul 2011 03:16:51 +0000 Subject: qlcnic: updated supported cards information Added QME8242-k 10GbE Dual Port Mezzanine Card to supported card info. Signed-off-by: Sritej Velaga Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9899a794771..7c0d6ee1697 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1510,6 +1510,8 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = { "NC523SFP 10Gb 2-port Server Adapter"}, {0x1077, 0x8020, 0x103c, 0x3346, "CN1000Q Dual Port Converged Network Adapter"}, + {0x1077, 0x8020, 0x1077, 0x210, + "QME8242-k 10GbE Dual Port Mezzanine Card"}, {0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"}, }; -- cgit v1.2.3-70-g09d2 From e5dcf6dcde26ffdbd237dda4956bc6d7115dfae6 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Thu, 14 Jul 2011 03:16:52 +0000 Subject: qlcnic: enable mac-learning in promiscous mode. MAC learning is required in bridge mode. During bridge mode device will be put in promiscous mode. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 ++ drivers/net/qlcnic/qlcnic_hw.c | 7 +++++++ drivers/net/qlcnic/qlcnic_main.c | 13 +++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 7c0d6ee1697..3ae24501911 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1015,6 +1015,7 @@ struct qlcnic_adapter { u8 mac_addr[ETH_ALEN]; u64 dev_rst_time; + u8 mac_learn; unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct qlcnic_npar_info *npars; @@ -1460,6 +1461,7 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val); int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data); void qlcnic_dev_request_reset(struct qlcnic_adapter *); +void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); /* Management functions */ int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 0391a04695d..4055c218ef2 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -446,6 +446,13 @@ void qlcnic_set_multi(struct net_device *netdev) } send_fw_cmd: + if (mode == VPORT_MISS_MODE_ACCEPT_ALL) { + qlcnic_alloc_lb_filters_mem(adapter); + adapter->mac_learn = 1; + } else { + adapter->mac_learn = 0; + } + qlcnic_nic_set_promisc(adapter, mode); } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 6b646c65f2f..916570db3aa 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -90,7 +90,6 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long); static int qlcnic_start_firmware(struct qlcnic_adapter *); -static void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); @@ -1578,6 +1577,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->dev_rst_time = jiffies; revision_id = pdev->revision; adapter->ahw->revision_id = revision_id; + adapter->mac_learn = qlcnic_mac_learn; rwlock_init(&adapter->ahw->crb_lock); mutex_init(&adapter->ahw->mem_lock); @@ -1654,7 +1654,9 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - qlcnic_alloc_lb_filters_mem(adapter); + if (adapter->mac_learn) + qlcnic_alloc_lb_filters_mem(adapter); + qlcnic_create_diag_entries(adapter); return 0; @@ -1850,13 +1852,12 @@ static int qlcnic_close(struct net_device *netdev) return 0; } -static void -qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) +void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) { void *head; int i; - if (!qlcnic_mac_learn) + if (adapter->fhash.fmax && adapter->fhash.fhead) return; spin_lock_init(&adapter->mac_learn_lock); @@ -2286,7 +2287,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb))) goto unwind_buff; - if (qlcnic_mac_learn) + if (adapter->mac_learn) qlcnic_send_filter(adapter, tx_ring, first_desc, skb); qlcnic_update_cmd_producer(adapter, tx_ring); -- cgit v1.2.3-70-g09d2 From f127f4727f3f60359570b6daa136ac1156e38fbf Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Thu, 14 Jul 2011 03:16:53 +0000 Subject: qlcnic: fix race in skb->len access. As soon as skb is given to hardware, TX completion can free skb under us. Therefore, we should update dev stats before kicking the device. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 916570db3aa..006a693d49a 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2290,11 +2290,11 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (adapter->mac_learn) qlcnic_send_filter(adapter, tx_ring, first_desc, skb); - qlcnic_update_cmd_producer(adapter, tx_ring); - adapter->stats.txbytes += skb->len; adapter->stats.xmitcalled++; + qlcnic_update_cmd_producer(adapter, tx_ring); + return NETDEV_TX_OK; unwind_buff: -- cgit v1.2.3-70-g09d2 From fef0c0600b265ea5d4b1e39574801e6509a1dae6 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 14 Jul 2011 03:16:54 +0000 Subject: qlcnic: define error code for loopback test o Defined error code such as fw not responding, test already running and cable not connected. o Check Fw capability before performing loopback test. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 9 ++++++++- drivers/net/qlcnic/qlcnic_ethtool.c | 27 ++++++++++++++++----------- drivers/net/qlcnic/qlcnic_init.c | 6 ++++++ 3 files changed, 30 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 3ae24501911..f6e54a8e349 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -822,6 +822,7 @@ struct qlcnic_mac_list_s { #define QLCNIC_FW_CAPABILITY_BDG BIT_8 #define QLCNIC_FW_CAPABILITY_FVLANTX BIT_9 #define QLCNIC_FW_CAPABILITY_HW_LRO BIT_10 +#define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK BIT_27 /* module types */ #define LINKEVENT_MODULE_NOT_PRESENT 1 @@ -936,6 +937,12 @@ struct qlcnic_ipaddr { #define QLCNIC_READD_AGE 20 #define QLCNIC_LB_MAX_FILTERS 64 +/* QLCNIC Driver Error Code */ +#define QLCNIC_FW_NOT_RESPOND 51 +#define QLCNIC_TEST_IN_PROGRESS 52 +#define QLCNIC_UNDEFINED_ERROR 53 +#define QLCNIC_LB_CABLE_NOT_CONN 54 + struct qlcnic_filter { struct hlist_node fnode; u8 faddr[ETH_ALEN]; @@ -1007,7 +1014,7 @@ struct qlcnic_adapter { u8 max_mac_filters; u8 dev_state; u8 diag_test; - u8 diag_cnt; + char diag_cnt; u8 reset_ack_timeo; u8 dev_init_timeo; u16 msg_enable; diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 3ea04e7da91..72a723d5c98 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -756,6 +756,11 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode) int loop = 0; int ret; + if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) { + netdev_info(netdev, "Firmware is not loopback test capable\n"); + return -EOPNOTSUPP; + } + netdev_info(netdev, "%s loopback test in progress\n", mode == QLCNIC_ILB_MODE ? "internal" : "external"); if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { @@ -765,8 +770,7 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode) } if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) - return -EIO; - + return -EBUSY; ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); if (ret) @@ -778,20 +782,21 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode) if (ret) goto free_res; + adapter->diag_cnt = 0; do { msleep(500); qlcnic_process_rcv_ring_diag(sds_ring); - if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) - break; + if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) { + netdev_info(netdev, "firmware didnt respond to loopback" + " configure request\n"); + ret = -QLCNIC_FW_NOT_RESPOND; + goto free_res; + } else if (adapter->diag_cnt) { + ret = adapter->diag_cnt; + goto free_res; + } } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)); - if (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)) { - netdev_info(netdev, "firmware didnt respond to loopback " - "configure request\n"); - ret = adapter->ahw->loopback_state; - goto free_res; - } - ret = qlcnic_do_lb_test(adapter); qlcnic_clear_lb_mode(adapter); diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 6ec1baa85f6..ee8a3982395 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1354,10 +1354,16 @@ qlcnic_handle_fw_message(int desc_cnt, int index, break; case 1: dev_info(dev, "loopback already in progress\n"); + adapter->diag_cnt = -QLCNIC_TEST_IN_PROGRESS; + break; + case 2: + dev_info(dev, "loopback cable is not connected\n"); + adapter->diag_cnt = -QLCNIC_LB_CABLE_NOT_CONN; break; default: dev_info(dev, "loopback configure request failed," " ret %x\n", ret); + adapter->diag_cnt = -QLCNIC_UNDEFINED_ERROR; break; } break; -- cgit v1.2.3-70-g09d2 From 40522998dec20d970fe6f0ea8507004aef18f72d Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Thu, 14 Jul 2011 03:16:55 +0000 Subject: qlcnic: change capture mask for FW dump o Change FW dump capture mask to a defult value, instead of using the recommended value from the FW. This was done to keep the capture mask consistent with other function drivers. o Update driver version to 5.0.21 Signed-off-by: Anirban Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 6 +++--- drivers/net/qlcnic/qlcnic_ctx.c | 6 +----- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index f6e54a8e349..baf646d98fa 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -36,8 +36,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 20 -#define QLCNIC_LINUX_VERSIONID "5.0.20" +#define _QLCNIC_LINUX_SUBVERSION 21 +#define QLCNIC_LINUX_VERSIONID "5.0.21" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -1339,7 +1339,7 @@ enum op_codes { #define QLCNIC_DUMP_SKIP BIT_7 #define QLCNIC_DUMP_MASK_MIN 3 -#define QLCNIC_DUMP_MASK_DEF 0x7f +#define QLCNIC_DUMP_MASK_DEF 0x1f #define QLCNIC_DUMP_MASK_MAX 0xff #define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed #define QLCNIC_ENABLE_FW_DUMP 0xaddfeed diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 33f5c8a8b55..b0d32ddd2cc 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -145,11 +145,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) *template++ = __le32_to_cpu(*tmp_buf++); tmpl_hdr = ahw->fw_dump.tmpl_hdr; - if (tmpl_hdr->cap_mask > QLCNIC_DUMP_MASK_DEF && - tmpl_hdr->cap_mask <= QLCNIC_DUMP_MASK_MAX) - tmpl_hdr->drv_cap_mask = tmpl_hdr->cap_mask; - else - tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF; + tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF; ahw->fw_dump.enable = 1; error: dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t); -- cgit v1.2.3-70-g09d2 From e3001c98df51d81a72534837d8069bfb53f3e1ea Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Tue, 12 Jul 2011 10:13:24 +0000 Subject: ps3_gelic: Fix typos Signed-off-by: Andre Heider Acked-by: Geoff Levand Signed-off-by: David S. Miller --- drivers/net/ps3_gelic_net.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 35e47c3cab3..9652d10b015 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -876,7 +876,7 @@ int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) result = gelic_descr_prepare_tx(card, descr, skb); if (result) { /* - * DMA map failed. As chanses are that failure + * DMA map failed. As chances are that failure * would continue, just release skb and return */ netdev->stats.tx_dropped++; @@ -1041,7 +1041,7 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) goto refill; } /* - * descriptoers any other than FRAME_END here should + * descriptors any other than FRAME_END here should * be treated as error. */ if (status != GELIC_DESCR_DMA_FRAME_END) { @@ -1200,7 +1200,7 @@ void gelic_net_poll_controller(struct net_device *netdev) #endif /* CONFIG_NET_POLL_CONTROLLER */ /** - * gelic_net_open - called upon ifonfig up + * gelic_net_open - called upon ifconfig up * @netdev: interface device structure * * returns 0 on success, <0 on failure -- cgit v1.2.3-70-g09d2 From bb4f85ce1731d78648870333f0ce77123fa162e6 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Tue, 12 Jul 2011 10:13:25 +0000 Subject: ps3_gelic: Fix start_xmit kick error path Revert to a proper state when gelic_card_kick_txdma() fails: - Don't trigger BUG_ON when releasing the unsent tx descriptor - Reset the tx chain head since the tail was not modified and hence not in sync - Unlink the released descriptor bus address from its predecessor Signed-off-by: Andre Heider Acked-by: Geoff Levand Signed-off-by: David S. Miller --- drivers/net/ps3_gelic_net.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 9652d10b015..94422fcc857 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -897,12 +897,16 @@ int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) if (gelic_card_kick_txdma(card, descr)) { /* * kick failed. - * release descriptors which were just prepared + * release descriptor which was just prepared */ netdev->stats.tx_dropped++; + /* don't trigger BUG_ON() in gelic_descr_release_tx */ + descr->data_status = cpu_to_be32(GELIC_DESCR_TX_TAIL); gelic_descr_release_tx(card, descr); - gelic_descr_release_tx(card, descr->next); - card->tx_chain.tail = descr->next->next; + /* reset head */ + card->tx_chain.head = descr; + /* reset hw termination */ + descr->prev->next_descr_addr = 0; dev_info(ctodev(card), "%s: kick failure\n", __func__); } -- cgit v1.2.3-70-g09d2 From eff896ce0b4231a998d8b3aa81e846ffc4f6c0a4 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Tue, 12 Jul 2011 10:13:26 +0000 Subject: ps3_gelic: Don't kill the device on DMA failure Reset card->tx_dma_progress when lv1_net_start_tx_dma() fails or it won't send anything afterwards anymore Signed-off-by: Andre Heider Acked-by: Geoff Levand Signed-off-by: David S. Miller --- drivers/net/ps3_gelic_net.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 94422fcc857..4acc17bffc4 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -838,9 +838,11 @@ static int gelic_card_kick_txdma(struct gelic_card *card, card->tx_dma_progress = 1; status = lv1_net_start_tx_dma(bus_id(card), dev_id(card), descr->bus_addr, 0); - if (status) + if (status) { + card->tx_dma_progress = 0; dev_info(ctodev(card), "lv1_net_start_txdma failed," \ "status=%d\n", status); + } } return status; } -- cgit v1.2.3-70-g09d2 From 4f6b00e5f139d7be3ca8371b769778f94fa549dd Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Wed, 6 Jul 2011 15:58:02 +0800 Subject: r8169: adjust some registers. Define new registers and modify some existing ones. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ef1a43dd145..52ad6cea4e7 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -70,8 +70,6 @@ static const int multicast_filter_limit = 32; #define MAC_ADDR_LEN 6 #define MAX_READ_REQUEST_SHIFT 12 -#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ -#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ @@ -270,9 +268,20 @@ enum rtl_registers { TxPoll = 0x38, IntrMask = 0x3c, IntrStatus = 0x3e, + TxConfig = 0x40, - RxConfig = 0x44, +#define TXCFG_AUTO_FIFO (1 << 7) /* 8111e-vl */ +#define TXCFG_EMPTY (1 << 11) /* 8111e-vl */ + RxConfig = 0x44, +#define RX128_INT_EN (1 << 15) /* 8111c and later */ +#define RX_MULTI_EN (1 << 14) /* 8111c only */ +#define RXCFG_FIFO_SHIFT 13 + /* No threshold before first PCI xfer */ +#define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) +#define RXCFG_DMA_SHIFT 8 + /* Unlimited maximum PCI burst. */ +#define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) #define RTL_RX_CONFIG_MASK 0xff7e1880u RxMissed = 0x4c, @@ -327,12 +336,13 @@ enum rtl8168_8101_registers { #define EPHYAR_REG_SHIFT 16 #define EPHYAR_DATA_MASK 0xffff DLLPR = 0xd0, -#define PM_SWITCH (1 << 6) +#define PFM_EN (1 << 6) DBG_REG = 0xd1, #define FIX_NAK_1 (1 << 4) #define FIX_NAK_2 (1 << 3) TWSI = 0xd2, MCU = 0xd3, +#define NOW_IS_OOB (1 << 7) #define EN_NDP (1 << 3) #define EN_OOB_RESET (1 << 2) EFUSEAR = 0xdc, @@ -345,18 +355,22 @@ enum rtl8168_8101_registers { }; enum rtl8168_registers { + LED_FREQ = 0x1a, + EEE_LED = 0x1b, ERIDR = 0x70, ERIAR = 0x74, #define ERIAR_FLAG 0x80000000 #define ERIAR_WRITE_CMD 0x80000000 #define ERIAR_READ_CMD 0x00000000 #define ERIAR_ADDR_BYTE_ALIGN 4 -#define ERIAR_EXGMAC 0 -#define ERIAR_MSIX 1 -#define ERIAR_ASF 2 #define ERIAR_TYPE_SHIFT 16 -#define ERIAR_BYTEEN 0x0f -#define ERIAR_BYTEEN_SHIFT 12 +#define ERIAR_EXGMAC (0x00 << ERIAR_TYPE_SHIFT) +#define ERIAR_MSIX (0x01 << ERIAR_TYPE_SHIFT) +#define ERIAR_ASF (0x02 << ERIAR_TYPE_SHIFT) +#define ERIAR_MASK_SHIFT 12 +#define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) +#define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) +#define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) EPHY_RXER_NUM = 0x7c, OCPDR = 0xb0, /* OCP GPHY access */ #define OCPDR_WRITE_CMD 0x80000000 @@ -371,6 +385,7 @@ enum rtl8168_registers { RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ MISC = 0xf0, /* 8168e only. */ #define TXPLA_RST (1 << 29) +#define PWM_EN (1 << 22) }; enum rtl_register_content { @@ -395,6 +410,7 @@ enum rtl_register_content { RxCRC = (1 << 19), /* ChipCmdBits */ + StopReq = 0x80, CmdReset = 0x10, CmdRxEnb = 0x08, CmdTxEnb = 0x04, @@ -417,10 +433,6 @@ enum rtl_register_content { AcceptMyPhys = 0x02, AcceptAllPhys = 0x01, - /* RxConfigBits */ - RxCfgFIFOShift = 13, - RxCfgDMAShift = 8, - /* TxConfigBits */ TxInterFrameGapShift = 24, TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ @@ -712,8 +724,7 @@ static void rtl8169_down(struct net_device *dev); static void rtl8169_rx_clear(struct rtl8169_private *tp); static int rtl8169_poll(struct napi_struct *napi, int budget); -static const unsigned int rtl8169_rx_config = - (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); +static const unsigned int rtl8169_rx_config = RX_FIFO_THRESH | RX_DMA_BURST; static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) { @@ -4368,7 +4379,7 @@ static void rtl_hw_start_8105e_1(void __iomem *ioaddr, struct pci_dev *pdev) RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000); RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); - RTL_W8(DLLPR, RTL_R8(DLLPR) | PM_SWITCH); + RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); } -- cgit v1.2.3-70-g09d2 From 92fc43b4159b518f5baae57301f26d770b0834c9 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Wed, 6 Jul 2011 15:58:03 +0800 Subject: r8169: modify the flow of the hw reset. - Disable tx and rx by resetting hw, so replace rtl8169_asic_down with rtl8169_hw_reset. - RxConfig bits 0 ~ 5 have to be cleared before hw reset to avoid receiving spurious data. - Certain chips need to do some checking before reset. - Remove hw reset which is done before hw_start. It is done in close, down or device probe functions. - Move rtl8169_init_ring_indexes function into rtl_hw_reset function. The indexes of tx and rx only need to be zero when the hw resets. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 52ad6cea4e7..604f94647b6 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1071,13 +1071,6 @@ static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) RTL_W16(IntrStatus, 0xffff); } -static void rtl8169_asic_down(void __iomem *ioaddr) -{ - RTL_W8(ChipCmd, 0x00); - rtl8169_irq_mask_and_ack(ioaddr); - RTL_R16(CPlusCmd); -} - static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3337,6 +3330,11 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) } } +static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) +{ + tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; +} + static void rtl_hw_reset(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3349,8 +3347,10 @@ static void rtl_hw_reset(struct rtl8169_private *tp) for (i = 0; i < 100; i++) { if ((RTL_R8(ChipCmd) & CmdReset) == 0) break; - msleep_interruptible(1); + udelay(100); } + + rtl8169_init_ring_indexes(tp); } static int __devinit @@ -3732,6 +3732,16 @@ err_pm_runtime_put: goto out; } +static void rtl_rx_close(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + u32 rxcfg = RTL_R32(RxConfig); + + rxcfg &= ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | + AcceptMyPhys | AcceptAllPhys); + RTL_W32(RxConfig, rxcfg); +} + static void rtl8169_hw_reset(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3739,19 +3749,19 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) /* Disable interrupts */ rtl8169_irq_mask_and_ack(ioaddr); + rtl_rx_close(tp); + if (tp->mac_version == RTL_GIGA_MAC_VER_27 || tp->mac_version == RTL_GIGA_MAC_VER_28 || tp->mac_version == RTL_GIGA_MAC_VER_31) { while (RTL_R8(TxPoll) & NPQ) udelay(20); - + } else { + RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); + udelay(100); } - /* Reset the chipset */ - RTL_W8(ChipCmd, CmdReset); - - /* PCI commit */ - RTL_R8(ChipCmd); + rtl_hw_reset(tp); } static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) @@ -3771,8 +3781,6 @@ static void rtl_hw_start(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - rtl_hw_reset(tp); - tp->hw_start(dev); netif_start_queue(dev); @@ -4581,11 +4589,6 @@ err_out: return -ENOMEM; } -static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) -{ - tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; -} - static int rtl8169_init_ring(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -4713,7 +4716,7 @@ static void rtl8169_reset_task(struct work_struct *work) rtl8169_tx_clear(tp); - rtl8169_init_ring_indexes(tp); + rtl8169_hw_reset(tp); rtl_hw_start(dev); netif_wake_queue(dev); rtl8169_check_link_status(dev, tp, tp->mmio_addr); @@ -5127,7 +5130,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) * the chip, so just exit the loop. */ if (unlikely(!netif_running(dev))) { - rtl8169_asic_down(ioaddr); + rtl8169_hw_reset(tp); break; } @@ -5250,7 +5253,7 @@ static void rtl8169_down(struct net_device *dev) spin_lock_irq(&tp->lock); - rtl8169_asic_down(ioaddr); + rtl8169_hw_reset(tp); /* * At this point device interrupts can not be enabled in any function, * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, @@ -5504,7 +5507,7 @@ static void rtl_shutdown(struct pci_dev *pdev) spin_lock_irq(&tp->lock); - rtl8169_asic_down(ioaddr); + rtl8169_hw_reset(tp); spin_unlock_irq(&tp->lock); -- cgit v1.2.3-70-g09d2 From 133ac40ac26a6cba957ad5765892f0531ba6ccee Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Wed, 6 Jul 2011 15:58:05 +0800 Subject: r8169: add ERI functions. Add the ERI functions which would be used by the new chips. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 604f94647b6..a983eaaaf2e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1046,6 +1046,49 @@ static u32 rtl_csi_read(void __iomem *ioaddr, int addr) return value; } +static +void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type) +{ + unsigned int i; + + BUG_ON((addr & 3) || (mask == 0)); + RTL_W32(ERIDR, val); + RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr); + + for (i = 0; i < 100; i++) { + if (!(RTL_R32(ERIAR) & ERIAR_FLAG)) + break; + udelay(100); + } +} + +static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type) +{ + u32 value = ~0x00; + unsigned int i; + + RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr); + + for (i = 0; i < 100; i++) { + if (RTL_R32(ERIAR) & ERIAR_FLAG) { + value = RTL_R32(ERIDR); + break; + } + udelay(100); + } + + return value; +} + +static void +rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type) +{ + u32 val; + + val = rtl_eri_read(ioaddr, addr, type); + rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type); +} + static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) { u8 value = 0xff; -- cgit v1.2.3-70-g09d2 From 70090424e59652c4b2e777b533cc23134b176b83 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Wed, 6 Jul 2011 15:58:06 +0800 Subject: r8169: support RTL8111E-VL. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index a983eaaaf2e..ecfaf5634f5 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -41,6 +41,7 @@ #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" #define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw" #define FIRMWARE_8168E_2 "rtl_nic/rtl8168e-2.fw" +#define FIRMWARE_8168E_3 "rtl_nic/rtl8168e-3.fw" #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" #ifdef RTL8169_DEBUG @@ -131,6 +132,7 @@ enum mac_version { RTL_GIGA_MAC_VER_31, RTL_GIGA_MAC_VER_32, RTL_GIGA_MAC_VER_33, + RTL_GIGA_MAC_VER_34, RTL_GIGA_MAC_NONE = 0xff, }; @@ -214,7 +216,9 @@ static const struct { [RTL_GIGA_MAC_VER_32] = _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1), [RTL_GIGA_MAC_VER_33] = - _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2) + _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2), + [RTL_GIGA_MAC_VER_34] = + _R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3) }; #undef _R @@ -1151,6 +1155,39 @@ static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp) rtl_writephy(tp, MII_BMCR, val & 0xffff); } +static void rtl_link_chg_patch(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + struct net_device *dev = tp->dev; + + if (!netif_running(dev)) + return; + + if (tp->mac_version == RTL_GIGA_MAC_VER_34) { + if (RTL_R8(PHYstatus) & _1000bpsF) { + rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, + 0x00000011, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, + 0x00000005, ERIAR_EXGMAC); + } else if (RTL_R8(PHYstatus) & _100bps) { + rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, + 0x0000001f, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, + 0x00000005, ERIAR_EXGMAC); + } else { + rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, + 0x0000001f, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, + 0x0000003f, ERIAR_EXGMAC); + } + /* Reset packet filter */ + rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, + ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, + ERIAR_EXGMAC); + } +} + static void __rtl8169_check_link_status(struct net_device *dev, struct rtl8169_private *tp, void __iomem *ioaddr, bool pm) @@ -1159,6 +1196,7 @@ static void __rtl8169_check_link_status(struct net_device *dev, spin_lock_irqsave(&tp->lock, flags); if (tp->link_ok(ioaddr)) { + rtl_link_chg_patch(tp); /* This is to cancel a scheduled suspend if there's one. */ if (pm) pm_request_resume(&tp->pci_dev->dev); @@ -1687,6 +1725,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, int mac_version; } mac_info[] = { /* 8168E family. */ + { 0x7c800000, 0x2c800000, RTL_GIGA_MAC_VER_34 }, { 0x7cf00000, 0x2c200000, RTL_GIGA_MAC_VER_33 }, { 0x7cf00000, 0x2c100000, RTL_GIGA_MAC_VER_32 }, { 0x7c800000, 0x2c000000, RTL_GIGA_MAC_VER_33 }, @@ -2664,7 +2703,7 @@ static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp) rtl_patchphy(tp, 0x0d, 1 << 5); } -static void rtl8168e_hw_phy_config(struct rtl8169_private *tp) +static void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { /* Enable Delay cap */ @@ -2737,6 +2776,91 @@ static void rtl8168e_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x0d, 0x0000); } +static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) +{ + static const struct phy_reg phy_reg_init[] = { + /* Enable Delay cap */ + { 0x1f, 0x0004 }, + { 0x1f, 0x0007 }, + { 0x1e, 0x00ac }, + { 0x18, 0x0006 }, + { 0x1f, 0x0002 }, + { 0x1f, 0x0000 }, + { 0x1f, 0x0000 }, + + /* Channel estimation fine tune */ + { 0x1f, 0x0003 }, + { 0x09, 0xa20f }, + { 0x1f, 0x0000 }, + { 0x1f, 0x0000 }, + + /* Green Setting */ + { 0x1f, 0x0005 }, + { 0x05, 0x8b5b }, + { 0x06, 0x9222 }, + { 0x05, 0x8b6d }, + { 0x06, 0x8000 }, + { 0x05, 0x8b76 }, + { 0x06, 0x8000 }, + { 0x1f, 0x0000 } + }; + + rtl_apply_firmware(tp); + + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + /* For 4-corner performance improve */ + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b80); + rtl_w1w0_phy(tp, 0x17, 0x0006, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0004); + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x002d); + rtl_w1w0_phy(tp, 0x18, 0x0010, 0x0000); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x0000); + + /* improve 10M EEE waveform */ + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b86); + rtl_w1w0_phy(tp, 0x06, 0x0001, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* Improve 2-pair detection performance */ + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b85); + rtl_w1w0_phy(tp, 0x06, 0x4000, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* EEE setting */ + rtl_w1w0_eri(tp->mmio_addr, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003, + ERIAR_EXGMAC); + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b85); + rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); + rtl_writephy(tp, 0x1f, 0x0004); + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x0020); + rtl_w1w0_phy(tp, 0x06, 0x0000, 0x0100); + rtl_writephy(tp, 0x1f, 0x0002); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x0d, 0x0007); + rtl_writephy(tp, 0x0e, 0x003c); + rtl_writephy(tp, 0x0d, 0x4007); + rtl_writephy(tp, 0x0e, 0x0000); + rtl_writephy(tp, 0x0d, 0x0000); + + /* Green feature */ + rtl_writephy(tp, 0x1f, 0x0003); + rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001); + rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400); + rtl_writephy(tp, 0x1f, 0x0000); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -2856,7 +2980,10 @@ static void rtl_hw_phy_config(struct net_device *dev) break; case RTL_GIGA_MAC_VER_32: case RTL_GIGA_MAC_VER_33: - rtl8168e_hw_phy_config(tp); + rtl8168e_1_hw_phy_config(tp); + break; + case RTL_GIGA_MAC_VER_34: + rtl8168e_2_hw_phy_config(tp); break; default: @@ -3362,6 +3489,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_31: case RTL_GIGA_MAC_VER_32: case RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_34: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -3799,6 +3927,9 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) tp->mac_version == RTL_GIGA_MAC_VER_31) { while (RTL_R8(TxPoll) & NPQ) udelay(20); + } else if (tp->mac_version == RTL_GIGA_MAC_VER_34) { + while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) + udelay(100); } else { RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); udelay(100); @@ -4210,9 +4341,9 @@ static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev) rtl_enable_clock_request(pdev); } -static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev) +static void rtl_hw_start_8168e_1(void __iomem *ioaddr, struct pci_dev *pdev) { - static const struct ephy_info e_info_8168e[] = { + static const struct ephy_info e_info_8168e_1[] = { { 0x00, 0x0200, 0x0100 }, { 0x00, 0x0000, 0x0004 }, { 0x06, 0x0002, 0x0001 }, @@ -4230,7 +4361,7 @@ static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev) rtl_csi_access_enable_2(ioaddr); - rtl_ephy_init(ioaddr, e_info_8168e, ARRAY_SIZE(e_info_8168e)); + rtl_ephy_init(ioaddr, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); @@ -4245,6 +4376,44 @@ static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev) RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); } +static void rtl_hw_start_8168e_2(void __iomem *ioaddr, struct pci_dev *pdev) +{ + static const struct ephy_info e_info_8168e_2[] = { + { 0x09, 0x0000, 0x0080 }, + { 0x19, 0x0000, 0x0224 } + }; + + rtl_csi_access_enable_1(ioaddr); + + rtl_ephy_init(ioaddr, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); + + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + + rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, + ERIAR_EXGMAC); + + RTL_W8(MaxTxPacketSize, 0x27); + + rtl_disable_clock_request(pdev); + + RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); + RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); + + /* Adjust EEE LED frequency */ + RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); + + RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); + RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); + RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); +} + static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -4333,7 +4502,10 @@ static void rtl_hw_start_8168(struct net_device *dev) case RTL_GIGA_MAC_VER_32: case RTL_GIGA_MAC_VER_33: - rtl_hw_start_8168e(ioaddr, pdev); + rtl_hw_start_8168e_1(ioaddr, pdev); + break; + case RTL_GIGA_MAC_VER_34: + rtl_hw_start_8168e_2(ioaddr, pdev); break; default: -- cgit v1.2.3-70-g09d2 From d4ed95d796e5126bba51466dc07e287cebc8bd19 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Wed, 6 Jul 2011 15:58:07 +0800 Subject: r8169: fix wake on lan setting for non-8111E. Only 8111E needs enable RxConfig bit 0 ~ 3 when suspending or shutdowning for wake on lan. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ecfaf5634f5..1d250883441 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3393,8 +3393,10 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, MII_BMCR, 0x0000); - RTL_W32(RxConfig, RTL_R32(RxConfig) | - AcceptBroadcast | AcceptMulticast | AcceptMyPhys); + if (tp->mac_version == RTL_GIGA_MAC_VER_32 || + tp->mac_version == RTL_GIGA_MAC_VER_33) + RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | + AcceptMulticast | AcceptMyPhys); return; } -- cgit v1.2.3-70-g09d2 From aaa89c08d9ffa3739c93d65d98b73ec2aa2e93a5 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Wed, 6 Jul 2011 15:58:08 +0800 Subject: r8169: don't enable rx when shutdown. Only 8111b needs to enable rx when shutdowning with WoL. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1d250883441..6d7f686383f 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -5729,8 +5729,11 @@ static void rtl_shutdown(struct pci_dev *pdev) spin_unlock_irq(&tp->lock); if (system_state == SYSTEM_POWER_OFF) { - /* WoL fails with some 8168 when the receiver is disabled. */ - if (tp->features & RTL_FEATURE_WOL) { + /* WoL fails with 8168b when the receiver is disabled. */ + if ((tp->mac_version == RTL_GIGA_MAC_VER_11 || + tp->mac_version == RTL_GIGA_MAC_VER_12 || + tp->mac_version == RTL_GIGA_MAC_VER_17) && + (tp->features & RTL_FEATURE_WOL)) { pci_clear_master(pdev); RTL_W8(ChipCmd, CmdRxEnb); -- cgit v1.2.3-70-g09d2 From e542a2269f232d61270ceddd42b73a4348dee2bb Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Wed, 6 Jul 2011 15:58:04 +0800 Subject: r8169: adjust the RxConfig settings. Set the init value before reset in probe function. And then just modify the relative bits and keep the init settings. For 8110S, 8110SB, and 8110SC series, the initial value of RxConfig needs to be set after the tx/rx is enabled. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 56 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 6d7f686383f..3ddd33936aa 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -286,7 +286,6 @@ enum rtl_registers { #define RXCFG_DMA_SHIFT 8 /* Unlimited maximum PCI burst. */ #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) -#define RTL_RX_CONFIG_MASK 0xff7e1880u RxMissed = 0x4c, Cfg9346 = 0x50, @@ -728,8 +727,6 @@ static void rtl8169_down(struct net_device *dev); static void rtl8169_rx_clear(struct rtl8169_private *tp); static int rtl8169_poll(struct napi_struct *napi, int budget); -static const unsigned int rtl8169_rx_config = RX_FIFO_THRESH | RX_DMA_BURST; - static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) { void __iomem *ioaddr = tp->mmio_addr; @@ -3503,6 +3500,42 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) } } +static void rtl_init_rxcfg(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_01: + case RTL_GIGA_MAC_VER_02: + case RTL_GIGA_MAC_VER_03: + case RTL_GIGA_MAC_VER_04: + case RTL_GIGA_MAC_VER_05: + case RTL_GIGA_MAC_VER_06: + case RTL_GIGA_MAC_VER_10: + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_13: + case RTL_GIGA_MAC_VER_14: + case RTL_GIGA_MAC_VER_15: + case RTL_GIGA_MAC_VER_16: + case RTL_GIGA_MAC_VER_17: + RTL_W32(RxConfig, RX_FIFO_THRESH | RX_DMA_BURST); + break; + case RTL_GIGA_MAC_VER_18: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); + break; + default: + RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST); + break; + } +} + static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) { tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; @@ -3630,6 +3663,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (!pci_is_pcie(pdev)) netif_info(tp, probe, dev, "not PCI Express\n"); + /* Identify chip attached to board */ + rtl8169_get_mac_version(tp, dev, cfg->default_ver); + + rtl_init_rxcfg(tp); + RTL_W16(IntrMask, 0x0000); rtl_hw_reset(tp); @@ -3638,9 +3676,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); - /* Identify chip attached to board */ - rtl8169_get_mac_version(tp, dev, cfg->default_ver); - /* * Pretend we are using VLANs; This bypasses a nasty bug where * Interrupts stop flowing on high load on 8110SCd controllers. @@ -3943,10 +3978,6 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - u32 cfg = rtl8169_rx_config; - - cfg |= (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK); - RTL_W32(RxConfig, cfg); /* Set DMA burst size and Interframe Gap Time */ RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | @@ -4034,6 +4065,8 @@ static void rtl_hw_start_8169(struct net_device *dev) tp->mac_version == RTL_GIGA_MAC_VER_04) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + rtl_init_rxcfg(tp); + RTL_W8(EarlyTxThres, NoEarlyTx); rtl_set_rx_max_size(ioaddr, rx_buf_sz); @@ -5553,8 +5586,7 @@ static void rtl_set_rx_mode(struct net_device *dev) spin_lock_irqsave(&tp->lock, flags); - tmp = rtl8169_rx_config | rx_mode | - (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK); + tmp = RTL_R32(RxConfig) | rx_mode; if (tp->mac_version > RTL_GIGA_MAC_VER_06) { u32 data = mc_filter[0]; -- cgit v1.2.3-70-g09d2 From 7be08a7222c345798b0697a89ea3dd2c7c83f47c Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 14 Jul 2011 08:31:19 +0000 Subject: bnx2x: Renaming the "reset_task" to "sp_rtnl_task" Renaming the "reset_task" to a more general purpose name, "sp_rtnl_task", as it is already used for another purpose other than reset which is parity recovery, and since I plan to add a third operation for this task, updating the priority to traffic class and traffic class to transmission queues mappings after dcbx negotiation takes place. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 11 +++++++++- drivers/net/bnx2x/bnx2x_cmn.c | 7 +++++- drivers/net/bnx2x/bnx2x_main.c | 48 +++++++++++++++++++++++++----------------- 3 files changed, 45 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 0d4b9812624..16dc2c9df8b 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1046,6 +1046,12 @@ struct bnx2x_fw_stats_data { struct per_queue_stats queue_stats[1]; }; +/* Public slow path states */ +enum { + BNX2X_SP_RTNL_TX_TIMEOUT, +}; + + struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure @@ -1159,7 +1165,7 @@ struct bnx2x { int mrrs; struct delayed_work sp_task; - struct delayed_work reset_task; + struct delayed_work sp_rtnl_task; struct delayed_work period_task; struct timer_list timer; @@ -1403,6 +1409,9 @@ struct bnx2x { unsigned long sp_state; + /* operation indication for the sp_rtnl task */ + unsigned long sp_rtnl_state; + /* DCBX Negotation results */ struct dcbx_features dcbx_local_feat; u32 dcbx_error; diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index bb7556016f4..8763625b09d 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -3233,8 +3233,13 @@ void bnx2x_tx_timeout(struct net_device *dev) if (!bp->panic) bnx2x_panic(); #endif + + smp_mb__before_clear_bit(); + set_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state); + smp_mb__after_clear_bit(); + /* This allows the netif to be shutdown gracefully before resetting */ - schedule_delayed_work(&bp->reset_task, 0); + schedule_delayed_work(&bp->sp_rtnl_task, 0); } int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 5b4a8f34b13..53f4ec3d1d9 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4020,7 +4020,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) if (bnx2x_chk_parity_attn(bp, &global, true)) { #ifndef BNX2X_STOP_ON_ERROR bp->recovery_state = BNX2X_RECOVERY_INIT; - schedule_delayed_work(&bp->reset_task, 0); + schedule_delayed_work(&bp->sp_rtnl_task, 0); /* Disable HW interrupts */ bnx2x_int_disable(bp); /* In case of parity errors don't handle attentions so that @@ -7963,7 +7963,7 @@ static void bnx2x_parity_recover(struct bnx2x *bp) /* Wait until all other functions get * down. */ - schedule_delayed_work(&bp->reset_task, + schedule_delayed_work(&bp->sp_rtnl_task, HZ/10); return; } else { @@ -8000,7 +8000,7 @@ static void bnx2x_parity_recover(struct bnx2x *bp) break; } - schedule_delayed_work(&bp->reset_task, + schedule_delayed_work(&bp->sp_rtnl_task, HZ/10); return; @@ -8011,7 +8011,8 @@ static void bnx2x_parity_recover(struct bnx2x *bp) */ if (bnx2x_reset_is_global(bp)) { schedule_delayed_work( - &bp->reset_task, HZ/10); + &bp->sp_rtnl_task, + HZ/10); return; } @@ -8035,30 +8036,39 @@ static void bnx2x_parity_recover(struct bnx2x *bp) /* bnx2x_nic_unload() flushes the bnx2x_wq, thus reset task is * scheduled on a general queue in order to prevent a dead lock. */ -static void bnx2x_reset_task(struct work_struct *work) +static void bnx2x_sp_rtnl_task(struct work_struct *work) { - struct bnx2x *bp = container_of(work, struct bnx2x, reset_task.work); - -#ifdef BNX2X_STOP_ON_ERROR - BNX2X_ERR("reset task called but STOP_ON_ERROR defined" - " so reset not done to allow debug dump,\n" - KERN_ERR " you will need to reboot when done\n"); - return; -#endif + struct bnx2x *bp = container_of(work, struct bnx2x, sp_rtnl_task.work); rtnl_lock(); if (!netif_running(bp->dev)) - goto reset_task_exit; + goto sp_rtnl_exit; + + /* if stop on error is defined no recovery flows should be executed */ +#ifdef BNX2X_STOP_ON_ERROR + BNX2X_ERR("recovery flow called but STOP_ON_ERROR defined " + "so reset not done to allow debug dump,\n" + "you will need to reboot when done\n"); + goto sp_rtnl_exit; +#endif - if (unlikely(bp->recovery_state != BNX2X_RECOVERY_DONE)) + if (unlikely(bp->recovery_state != BNX2X_RECOVERY_DONE)) { + /* + * Clear TX_TIMEOUT bit as we are going to reset the function + * anyway. + */ + smp_mb__before_clear_bit(); + clear_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state); + smp_mb__after_clear_bit(); bnx2x_parity_recover(bp); - else { + } else if (test_and_clear_bit(BNX2X_SP_RTNL_TX_TIMEOUT, + &bp->sp_rtnl_state)){ bnx2x_nic_unload(bp, UNLOAD_NORMAL); bnx2x_nic_load(bp, LOAD_NORMAL); } -reset_task_exit: +sp_rtnl_exit: rtnl_unlock(); } @@ -9291,7 +9301,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) #endif INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); - INIT_DELAYED_WORK(&bp->reset_task, bnx2x_reset_task); + INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task); INIT_DELAYED_WORK(&bp->period_task, bnx2x_period_task); rc = bnx2x_get_hwinfo(bp); if (rc) @@ -10342,7 +10352,7 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) bnx2x_set_power_state(bp, PCI_D3hot); /* Make sure RESET task is not scheduled before continuing */ - cancel_delayed_work_sync(&bp->reset_task); + cancel_delayed_work_sync(&bp->sp_rtnl_task); if (bp->regview) iounmap(bp->regview); -- cgit v1.2.3-70-g09d2 From 6383c0b35b48bfbd0fc8c6fe126a6603c5a9a4b3 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 14 Jul 2011 08:31:57 +0000 Subject: bnx2x: Multiple concurrent l2 traffic classes Overview: Support mapping of priorities to traffic classes and traffic classes to transmission queues ranges in the net device. The queue ranges are (count, offset) pairs relating to the txq array. This can be done via DCBX negotiation or by kernel. As a result Enhanced Transmission Selection (ETS) and Priority Flow Control (PFC) are supported between L2 network traffic classes. Mapping: This patch uses the netdev_set_num_tc, netdev_set_prio_tc_map and netdev_set_tc_queue functions to map priorities to traffic classes and traffic classes to transmission queue ranges. This mapping is performed by bnx2x_setup_tc function which is connected to the ndo_setup_tc. This function is always called at nic load where by default it maps all priorities to tc 0, and it may also be called by the kernel or by the bnx2x upon DCBX negotiation to modify the mapping. rtnl lock: When the ndo_setup_tc is called at nic load or by kernel the rtnl lock is already taken. However, when DCBX negotiation takes place the lock is not taken. The work is therefore scheduled to be handled by the sp_rtnl task. Fastpath: The fastpath structure of the bnx2x which was previously used to hold the information of one tx queue and one rx queue was redesigned to represent multiple tx queues, one for each traffic class. The transmission queue supplied in the skb by the kernel can no longer be interpreted as a straightforward index into the fastpath structure array, but it must rather be decoded to the appropriate fastpath index and the tc within that fastpath. Slowpath: The bnx2x's queue object was redesigned to accommodate multiple transmission queues. The queue object's state machine was enhanced to allow opening multiple transmission-only connections on top of the regular tx-rx connection. Firmware: This feature relies on the tx-only queue feature introduced in the bnx2x 7.0.23 firmware and the FW likewise must have the bnx2x multi cos support. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 181 ++++++++----- drivers/net/bnx2x/bnx2x_cmn.c | 370 +++++++++++++++++++-------- drivers/net/bnx2x/bnx2x_cmn.h | 109 +++++--- drivers/net/bnx2x/bnx2x_dcb.c | 25 ++ drivers/net/bnx2x/bnx2x_ethtool.c | 27 +- drivers/net/bnx2x/bnx2x_hsi.h | 2 +- drivers/net/bnx2x/bnx2x_init.h | 19 +- drivers/net/bnx2x/bnx2x_main.c | 521 +++++++++++++++++++++++++++----------- drivers/net/bnx2x/bnx2x_sp.c | 476 ++++++++++++++++++++++++---------- drivers/net/bnx2x/bnx2x_sp.h | 70 ++++- drivers/net/bnx2x/bnx2x_stats.c | 40 ++- 11 files changed, 1316 insertions(+), 524 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 16dc2c9df8b..53fa8ea983e 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -120,6 +120,7 @@ do { \ #ifdef BNX2X_STOP_ON_ERROR +void bnx2x_int_disable(struct bnx2x *bp); #define bnx2x_panic() do { \ bp->panic = 1; \ BNX2X_ERR("driver assert\n"); \ @@ -240,21 +241,21 @@ do { \ */ /* iSCSI L2 */ #define BNX2X_ISCSI_ETH_CL_ID_IDX 1 -#define BNX2X_ISCSI_ETH_CID 17 +#define BNX2X_ISCSI_ETH_CID 49 /* FCoE L2 */ #define BNX2X_FCOE_ETH_CL_ID_IDX 2 -#define BNX2X_FCOE_ETH_CID 18 +#define BNX2X_FCOE_ETH_CID 50 /** Additional rings budgeting */ #ifdef BCM_CNIC -#define CNIC_CONTEXT_USE 1 -#define FCOE_CONTEXT_USE 1 +#define CNIC_PRESENT 1 +#define FCOE_PRESENT 1 #else -#define CNIC_CONTEXT_USE 0 -#define FCOE_CONTEXT_USE 0 +#define CNIC_PRESENT 0 +#define FCOE_PRESENT 0 #endif /* BCM_CNIC */ -#define NONE_ETH_CONTEXT_USE (FCOE_CONTEXT_USE) +#define NON_ETH_CONTEXT_USE (FCOE_PRESENT) #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR @@ -262,8 +263,35 @@ do { \ #define SM_RX_ID 0 #define SM_TX_ID 1 -/* fast path */ +/* defines for multiple tx priority indices */ +#define FIRST_TX_ONLY_COS_INDEX 1 +#define FIRST_TX_COS_INDEX 0 + +/* defines for decodeing the fastpath index and the cos index out of the + * transmission queue index + */ +#define MAX_TXQS_PER_COS FP_SB_MAX_E1x + +#define TXQ_TO_FP(txq_index) ((txq_index) % MAX_TXQS_PER_COS) +#define TXQ_TO_COS(txq_index) ((txq_index) / MAX_TXQS_PER_COS) + +/* rules for calculating the cids of tx-only connections */ +#define CID_TO_FP(cid) ((cid) % MAX_TXQS_PER_COS) +#define CID_COS_TO_TX_ONLY_CID(cid, cos) (cid + cos * MAX_TXQS_PER_COS) + +/* fp index inside class of service range */ +#define FP_COS_TO_TXQ(fp, cos) ((fp)->index + cos * MAX_TXQS_PER_COS) + +/* + * 0..15 eth cos0 + * 16..31 eth cos1 if applicable + * 32..47 eth cos2 If applicable + * fcoe queue follows eth queues (16, 32, 48 depending on cos) + */ +#define MAX_ETH_TXQ_IDX(bp) (MAX_TXQS_PER_COS * (bp)->max_cos) +#define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp)) +/* fast path */ struct sw_rx_bd { struct sk_buff *skb; DEFINE_DMA_UNMAP_ADDR(mapping); @@ -388,6 +416,29 @@ struct bnx2x_agg_info { #define Q_STATS_OFFSET32(stat_name) \ (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) +struct bnx2x_fp_txdata { + + struct sw_tx_bd *tx_buf_ring; + + union eth_tx_bd_types *tx_desc_ring; + dma_addr_t tx_desc_mapping; + + u32 cid; + + union db_prod tx_db; + + u16 tx_pkt_prod; + u16 tx_pkt_cons; + u16 tx_bd_prod; + u16 tx_bd_cons; + + unsigned long tx_pkt; + + __le16 *tx_cons_sb; + + int txq_index; +}; + struct bnx2x_fastpath { struct bnx2x *bp; /* parent */ @@ -404,10 +455,8 @@ struct bnx2x_fastpath { dma_addr_t status_blk_mapping; - struct sw_tx_bd *tx_buf_ring; - - union eth_tx_bd_types *tx_desc_ring; - dma_addr_t tx_desc_mapping; + u8 max_cos; /* actual number of active tx coses */ + struct bnx2x_fp_txdata txdata[BNX2X_MULTI_TX_COS]; struct sw_rx_bd *rx_buf_ring; /* BDs mappings ring */ struct sw_rx_page *rx_page_ring; /* SGE pages mappings ring */ @@ -426,20 +475,13 @@ struct bnx2x_fastpath { u32 cid; + __le16 fp_hc_idx; + u8 index; /* number in fp array */ u8 cl_id; /* eth client id */ u8 cl_qzone_id; u8 fw_sb_id; /* status block number in FW */ u8 igu_sb_id; /* status block number in HW */ - union db_prod tx_db; - - u16 tx_pkt_prod; - u16 tx_pkt_cons; - u16 tx_bd_prod; - u16 tx_bd_cons; - __le16 *tx_cons_sb; - - __le16 fp_hc_idx; u16 rx_bd_prod; u16 rx_bd_cons; @@ -449,8 +491,7 @@ struct bnx2x_fastpath { /* The last maximal completed SGE */ u16 last_max_sge; __le16 *rx_cons_sb; - unsigned long tx_pkt, - rx_pkt, + unsigned long rx_pkt, rx_calls; /* TPA related */ @@ -489,8 +530,12 @@ struct bnx2x_fastpath { #define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp) #define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX]) #define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var) +#define bnx2x_fcoe_tx(bp, var) (bnx2x_fcoe_fp(bp)-> \ + txdata[FIRST_TX_COS_INDEX].var) +#define IS_ETH_FP(fp) (fp->index < \ + BNX2X_NUM_ETH_QUEUES(fp->bp)) #ifdef BCM_CNIC #define IS_FCOE_FP(fp) (fp->index == FCOE_IDX) #define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX) @@ -649,18 +694,23 @@ struct bnx2x_fastpath { #define HC_INDEX_TOE_TX_CQ_CONS 4 /* Formerly Cstorm TOE CQ index */ /* (HC_INDEX_C_TOE_TX_CQ_CONS) */ -#define HC_INDEX_ETH_TX_CQ_CONS 5 /* Formerly Cstorm ETH CQ index */ +#define HC_INDEX_ETH_TX_CQ_CONS_COS0 5 /* Formerly Cstorm ETH CQ index */ + /* (HC_INDEX_C_ETH_TX_CQ_CONS) */ +#define HC_INDEX_ETH_TX_CQ_CONS_COS1 6 /* Formerly Cstorm ETH CQ index */ + /* (HC_INDEX_C_ETH_TX_CQ_CONS) */ +#define HC_INDEX_ETH_TX_CQ_CONS_COS2 7 /* Formerly Cstorm ETH CQ index */ /* (HC_INDEX_C_ETH_TX_CQ_CONS) */ -#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_ETH_RX_CQ_CONS -#define U_SB_ETH_RX_BD_INDEX HC_INDEX_ETH_RX_BD_CONS -#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_ETH_TX_CQ_CONS +#define HC_INDEX_ETH_FIRST_TX_CQ_CONS HC_INDEX_ETH_TX_CQ_CONS_COS0 + #define BNX2X_RX_SB_INDEX \ (&fp->sb_index_values[HC_INDEX_ETH_RX_CQ_CONS]) -#define BNX2X_TX_SB_INDEX \ - (&fp->sb_index_values[C_SB_ETH_TX_CQ_INDEX]) +#define BNX2X_TX_SB_INDEX_BASE BNX2X_TX_SB_INDEX_COS0 + +#define BNX2X_TX_SB_INDEX_COS0 \ + (&fp->sb_index_values[HC_INDEX_ETH_TX_CQ_CONS_COS0]) /* end of fast path */ @@ -845,25 +895,6 @@ extern struct workqueue_struct *bnx2x_wq; /* fast-path interrupt contexts E2 */ #define FP_SB_MAX_E2 HC_SB_MAX_SB_E2 -/* - * cid_cnt paramter below refers to the value returned by - * 'bnx2x_get_l2_cid_count()' routine - */ - -/* - * The number of FP context allocated by the driver == max number of regular - * L2 queues + 1 for the FCoE L2 queue - */ -#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - FCOE_CONTEXT_USE) - -/* - * The number of FP-SB allocated by the driver == max number of regular L2 - * queues + 1 for the CNIC which also consumes an FP-SB - */ -#define FP_SB_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) -#define NUM_IGU_SB_REQUIRED(cid_cnt) \ - (FP_SB_COUNT(cid_cnt) - NONE_ETH_CONTEXT_USE) - union cdu_context { struct eth_context eth; char pad[1024]; @@ -871,7 +902,7 @@ union cdu_context { /* CDU host DB constants */ #define CDU_ILT_PAGE_SZ_HW 3 -#define CDU_ILT_PAGE_SZ (4096 << CDU_ILT_PAGE_SZ_HW) /* 32K */ +#define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 64K */ #define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) #ifdef BCM_CNIC @@ -1048,6 +1079,7 @@ struct bnx2x_fw_stats_data { /* Public slow path states */ enum { + BNX2X_SP_RTNL_SETUP_TC, BNX2X_SP_RTNL_TX_TIMEOUT, }; @@ -1226,6 +1258,10 @@ struct bnx2x { #define BNX2X_STATE_ERROR 0xf000 int multi_mode; +#define BNX2X_MAX_PRIORITY 8 +#define BNX2X_MAX_ENTRIES_PER_PRI 16 +#define BNX2X_MAX_COS 3 +#define BNX2X_MAX_TX_COS 2 int num_queues; int disable_tpa; @@ -1275,11 +1311,21 @@ struct bnx2x { struct bnx2x_ilt *ilt; #define BP_ILT(bp) ((bp)->ilt) #define ILT_MAX_LINES 256 +/* + * Maximum supported number of RSS queues: number of IGU SBs minus one that goes + * to CNIC. + */ +#define BNX2X_MAX_RSS_COUNT(bp) ((bp)->igu_sb_cnt - CNIC_PRESENT) - int l2_cid_count; -#define L2_ILT_LINES(bp) (DIV_ROUND_UP((bp)->l2_cid_count, \ - ILT_PAGE_CIDS)) -#define BNX2X_DB_SIZE(bp) ((bp)->l2_cid_count * (1 << BNX2X_DB_SHIFT)) +/* + * Maximum CID count that might be required by the bnx2x: + * Max Tss * Max_Tx_Multi_Cos + CNIC L2 Clients (FCoE and iSCSI related) + */ +#define BNX2X_L2_CID_COUNT(bp) (MAX_TXQS_PER_COS * BNX2X_MULTI_TX_COS +\ + NON_ETH_CONTEXT_USE + CNIC_PRESENT) +#define L2_ILT_LINES(bp) (DIV_ROUND_UP(BNX2X_L2_CID_COUNT(bp),\ + ILT_PAGE_CIDS)) +#define BNX2X_DB_SIZE(bp) (BNX2X_L2_CID_COUNT(bp) * (1 << BNX2X_DB_SHIFT)) int qm_cid_count; @@ -1421,16 +1467,24 @@ struct bnx2x { u32 dcbx_remote_flags; #endif u32 pending_max; + + /* multiple tx classes of service */ + u8 max_cos; + + /* priority to cos mapping */ + u8 prio_to_cos[8]; }; /* Tx queues may be less or equal to Rx queues */ extern int num_queues; #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) -#define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NONE_ETH_CONTEXT_USE) +#define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NON_ETH_CONTEXT_USE) +#define BNX2X_NUM_RX_QUEUES(bp) BNX2X_NUM_QUEUES(bp) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) -#define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE) +#define BNX2X_MAX_QUEUES(bp) BNX2X_MAX_RSS_COUNT(bp) +/* #define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1) */ #define RSS_IPV4_CAP_MASK \ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY @@ -1465,35 +1519,40 @@ struct bnx2x_func_init_params { }; #define for_each_eth_queue(bp, var) \ - for (var = 0; var < BNX2X_NUM_ETH_QUEUES(bp); var++) + for ((var) = 0; (var) < BNX2X_NUM_ETH_QUEUES(bp); (var)++) #define for_each_nondefault_eth_queue(bp, var) \ - for (var = 1; var < BNX2X_NUM_ETH_QUEUES(bp); var++) + for ((var) = 1; (var) < BNX2X_NUM_ETH_QUEUES(bp); (var)++) #define for_each_queue(bp, var) \ - for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ if (skip_queue(bp, var)) \ continue; \ else +/* Skip forwarding FP */ #define for_each_rx_queue(bp, var) \ - for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ if (skip_rx_queue(bp, var)) \ continue; \ else +/* Skip OOO FP */ #define for_each_tx_queue(bp, var) \ - for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ if (skip_tx_queue(bp, var)) \ continue; \ else #define for_each_nondefault_queue(bp, var) \ - for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) \ + for ((var) = 1; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ if (skip_queue(bp, var)) \ continue; \ else +#define for_each_cos_in_tx_queue(fp, var) \ + for ((var) = 0; (var) < (fp)->max_cos; (var)++) + /* skip rx queue * if FCOE l2 support is disabled and this is the fcoe L2 queue */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 8763625b09d..e5fac6244f4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -47,6 +47,25 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int index) /* Restore the NAPI object as it has been already initialized */ fp->napi = orig_napi; + + fp->bp = bp; + fp->index = index; + if (IS_ETH_FP(fp)) + fp->max_cos = bp->max_cos; + else + /* Special queues support only one CoS */ + fp->max_cos = 1; + + /* + * set the tpa flag for each queue. The tpa flag determines the queue + * minimal size so it must be set prior to queue memory allocation + */ + fp->disable_tpa = ((bp->flags & TPA_ENABLE_FLAG) == 0); + +#ifdef BCM_CNIC + /* We don't want TPA on FCoE, FWD and OOO L2 rings */ + bnx2x_fcoe(bp, disable_tpa) = 1; +#endif } /** @@ -77,10 +96,10 @@ int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ /* free skb in the packet ring at pos idx * return idx of last bd freed */ -static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, +static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, u16 idx) { - struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx]; + struct sw_tx_bd *tx_buf = &txdata->tx_buf_ring[idx]; struct eth_tx_start_bd *tx_start_bd; struct eth_tx_bd *tx_data_bd; struct sk_buff *skb = tx_buf->skb; @@ -91,11 +110,11 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, prefetch(&skb->end); DP(BNX2X_MSG_FP, "fp[%d]: pkt_idx %d buff @(%p)->skb %p\n", - fp->index, idx, tx_buf, skb); + txdata->txq_index, idx, tx_buf, skb); /* unmap first bd */ DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); - tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd; + tx_start_bd = &txdata->tx_desc_ring[bd_idx].start_bd; dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE); @@ -126,7 +145,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, while (nbd > 0) { DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx); - tx_data_bd = &fp->tx_desc_ring[bd_idx].reg_bd; + tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd; dma_unmap_page(&bp->pdev->dev, BD_UNMAP_ADDR(tx_data_bd), BD_UNMAP_LEN(tx_data_bd), DMA_TO_DEVICE); if (--nbd) @@ -142,20 +161,19 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, return new_cons; } -int bnx2x_tx_int(struct bnx2x_fastpath *fp) +int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) { - struct bnx2x *bp = fp->bp; struct netdev_queue *txq; - u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons; + u16 hw_cons, sw_cons, bd_cons = txdata->tx_bd_cons; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) return -1; #endif - txq = netdev_get_tx_queue(bp->dev, fp->index); - hw_cons = le16_to_cpu(*fp->tx_cons_sb); - sw_cons = fp->tx_pkt_cons; + txq = netdev_get_tx_queue(bp->dev, txdata->txq_index); + hw_cons = le16_to_cpu(*txdata->tx_cons_sb); + sw_cons = txdata->tx_pkt_cons; while (sw_cons != hw_cons) { u16 pkt_cons; @@ -164,14 +182,14 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) DP(NETIF_MSG_TX_DONE, "queue[%d]: hw_cons %u sw_cons %u " " pkt_cons %u\n", - fp->index, hw_cons, sw_cons, pkt_cons); + txdata->txq_index, hw_cons, sw_cons, pkt_cons); - bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons); + bd_cons = bnx2x_free_tx_pkt(bp, txdata, pkt_cons); sw_cons++; } - fp->tx_pkt_cons = sw_cons; - fp->tx_bd_cons = bd_cons; + txdata->tx_pkt_cons = sw_cons; + txdata->tx_bd_cons = bd_cons; /* Need to make the tx_bd_cons update visible to start_xmit() * before checking for netif_tx_queue_stopped(). Without the @@ -199,7 +217,7 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) if ((netif_tx_queue_stopped(txq)) && (bp->state == BNX2X_STATE_OPEN) && - (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)) + (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) netif_tx_wake_queue(txq); __netif_tx_unlock(txq); @@ -777,6 +795,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) { struct bnx2x_fastpath *fp = fp_cookie; struct bnx2x *bp = fp->bp; + u8 cos; DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB " "[fp %d fw_sd %d igusb %d]\n", @@ -790,7 +809,10 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) /* Handle Rx and Tx according to MSI-X vector */ prefetch(fp->rx_cons_sb); - prefetch(fp->tx_cons_sb); + + for_each_cos_in_tx_queue(fp, cos) + prefetch(fp->txdata[cos].tx_cons_sb); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); @@ -1060,17 +1082,22 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) static void bnx2x_free_tx_skbs(struct bnx2x *bp) { int i; + u8 cos; for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; + for_each_cos_in_tx_queue(fp, cos) { + struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; - u16 bd_cons = fp->tx_bd_cons; - u16 sw_prod = fp->tx_pkt_prod; - u16 sw_cons = fp->tx_pkt_cons; + u16 bd_cons = txdata->tx_bd_cons; + u16 sw_prod = txdata->tx_pkt_prod; + u16 sw_cons = txdata->tx_pkt_cons; - while (sw_cons != sw_prod) { - bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons)); - sw_cons++; + while (sw_cons != sw_prod) { + bd_cons = bnx2x_free_tx_pkt(bp, txdata, + TX_BD(sw_cons)); + sw_cons++; + } } } } @@ -1174,7 +1201,7 @@ void bnx2x_free_irq(struct bnx2x *bp) { if (bp->flags & USING_MSIX_FLAG) bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) + - CNIC_CONTEXT_USE + 1); + CNIC_PRESENT + 1); else if (bp->flags & USING_MSI_FLAG) free_irq(bp->pdev->irq, bp->dev); else @@ -1196,6 +1223,7 @@ int bnx2x_enable_msix(struct bnx2x *bp) bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry); msix_vec++; #endif + /* We need separate vectors for ETH queues only (not FCoE) */ for_each_eth_queue(bp, i) { bp->msix_table[msix_vec].entry = msix_vec; DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " @@ -1203,7 +1231,7 @@ int bnx2x_enable_msix(struct bnx2x *bp) msix_vec++; } - req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_CONTEXT_USE + 1; + req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_PRESENT + 1; rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); @@ -1278,7 +1306,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) } i = BNX2X_NUM_ETH_QUEUES(bp); - offset = 1 + CNIC_CONTEXT_USE; + offset = 1 + CNIC_PRESENT; netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" " ... fp[%d] %d\n", bp->msix_table[0].vector, @@ -1393,13 +1421,12 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) /* If ethertype is FCoE or FIP - use FCoE ring */ if ((ether_type == ETH_P_FCOE) || (ether_type == ETH_P_FIP)) - return bnx2x_fcoe(bp, index); + return bnx2x_fcoe_tx(bp, txq_index); } #endif /* Select a none-FCoE queue: if FCoE is enabled, exclude FCoE L2 ring */ - return __skb_tx_hash(dev, skb, - dev->real_num_tx_queues - FCOE_CONTEXT_USE); + return __skb_tx_hash(dev, skb, BNX2X_NUM_ETH_QUEUES(bp)); } void bnx2x_set_num_queues(struct bnx2x *bp) @@ -1418,20 +1445,38 @@ void bnx2x_set_num_queues(struct bnx2x *bp) } /* Add special queues */ - bp->num_queues += NONE_ETH_CONTEXT_USE; + bp->num_queues += NON_ETH_CONTEXT_USE; } static inline int bnx2x_set_real_num_queues(struct bnx2x *bp) { - int rc, num = bp->num_queues; + int rc, tx, rx; -#ifdef BCM_CNIC - if (NO_FCOE(bp)) - num -= FCOE_CONTEXT_USE; + tx = MAX_TXQS_PER_COS * bp->max_cos; + rx = BNX2X_NUM_ETH_QUEUES(bp); +/* account for fcoe queue */ +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + rx += FCOE_PRESENT; + tx += FCOE_PRESENT; + } #endif - netif_set_real_num_tx_queues(bp->dev, num); - rc = netif_set_real_num_rx_queues(bp->dev, num); + + rc = netif_set_real_num_tx_queues(bp->dev, tx); + if (rc) { + BNX2X_ERR("Failed to set real number of Tx queues: %d\n", rc); + return rc; + } + rc = netif_set_real_num_rx_queues(bp->dev, rx); + if (rc) { + BNX2X_ERR("Failed to set real number of Rx queues: %d\n", rc); + return rc; + } + + DP(NETIF_MSG_DRV, "Setting real num queues to (tx, rx) (%d, %d)\n", + tx, rx); + return rc; } @@ -1661,28 +1706,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* must be called before memory allocation and HW init */ bnx2x_ilt_set_info(bp); - /* zero fastpath structures preserving invariants like napi which are - * allocated only once + /* + * Zero fastpath structures preserving invariants like napi, which are + * allocated only once, fp index, max_cos, bp pointer. + * Also set fp->disable_tpa. */ for_each_queue(bp, i) bnx2x_bz_fp(bp, i); + /* Set the receive queues buffer size */ bnx2x_set_rx_buf_size(bp); - /* - * set the tpa flag for each queue. The tpa flag determines the queue - * minimal size so it must be set prior to queue memory allocation - */ - for_each_queue(bp, i) - bnx2x_fp(bp, i, disable_tpa) = - ((bp->flags & TPA_ENABLE_FLAG) == 0); - -#ifdef BCM_CNIC - /* We don't want TPA on FCoE L2 ring */ - bnx2x_fcoe(bp, disable_tpa) = 1; -#endif - if (bnx2x_alloc_mem(bp)) return -ENOMEM; @@ -1696,6 +1731,12 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) LOAD_ERROR_EXIT(bp, load_error0); } + /* configure multi cos mappings in kernel. + * this configuration may be overriden by a multi class queue discipline + * or by a dcbx negotiation result. + */ + bnx2x_setup_tc(bp->dev, bp->max_cos); + bnx2x_napi_enable(bp); /* Send LOAD_REQUEST command to MCP @@ -1747,6 +1788,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) queue_delayed_work(bnx2x_wq, &bp->period_task, 0); } else bp->port.pmf = 0; + DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); /* Init Function state controlling object */ @@ -2089,6 +2131,7 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) int bnx2x_poll(struct napi_struct *napi, int budget) { int work_done = 0; + u8 cos; struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath, napi); struct bnx2x *bp = fp->bp; @@ -2101,8 +2144,10 @@ int bnx2x_poll(struct napi_struct *napi, int budget) } #endif - if (bnx2x_has_tx_work(fp)) - bnx2x_tx_int(fp); + for_each_cos_in_tx_queue(fp, cos) + if (bnx2x_tx_queue_has_work(&fp->txdata[cos])) + bnx2x_tx_int(bp, &fp->txdata[cos]); + if (bnx2x_has_rx_work(fp)) { work_done += bnx2x_rx_int(fp, budget - work_done); @@ -2164,7 +2209,7 @@ int bnx2x_poll(struct napi_struct *napi, int budget) * in Other Operating Systems(TM) */ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, - struct bnx2x_fastpath *fp, + struct bnx2x_fp_txdata *txdata, struct sw_tx_bd *tx_buf, struct eth_tx_start_bd **tx_bd, u16 hlen, u16 bd_prod, int nbd) @@ -2185,7 +2230,7 @@ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, /* now get a new data BD * (after the pbd) and fill it */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - d_tx_bd = &fp->tx_desc_ring[bd_prod].reg_bd; + d_tx_bd = &txdata->tx_desc_ring[bd_prod].reg_bd; mapping = HILO_U64(le32_to_cpu(h_tx_bd->addr_hi), le32_to_cpu(h_tx_bd->addr_lo)) + hlen; @@ -2481,8 +2526,10 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); + struct bnx2x_fastpath *fp; struct netdev_queue *txq; + struct bnx2x_fp_txdata *txdata; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd, *first_bd; struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; @@ -2490,7 +2537,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; u32 pbd_e2_parsing_data = 0; u16 pkt_prod, bd_prod; - int nbd, fp_index; + int nbd, txq_index, fp_index, txdata_index; dma_addr_t mapping; u32 xmit_type = bnx2x_xmit_type(bp, skb); int i; @@ -2504,12 +2551,43 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; #endif - fp_index = skb_get_queue_mapping(skb); - txq = netdev_get_tx_queue(dev, fp_index); + txq_index = skb_get_queue_mapping(skb); + txq = netdev_get_tx_queue(dev, txq_index); + + BUG_ON(txq_index >= MAX_ETH_TXQ_IDX(bp) + FCOE_PRESENT); + + /* decode the fastpath index and the cos index from the txq */ + fp_index = TXQ_TO_FP(txq_index); + txdata_index = TXQ_TO_COS(txq_index); + +#ifdef BCM_CNIC + /* + * Override the above for the FCoE queue: + * - FCoE fp entry is right after the ETH entries. + * - FCoE L2 queue uses bp->txdata[0] only. + */ + if (unlikely(!NO_FCOE(bp) && (txq_index == + bnx2x_fcoe_tx(bp, txq_index)))) { + fp_index = FCOE_IDX; + txdata_index = 0; + } +#endif + + /* enable this debug print to view the transmission queue being used + DP(BNX2X_MSG_FP, "indices: txq %d, fp %d, txdata %d", + txq_index, fp_index, txdata_index); */ + /* locate the fastpath and the txdata */ fp = &bp->fp[fp_index]; + txdata = &fp->txdata[txdata_index]; + + /* enable this debug print to view the tranmission details + DP(BNX2X_MSG_FP,"transmitting packet cid %d fp index %d txdata_index %d" + " tx_data ptr %p fp pointer %p", + txdata->cid, fp_index, txdata_index, txdata, fp); */ - if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) { + if (unlikely(bnx2x_tx_avail(bp, txdata) < + (skb_shinfo(skb)->nr_frags + 3))) { fp->eth_q_stats.driver_xoff++; netif_tx_stop_queue(txq); BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); @@ -2518,7 +2596,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) DP(NETIF_MSG_TX_QUEUED, "queue[%d]: SKB: summed %x protocol %x " "protocol(%x,%x) gso type %x xmit_type %x\n", - fp_index, skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, + txq_index, skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); eth = (struct ethhdr *)skb->data; @@ -2567,15 +2645,15 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) /* get current pkt produced now - advance it just before sending packet * since mapping of pages may fail and cause packet to be dropped */ - pkt_prod = fp->tx_pkt_prod; - bd_prod = TX_BD(fp->tx_bd_prod); + pkt_prod = txdata->tx_pkt_prod; + bd_prod = TX_BD(txdata->tx_bd_prod); /* get a tx_buf and first BD * tx_start_bd may be changed during SPLIT, * but first_bd will always stay first */ - tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)]; - tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; + tx_buf = &txdata->tx_buf_ring[TX_BD(pkt_prod)]; + tx_start_bd = &txdata->tx_desc_ring[bd_prod].start_bd; first_bd = tx_start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; @@ -2586,13 +2664,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_HDR_NBDS, 1); /* remember the first BD of the packet */ - tx_buf->first_bd = fp->tx_bd_prod; + tx_buf->first_bd = txdata->tx_bd_prod; tx_buf->skb = skb; tx_buf->flags = 0; DP(NETIF_MSG_TX_QUEUED, "sending pkt %u @%p next_idx %u bd %u @%p\n", - pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); + pkt_prod, tx_buf, txdata->tx_pkt_prod, bd_prod, tx_start_bd); if (vlan_tx_tag_present(skb)) { tx_start_bd->vlan_or_ethertype = @@ -2609,7 +2687,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) bnx2x_set_sbd_csum(bp, skb, tx_start_bd, xmit_type); if (!CHIP_IS_E1x(bp)) { - pbd_e2 = &fp->tx_desc_ring[bd_prod].parse_bd_e2; + pbd_e2 = &txdata->tx_desc_ring[bd_prod].parse_bd_e2; memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) @@ -2631,7 +2709,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) eth->h_dest); } } else { - pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; + pbd_e1x = &txdata->tx_desc_ring[bd_prod].parse_bd_e1x; memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) @@ -2663,8 +2741,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO; if (unlikely(skb_headlen(skb) > hlen)) - bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, - hlen, bd_prod, ++nbd); + bd_prod = bnx2x_tx_split(bp, txdata, tx_buf, + &tx_start_bd, hlen, + bd_prod, ++nbd); if (!CHIP_IS_E1x(bp)) bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, xmit_type); @@ -2698,14 +2777,15 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) * before call to bnx2x_free_tx_pkt */ first_bd->nbd = cpu_to_le16(nbd); - bnx2x_free_tx_pkt(bp, fp, TX_BD(fp->tx_pkt_prod)); + bnx2x_free_tx_pkt(bp, txdata, + TX_BD(txdata->tx_pkt_prod)); return NETDEV_TX_OK; } bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - tx_data_bd = &fp->tx_desc_ring[bd_prod].reg_bd; + tx_data_bd = &txdata->tx_desc_ring[bd_prod].reg_bd; if (total_pkt_bd == NULL) - total_pkt_bd = &fp->tx_desc_ring[bd_prod].reg_bd; + total_pkt_bd = &txdata->tx_desc_ring[bd_prod].reg_bd; tx_data_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_data_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); @@ -2759,7 +2839,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) pbd_e2->parsing_data); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); - fp->tx_pkt_prod++; + txdata->tx_pkt_prod++; /* * Make sure that the BD data is updated before updating the producer * since FW might read the BD right after the producer is updated. @@ -2769,16 +2849,16 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) */ wmb(); - fp->tx_db.data.prod += nbd; + txdata->tx_db.data.prod += nbd; barrier(); - DOORBELL(bp, fp->cid, fp->tx_db.raw); + DOORBELL(bp, txdata->cid, txdata->tx_db.raw); mmiowb(); - fp->tx_bd_prod += nbd; + txdata->tx_bd_prod += nbd; - if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { + if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { netif_tx_stop_queue(txq); /* paired memory barrier is in bnx2x_tx_int(), we have to keep @@ -2787,14 +2867,81 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) smp_mb(); fp->eth_q_stats.driver_xoff++; - if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) + if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) netif_tx_wake_queue(txq); } - fp->tx_pkt++; + txdata->tx_pkt++; return NETDEV_TX_OK; } +/** + * bnx2x_setup_tc - routine to configure net_device for multi tc + * + * @netdev: net device to configure + * @tc: number of traffic classes to enable + * + * callback connected to the ndo_setup_tc function pointer + */ +int bnx2x_setup_tc(struct net_device *dev, u8 num_tc) +{ + int cos, prio, count, offset; + struct bnx2x *bp = netdev_priv(dev); + + /* setup tc must be called under rtnl lock */ + ASSERT_RTNL(); + + /* no traffic classes requested. aborting */ + if (!num_tc) { + netdev_reset_tc(dev); + return 0; + } + + /* requested to support too many traffic classes */ + if (num_tc > bp->max_cos) { + DP(NETIF_MSG_TX_ERR, "support for too many traffic classes" + " requested: %d. max supported is %d", + num_tc, bp->max_cos); + return -EINVAL; + } + + /* declare amount of supported traffic classes */ + if (netdev_set_num_tc(dev, num_tc)) { + DP(NETIF_MSG_TX_ERR, "failed to declare %d traffic classes", + num_tc); + return -EINVAL; + } + + /* configure priority to traffic class mapping */ + for (prio = 0; prio < BNX2X_MAX_PRIORITY; prio++) { + netdev_set_prio_tc_map(dev, prio, bp->prio_to_cos[prio]); + DP(BNX2X_MSG_SP, "mapping priority %d to tc %d", + prio, bp->prio_to_cos[prio]); + } + + + /* Use this configuration to diffrentiate tc0 from other COSes + This can be used for ets or pfc, and save the effort of setting + up a multio class queue disc or negotiating DCBX with a switch + netdev_set_prio_tc_map(dev, 0, 0); + DP(BNX2X_MSG_SP, "mapping priority %d to tc %d", 0, 0); + for (prio = 1; prio < 16; prio++) { + netdev_set_prio_tc_map(dev, prio, 1); + DP(BNX2X_MSG_SP, "mapping priority %d to tc %d", prio, 1); + } */ + + /* configure traffic class to transmission queue mapping */ + for (cos = 0; cos < bp->max_cos; cos++) { + count = BNX2X_NUM_ETH_QUEUES(bp); + offset = cos * MAX_TXQS_PER_COS; + netdev_set_tc_queue(dev, cos, count, offset); + DP(BNX2X_MSG_SP, "mapping tc %d to offset %d count %d", + cos, offset, count); + } + + return 0; +} + /* called with rtnl_lock */ int bnx2x_change_mac_addr(struct net_device *dev, void *p) { @@ -2823,6 +2970,7 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) { union host_hc_status_block *sb = &bnx2x_fp(bp, fp_index, status_blk); struct bnx2x_fastpath *fp = &bp->fp[fp_index]; + u8 cos; /* Common */ #ifdef BCM_CNIC @@ -2871,10 +3019,18 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) /* Tx */ if (!skip_tx_queue(bp, fp_index)) { /* fastpath tx rings: tx_buf tx_desc */ - BNX2X_FREE(bnx2x_fp(bp, fp_index, tx_buf_ring)); - BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, tx_desc_ring), - bnx2x_fp(bp, fp_index, tx_desc_mapping), - sizeof(union eth_tx_bd_types) * NUM_TX_BD); + for_each_cos_in_tx_queue(fp, cos) { + struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; + + DP(BNX2X_MSG_SP, + "freeing tx memory of fp %d cos %d cid %d", + fp_index, cos, txdata->cid); + + BNX2X_FREE(txdata->tx_buf_ring); + BNX2X_PCI_FREE(txdata->tx_desc_ring, + txdata->tx_desc_mapping, + sizeof(union eth_tx_bd_types) * NUM_TX_BD); + } } /* end of fastpath */ } @@ -2907,19 +3063,17 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) union host_hc_status_block *sb; struct bnx2x_fastpath *fp = &bp->fp[index]; int ring_size = 0; + u8 cos; /* if rx_ring_size specified - use it */ int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : - MAX_RX_AVAIL/bp->num_queues; + MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp); /* allocate at least number of buffers required by FW */ - rx_ring_size = max_t(int, fp->disable_tpa ? MIN_RX_SIZE_NONTPA : + rx_ring_size = max_t(int, bp->disable_tpa ? MIN_RX_SIZE_NONTPA : MIN_RX_SIZE_TPA, rx_ring_size); - bnx2x_fp(bp, index, bp) = bp; - bnx2x_fp(bp, index, index) = index; - /* Common */ sb = &bnx2x_fp(bp, index, status_blk); #ifdef BCM_CNIC @@ -2947,11 +3101,19 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) /* Tx */ if (!skip_tx_queue(bp, index)) { /* fastpath tx rings: tx_buf tx_desc */ - BNX2X_ALLOC(bnx2x_fp(bp, index, tx_buf_ring), + for_each_cos_in_tx_queue(fp, cos) { + struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; + + DP(BNX2X_MSG_SP, "allocating tx memory of " + "fp %d cos %d", + index, cos); + + BNX2X_ALLOC(txdata->tx_buf_ring, sizeof(struct sw_tx_bd) * NUM_TX_BD); - BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, tx_desc_ring), - &bnx2x_fp(bp, index, tx_desc_mapping), + BNX2X_PCI_ALLOC(txdata->tx_desc_ring, + &txdata->tx_desc_mapping, sizeof(union eth_tx_bd_types) * NUM_TX_BD); + } } /* Rx */ @@ -2994,7 +3156,7 @@ alloc_mem_err: index, ring_size); /* FW will drop all packets if queue is not big enough, * In these cases we disable the queue - * Min size diferent for TPA and non-TPA queues + * Min size is different for OOO, TPA and non-TPA queues */ if (ring_size < (fp->disable_tpa ? MIN_RX_SIZE_NONTPA : MIN_RX_SIZE_TPA)) { @@ -3012,12 +3174,14 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) /** * 1. Allocate FP for leading - fatal if error * 2. {CNIC} Allocate FCoE FP - fatal if error - * 3. Allocate RSS - fix number of queues if error + * 3. {CNIC} Allocate OOO + FWD - disable OOO if error + * 4. Allocate RSS - fix number of queues if error */ /* leading */ if (bnx2x_alloc_fp_mem_at(bp, 0)) return -ENOMEM; + #ifdef BCM_CNIC if (!NO_FCOE(bp)) /* FCoE */ @@ -3027,6 +3191,7 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) */ return -ENOMEM; #endif + /* RSS */ for_each_nondefault_eth_queue(bp, i) if (bnx2x_alloc_fp_mem_at(bp, i)) @@ -3044,7 +3209,7 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) * FCOE_IDX < FWD_IDX < OOO_IDX */ - /* move FCoE fp */ + /* move FCoE fp even NO_FCOE_FLAG is on */ bnx2x_move_fp(bp, FCOE_IDX, FCOE_IDX - delta); #endif bp->num_queues -= delta; @@ -3067,16 +3232,23 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) struct bnx2x_fastpath *fp; struct msix_entry *tbl; struct bnx2x_ilt *ilt; + int msix_table_size = 0; + + /* + * The biggest MSI-X table we might need is as a maximum number of fast + * path IGU SBs plus default SB (for PF). + */ + msix_table_size = bp->igu_sb_cnt + 1; - /* fp array */ - fp = kzalloc(L2_FP_COUNT(bp->l2_cid_count)*sizeof(*fp), GFP_KERNEL); + /* fp array: RSS plus CNIC related L2 queues */ + fp = kzalloc((BNX2X_MAX_RSS_COUNT(bp) + NON_ETH_CONTEXT_USE) * + sizeof(*fp), GFP_KERNEL); if (!fp) goto alloc_err; bp->fp = fp; /* msix table */ - tbl = kzalloc((FP_SB_COUNT(bp->l2_cid_count) + 1) * sizeof(*tbl), - GFP_KERNEL); + tbl = kzalloc(msix_table_size * sizeof(*tbl), GFP_KERNEL); if (!tbl) goto alloc_err; bp->msix_table = tbl; diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index c016e20c5c2..595d4cdada3 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -439,6 +439,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode); /* hard_xmit callback */ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); +/* setup_tc callback */ +int bnx2x_setup_tc(struct net_device *dev, u8 num_tc); + /* select_queue callback */ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); @@ -454,7 +457,7 @@ void bnx2x_update_rx_prod(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 bd_prod, u16 rx_comp_prod, u16 rx_sge_prod); /* NAPI poll Tx part */ -int bnx2x_tx_int(struct bnx2x_fastpath *fp); +int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata); /* suspend/resume callbacks */ int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); @@ -715,21 +718,22 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp) return bnx2x_igu_ack_int(bp); } -static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) +static inline int bnx2x_has_tx_work_unload(struct bnx2x_fp_txdata *txdata) { /* Tell compiler that consumer and producer can change */ barrier(); - return fp->tx_pkt_prod != fp->tx_pkt_cons; + return txdata->tx_pkt_prod != txdata->tx_pkt_cons; } -static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) +static inline u16 bnx2x_tx_avail(struct bnx2x *bp, + struct bnx2x_fp_txdata *txdata) { s16 used; u16 prod; u16 cons; - prod = fp->tx_bd_prod; - cons = fp->tx_bd_cons; + prod = txdata->tx_bd_prod; + cons = txdata->tx_bd_cons; /* NUM_TX_RINGS = number of "next-page" entries It will be used as a threshold */ @@ -737,21 +741,30 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) #ifdef BNX2X_STOP_ON_ERROR WARN_ON(used < 0); - WARN_ON(used > fp->bp->tx_ring_size); - WARN_ON((fp->bp->tx_ring_size - used) > MAX_TX_AVAIL); + WARN_ON(used > bp->tx_ring_size); + WARN_ON((bp->tx_ring_size - used) > MAX_TX_AVAIL); #endif - return (s16)(fp->bp->tx_ring_size) - used; + return (s16)(bp->tx_ring_size) - used; } -static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) +static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) { u16 hw_cons; /* Tell compiler that status block fields can change */ barrier(); - hw_cons = le16_to_cpu(*fp->tx_cons_sb); - return hw_cons != fp->tx_pkt_cons; + hw_cons = le16_to_cpu(*txdata->tx_cons_sb); + return hw_cons != txdata->tx_pkt_cons; +} + +static inline bool bnx2x_has_tx_work(struct bnx2x_fastpath *fp) +{ + u8 cos; + for_each_cos_in_tx_queue(fp, cos) + if (bnx2x_tx_queue_has_work(&fp->txdata[cos])) + return true; + return false; } static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) @@ -963,7 +976,10 @@ static inline int bnx2x_func_start(struct bnx2x *bp) /* Function parameters */ start_params->mf_mode = bp->mf_mode; start_params->sd_vlan_tag = bp->mf_ov; + if (CHIP_IS_E1x(bp)) start_params->network_cos_mode = OVERRIDE_COS; + else + start_params->network_cos_mode = STATIC_COS; return bnx2x_func_state_change(bp, &func_params); } @@ -1023,39 +1039,41 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, } } -static inline void bnx2x_init_tx_ring_one(struct bnx2x_fastpath *fp) +static inline void bnx2x_init_tx_ring_one(struct bnx2x_fp_txdata *txdata) { int i; for (i = 1; i <= NUM_TX_RINGS; i++) { struct eth_tx_next_bd *tx_next_bd = - &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd; + &txdata->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd; tx_next_bd->addr_hi = - cpu_to_le32(U64_HI(fp->tx_desc_mapping + + cpu_to_le32(U64_HI(txdata->tx_desc_mapping + BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); tx_next_bd->addr_lo = - cpu_to_le32(U64_LO(fp->tx_desc_mapping + + cpu_to_le32(U64_LO(txdata->tx_desc_mapping + BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); } - SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1); - fp->tx_db.data.zero_fill1 = 0; - fp->tx_db.data.prod = 0; + SET_FLAG(txdata->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1); + txdata->tx_db.data.zero_fill1 = 0; + txdata->tx_db.data.prod = 0; - fp->tx_pkt_prod = 0; - fp->tx_pkt_cons = 0; - fp->tx_bd_prod = 0; - fp->tx_bd_cons = 0; - fp->tx_pkt = 0; + txdata->tx_pkt_prod = 0; + txdata->tx_pkt_cons = 0; + txdata->tx_bd_prod = 0; + txdata->tx_bd_cons = 0; + txdata->tx_pkt = 0; } static inline void bnx2x_init_tx_rings(struct bnx2x *bp) { int i; + u8 cos; for_each_tx_queue(bp, i) - bnx2x_init_tx_ring_one(&bp->fp[i]); + for_each_cos_in_tx_queue(&bp->fp[i], cos) + bnx2x_init_tx_ring_one(&bp->fp[i].txdata[cos]); } static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) @@ -1257,12 +1275,23 @@ static inline u32 bnx2x_rx_ustorm_prods_offset(struct bnx2x_fastpath *fp) return USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); } +static inline void bnx2x_init_txdata(struct bnx2x *bp, + struct bnx2x_fp_txdata *txdata, u32 cid, int txq_index, + __le16 *tx_cons_sb) +{ + txdata->cid = cid; + txdata->txq_index = txq_index; + txdata->tx_cons_sb = tx_cons_sb; + + DP(BNX2X_MSG_SP, "created tx data cid %d, txq %d", + txdata->cid, txdata->txq_index); +} #ifdef BCM_CNIC static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx) { return bp->cnic_base_cl_id + cl_idx + - (bp->pf_num >> 1) * NONE_ETH_CONTEXT_USE; + (bp->pf_num >> 1) * NON_ETH_CONTEXT_USE; } static inline u8 bnx2x_cnic_fw_sb_id(struct bnx2x *bp) @@ -1293,10 +1322,13 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID; bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; - bnx2x_fcoe(bp, bp) = bp; - bnx2x_fcoe(bp, index) = FCOE_IDX; bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; - bnx2x_fcoe(bp, tx_cons_sb) = BNX2X_FCOE_L2_TX_INDEX; + + bnx2x_init_txdata(bp, &bnx2x_fcoe(bp, txdata[0]), + fp->cid, FCOE_TXQ_IDX(bp), BNX2X_FCOE_L2_TX_INDEX); + + DP(BNX2X_MSG_SP, "created fcoe tx data (fp index %d)", fp->index); + /* qZone id equals to FW (per path) client id */ bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fp_qzone_id(fp); /* init shortcut */ @@ -1306,9 +1338,13 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) /* Configure Queue State object */ __set_bit(BNX2X_Q_TYPE_HAS_RX, &q_type); __set_bit(BNX2X_Q_TYPE_HAS_TX, &q_type); - bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, fp->cid, BP_FUNC(bp), - bnx2x_sp(bp, q_rdata), bnx2x_sp_mapping(bp, q_rdata), - q_type); + + /* No multi-CoS for FCoE L2 client */ + BUG_ON(fp->max_cos != 1); + + bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, &fp->cid, 1, + BP_FUNC(bp), bnx2x_sp(bp, q_rdata), + bnx2x_sp_mapping(bp, q_rdata), q_type); DP(NETIF_MSG_IFUP, "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d fw_sb %d " "igu_sb %d\n", @@ -1318,15 +1354,16 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) #endif static inline int bnx2x_clean_tx_queue(struct bnx2x *bp, - struct bnx2x_fastpath *fp) + struct bnx2x_fp_txdata *txdata) { int cnt = 1000; - while (bnx2x_has_tx_work_unload(fp)) { + while (bnx2x_has_tx_work_unload(txdata)) { if (!cnt) { BNX2X_ERR("timeout waiting for queue[%d]: " - "fp->tx_pkt_prod(%d) != fp->tx_pkt_cons(%d)\n", - fp->index, fp->tx_pkt_prod, fp->tx_pkt_cons); + "txdata->tx_pkt_prod(%d) != txdata->tx_pkt_cons(%d)\n", + txdata->txq_index, txdata->tx_pkt_prod, + txdata->tx_pkt_cons); #ifdef BNX2X_STOP_ON_ERROR bnx2x_panic(); return -EBUSY; diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 45cf3ceef14..3bfba44961d 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -653,6 +653,26 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) } } +static inline void bnx2x_dcbx_update_tc_mapping(struct bnx2x *bp) +{ + u8 prio, cos; + for (cos = 0; cos < bp->dcbx_port_params.ets.num_of_cos; cos++) { + for (prio = 0; prio < BNX2X_MAX_PRIORITY; prio++) { + if (bp->dcbx_port_params.ets.cos_params[cos].pri_bitmask + & (1 << prio)) { + bp->prio_to_cos[prio] = cos; + } + } + } + + /* setup tc must be called under rtnl lock, but we can't take it here + * as we are handling an attetntion on a work queue which must be + * flushed at some rtnl-locked contexts (e.g. if down) + */ + if (!test_and_set_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state)) + schedule_delayed_work(&bp->sp_rtnl_task, 0); +} + void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) { switch (state) { @@ -690,6 +710,11 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) #endif bnx2x_dcbx_stop_hw_tx(bp); + /* reconfigure the netdevice with the results of the new + * dcbx negotiation. + */ + bnx2x_dcbx_update_tc_mapping(bp); + return; } case BNX2X_DCBX_STATE_TX_PAUSED: diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 1a3ed418946..ac0223135b7 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1616,6 +1616,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) unsigned char *packet; struct bnx2x_fastpath *fp_rx = &bp->fp[0]; struct bnx2x_fastpath *fp_tx = &bp->fp[0]; + struct bnx2x_fp_txdata *txdata = &fp_tx->txdata[0]; u16 tx_start_idx, tx_idx; u16 rx_start_idx, rx_idx; u16 pkt_prod, bd_prod, rx_comp_cons; @@ -1670,17 +1671,17 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) /* send the loopback packet */ num_pkts = 0; - tx_start_idx = le16_to_cpu(*fp_tx->tx_cons_sb); + tx_start_idx = le16_to_cpu(*txdata->tx_cons_sb); rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb); - pkt_prod = fp_tx->tx_pkt_prod++; - tx_buf = &fp_tx->tx_buf_ring[TX_BD(pkt_prod)]; - tx_buf->first_bd = fp_tx->tx_bd_prod; + pkt_prod = txdata->tx_pkt_prod++; + tx_buf = &txdata->tx_buf_ring[TX_BD(pkt_prod)]; + tx_buf->first_bd = txdata->tx_bd_prod; tx_buf->skb = skb; tx_buf->flags = 0; - bd_prod = TX_BD(fp_tx->tx_bd_prod); - tx_start_bd = &fp_tx->tx_desc_ring[bd_prod].start_bd; + bd_prod = TX_BD(txdata->tx_bd_prod); + tx_start_bd = &txdata->tx_desc_ring[bd_prod].start_bd; tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */ @@ -1697,27 +1698,27 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; - pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2; + pbd_e1x = &txdata->tx_desc_ring[bd_prod].parse_bd_e1x; + pbd_e2 = &txdata->tx_desc_ring[bd_prod].parse_bd_e2; memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); wmb(); - fp_tx->tx_db.data.prod += 2; + txdata->tx_db.data.prod += 2; barrier(); - DOORBELL(bp, fp_tx->index, fp_tx->tx_db.raw); + DOORBELL(bp, txdata->cid, txdata->tx_db.raw); mmiowb(); barrier(); num_pkts++; - fp_tx->tx_bd_prod += 2; /* start + pbd */ + txdata->tx_bd_prod += 2; /* start + pbd */ udelay(100); - tx_idx = le16_to_cpu(*fp_tx->tx_cons_sb); + tx_idx = le16_to_cpu(*txdata->tx_cons_sb); if (tx_idx != tx_start_idx + num_pkts) goto test_loopback_exit; @@ -1731,7 +1732,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) * bnx2x_tx_int()), as both are taking netif_tx_lock(). */ local_bh_disable(); - bnx2x_tx_int(fp_tx); + bnx2x_tx_int(bp, txdata); local_bh_enable(); } diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 0692d75756d..ce3b5662ca5 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -2545,7 +2545,7 @@ struct host_func_stats { #define BCM_5710_FW_MAJOR_VERSION 7 #define BCM_5710_FW_MINOR_VERSION 0 -#define BCM_5710_FW_REVISION_VERSION 20 +#define BCM_5710_FW_REVISION_VERSION 23 #define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index df9f196dd6e..82795a8349f 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -128,11 +128,10 @@ enum { MODE_MF_NIV = 0x00000800, MODE_E3_A0 = 0x00001000, MODE_E3_B0 = 0x00002000, - MODE_COS_BC = 0x00004000, - MODE_COS3 = 0x00008000, - MODE_COS6 = 0x00010000, - MODE_LITTLE_ENDIAN = 0x00020000, - MODE_BIG_ENDIAN = 0x00040000, + MODE_COS3 = 0x00004000, + MODE_COS6 = 0x00008000, + MODE_LITTLE_ENDIAN = 0x00010000, + MODE_BIG_ENDIAN = 0x00020000, }; /* Init Blocks */ @@ -179,7 +178,7 @@ enum { #define BNX2X_TOE_Q 3 #define BNX2X_TOE_ACK_Q 6 #define BNX2X_ISCSI_Q 9 -#define BNX2X_ISCSI_ACK_Q 8 +#define BNX2X_ISCSI_ACK_Q 11 #define BNX2X_FCOE_Q 10 /* Vnics per mode */ @@ -257,14 +256,16 @@ static inline void bnx2x_map_q_cos(struct bnx2x *bp, u32 q_num, u32 new_cos) } /* Configures the QM according to the specified per-traffic-type COSes */ -static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, +static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode, struct priority_cos *traffic_cos) { bnx2x_map_q_cos(bp, BNX2X_FCOE_Q, traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos); bnx2x_map_q_cos(bp, BNX2X_ISCSI_Q, traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); - if (INIT_MODE_FLAGS(bp) & MODE_COS_BC) { + bnx2x_map_q_cos(bp, BNX2X_ISCSI_ACK_Q, + traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); + if (mode != STATIC_COS) { /* required only in backward compatible COS mode */ bnx2x_map_q_cos(bp, BNX2X_ETH_Q, traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); @@ -272,8 +273,6 @@ static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); bnx2x_map_q_cos(bp, BNX2X_TOE_ACK_Q, traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); - bnx2x_map_q_cos(bp, BNX2X_ISCSI_ACK_Q, - traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); } } diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 53f4ec3d1d9..8a374a77cdc 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -767,6 +767,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) int func = BP_FUNC(bp); #ifdef BNX2X_STOP_ON_ERROR u16 start = 0, end = 0; + u8 cos; #endif bp->stats_state = STATS_STATE_DISABLED; @@ -822,8 +823,9 @@ void bnx2x_panic_dump(struct bnx2x *bp) CHIP_IS_E1x(bp) ? sb_data_e1x.index_data : sb_data_e2.index_data; - int data_size; + u8 data_size, cos; u32 *sb_data_p; + struct bnx2x_fp_txdata txdata; /* Rx */ BNX2X_ERR("fp%d: rx_bd_prod(0x%x) rx_bd_cons(0x%x)" @@ -838,11 +840,17 @@ void bnx2x_panic_dump(struct bnx2x *bp) le16_to_cpu(fp->fp_hc_idx)); /* Tx */ - BNX2X_ERR("fp%d: tx_pkt_prod(0x%x) tx_pkt_cons(0x%x)" - " tx_bd_prod(0x%x) tx_bd_cons(0x%x)" - " *tx_cons_sb(0x%x)\n", - i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, - fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); + for_each_cos_in_tx_queue(fp, cos) + { + txdata = fp->txdata[cos]; + BNX2X_ERR("fp%d: tx_pkt_prod(0x%x) tx_pkt_cons(0x%x)" + " tx_bd_prod(0x%x) tx_bd_cons(0x%x)" + " *tx_cons_sb(0x%x)\n", + i, txdata.tx_pkt_prod, + txdata.tx_pkt_cons, txdata.tx_bd_prod, + txdata.tx_bd_cons, + le16_to_cpu(*txdata.tx_cons_sb)); + } loop = CHIP_IS_E1x(bp) ? HC_SB_MAX_INDICES_E1X : HC_SB_MAX_INDICES_E2; @@ -961,23 +969,31 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* Tx */ for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; + for_each_cos_in_tx_queue(fp, cos) { + struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; + + start = TX_BD(le16_to_cpu(*txdata->tx_cons_sb) - 10); + end = TX_BD(le16_to_cpu(*txdata->tx_cons_sb) + 245); + for (j = start; j != end; j = TX_BD(j + 1)) { + struct sw_tx_bd *sw_bd = + &txdata->tx_buf_ring[j]; + + BNX2X_ERR("fp%d: txdata %d, " + "packet[%x]=[%p,%x]\n", + i, cos, j, sw_bd->skb, + sw_bd->first_bd); + } - start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10); - end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245); - for (j = start; j != end; j = TX_BD(j + 1)) { - struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j]; - - BNX2X_ERR("fp%d: packet[%x]=[%p,%x]\n", - i, j, sw_bd->skb, sw_bd->first_bd); - } - - start = TX_BD(fp->tx_bd_cons - 10); - end = TX_BD(fp->tx_bd_cons + 254); - for (j = start; j != end; j = TX_BD(j + 1)) { - u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j]; + start = TX_BD(txdata->tx_bd_cons - 10); + end = TX_BD(txdata->tx_bd_cons + 254); + for (j = start; j != end; j = TX_BD(j + 1)) { + u32 *tx_bd = (u32 *)&txdata->tx_desc_ring[j]; - BNX2X_ERR("fp%d: tx_bd[%x]=[%x:%x:%x:%x]\n", - i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]); + BNX2X_ERR("fp%d: txdata %d, tx_bd[%x]=" + "[%x:%x:%x:%x]\n", + i, cos, j, tx_bd[0], tx_bd[1], + tx_bd[2], tx_bd[3]); + } } } #endif @@ -1533,7 +1549,7 @@ static void bnx2x_igu_int_disable(struct bnx2x *bp) BNX2X_ERR("BUG! proper val not read from IGU!\n"); } -static void bnx2x_int_disable(struct bnx2x *bp) +void bnx2x_int_disable(struct bnx2x *bp) { if (bp->common.int_block == INT_BLOCK_HC) bnx2x_hc_int_disable(bp); @@ -1663,6 +1679,11 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) drv_cmd = BNX2X_Q_CMD_SETUP; break; + case (RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP): + DP(NETIF_MSG_IFUP, "got MULTI[%d] tx-only setup ramrod\n", cid); + drv_cmd = BNX2X_Q_CMD_SETUP_TX_ONLY; + break; + case (RAMROD_CMD_ID_ETH_HALT): DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", cid); drv_cmd = BNX2X_Q_CMD_HALT; @@ -1722,6 +1743,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) u16 status = bnx2x_ack_int(bp); u16 mask; int i; + u8 cos; /* Return here if interrupt is shared and it's not for us */ if (unlikely(status == 0)) { @@ -1738,11 +1760,12 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); + mask = 0x2 << (fp->index + CNIC_PRESENT); if (status & mask) { /* Handle Rx or Tx according to SB id */ prefetch(fp->rx_cons_sb); - prefetch(fp->tx_cons_sb); + for_each_cos_in_tx_queue(fp, cos) + prefetch(fp->txdata[cos].tx_cons_sb); prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); status &= ~mask; @@ -2632,15 +2655,43 @@ void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) } } -static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp, - struct bnx2x_fastpath *fp, - bool leading) +/** + * bnx2x_get_tx_only_flags - Return common flags + * + * @bp device handle + * @fp queue handle + * @zero_stats TRUE if statistics zeroing is needed + * + * Return the flags that are common for the Tx-only and not normal connections. + */ +static inline unsigned long bnx2x_get_common_flags(struct bnx2x *bp, + struct bnx2x_fastpath *fp, + bool zero_stats) { unsigned long flags = 0; /* PF driver will always initialize the Queue to an ACTIVE state */ __set_bit(BNX2X_Q_FLG_ACTIVE, &flags); + /* tx only connections collect statistics (on the same index as the + * parent connection). The statistics are zeroed when the parent + * connection is initialized. + */ + if (stat_counter_valid(bp, fp)) { + __set_bit(BNX2X_Q_FLG_STATS, &flags); + if (zero_stats) + __set_bit(BNX2X_Q_FLG_ZERO_STATS, &flags); + } + + return flags; +} + +static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp, + struct bnx2x_fastpath *fp, + bool leading) +{ + unsigned long flags = 0; + /* calculate other queue flags */ if (IS_MF_SD(bp)) __set_bit(BNX2X_Q_FLG_OV, &flags); @@ -2651,11 +2702,6 @@ static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp, if (!fp->disable_tpa) __set_bit(BNX2X_Q_FLG_TPA, &flags); - if (stat_counter_valid(bp, fp)) { - __set_bit(BNX2X_Q_FLG_STATS, &flags); - __set_bit(BNX2X_Q_FLG_ZERO_STATS, &flags); - } - if (leading) { __set_bit(BNX2X_Q_FLG_LEADING_RSS, &flags); __set_bit(BNX2X_Q_FLG_MCAST, &flags); @@ -2664,11 +2710,13 @@ static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp, /* Always set HW VLAN stripping */ __set_bit(BNX2X_Q_FLG_VLAN, &flags); - return flags; + + return flags | bnx2x_get_common_flags(bp, fp, true); } static void bnx2x_pf_q_prep_general(struct bnx2x *bp, - struct bnx2x_fastpath *fp, struct bnx2x_general_setup_params *gen_init) + struct bnx2x_fastpath *fp, struct bnx2x_general_setup_params *gen_init, + u8 cos) { gen_init->stat_id = bnx2x_stats_id(fp); gen_init->spcl_id = fp->cl_id; @@ -2678,6 +2726,8 @@ static void bnx2x_pf_q_prep_general(struct bnx2x *bp, gen_init->mtu = BNX2X_FCOE_MINI_JUMBO_MTU; else gen_init->mtu = bp->dev->mtu; + + gen_init->cos = cos; } static void bnx2x_pf_rx_q_prep(struct bnx2x *bp, @@ -2745,14 +2795,15 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp, if (IS_FCOE_FP(fp)) rxq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS; else - rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; + rxq_init->sb_cq_index = HC_INDEX_ETH_RX_CQ_CONS; } static void bnx2x_pf_tx_q_prep(struct bnx2x *bp, - struct bnx2x_fastpath *fp, struct bnx2x_txq_setup_params *txq_init) + struct bnx2x_fastpath *fp, struct bnx2x_txq_setup_params *txq_init, + u8 cos) { - txq_init->dscr_map = fp->tx_desc_mapping; - txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX; + txq_init->dscr_map = fp->txdata[cos].tx_desc_mapping; + txq_init->sb_cq_index = HC_INDEX_ETH_FIRST_TX_CQ_CONS + cos; txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; txq_init->fw_sb_id = fp->fw_sb_id; @@ -2948,6 +2999,7 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) static inline bool bnx2x_is_contextless_ramrod(int cmd, int cmd_type) { if ((cmd_type == NONE_CONNECTION_TYPE) || + (cmd == RAMROD_CMD_ID_ETH_FORWARD_SETUP) || (cmd == RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES) || (cmd == RAMROD_CMD_ID_ETH_FILTER_RULES) || (cmd == RAMROD_CMD_ID_ETH_MULTICAST_RULES) || @@ -4270,12 +4322,13 @@ static inline void bnx2x_handle_rx_mode_eqe(struct bnx2x *bp) static inline struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj( struct bnx2x *bp, u32 cid) { + DP(BNX2X_MSG_SP, "retrieving fp from cid %d", cid); #ifdef BCM_CNIC if (cid == BNX2X_FCOE_ETH_CID) return &bnx2x_fcoe(bp, q_obj); else #endif - return &bnx2x_fp(bp, cid, q_obj); + return &bnx2x_fp(bp, CID_TO_FP(cid), q_obj); } static void bnx2x_eq_int(struct bnx2x *bp) @@ -4522,6 +4575,7 @@ void bnx2x_drv_pulse(struct bnx2x *bp) static void bnx2x_timer(unsigned long data) { + u8 cos; struct bnx2x *bp = (struct bnx2x *) data; if (!netif_running(bp->dev)) @@ -4530,7 +4584,8 @@ static void bnx2x_timer(unsigned long data) if (poll) { struct bnx2x_fastpath *fp = &bp->fp[0]; - bnx2x_tx_int(fp); + for_each_cos_in_tx_queue(fp, cos) + bnx2x_tx_int(bp, &fp->txdata[cos]); bnx2x_rx_int(fp, 1000); } @@ -4735,10 +4790,17 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u8 fw_sb_id, u16 tx_usec, u16 rx_usec) { - bnx2x_update_coalesce_sb_index(bp, fw_sb_id, U_SB_ETH_RX_CQ_INDEX, + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, HC_INDEX_ETH_RX_CQ_CONS, false, rx_usec); - bnx2x_update_coalesce_sb_index(bp, fw_sb_id, C_SB_ETH_TX_CQ_INDEX, - false, tx_usec); + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, + HC_INDEX_ETH_TX_CQ_CONS_COS0, false, + tx_usec); + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, + HC_INDEX_ETH_TX_CQ_CONS_COS1, false, + tx_usec); + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, + HC_INDEX_ETH_TX_CQ_CONS_COS2, false, + tx_usec); } static void bnx2x_init_def_sb(struct bnx2x *bp) @@ -5035,12 +5097,12 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) static inline u8 bnx2x_fp_igu_sb_id(struct bnx2x_fastpath *fp) { - return fp->bp->igu_base_sb + fp->index + CNIC_CONTEXT_USE; + return fp->bp->igu_base_sb + fp->index + CNIC_PRESENT; } static inline u8 bnx2x_fp_fw_sb_id(struct bnx2x_fastpath *fp) { - return fp->bp->base_fw_ndsb + fp->index + CNIC_CONTEXT_USE; + return fp->bp->base_fw_ndsb + fp->index + CNIC_PRESENT; } static inline u8 bnx2x_fp_cl_id(struct bnx2x_fastpath *fp) @@ -5051,10 +5113,12 @@ static inline u8 bnx2x_fp_cl_id(struct bnx2x_fastpath *fp) return bnx2x_fp_igu_sb_id(fp); } -static void bnx2x_init_fp(struct bnx2x *bp, int fp_idx) +static void bnx2x_init_eth_fp(struct bnx2x *bp, int fp_idx) { struct bnx2x_fastpath *fp = &bp->fp[fp_idx]; + u8 cos; unsigned long q_type = 0; + u32 cids[BNX2X_MULTI_TX_COS] = { 0 }; fp->cid = fp_idx; fp->cl_id = bnx2x_fp_cl_id(fp); @@ -5067,14 +5131,25 @@ static void bnx2x_init_fp(struct bnx2x *bp, int fp_idx) fp->ustorm_rx_prods_offset = bnx2x_rx_ustorm_prods_offset(fp); /* Setup SB indicies */ fp->rx_cons_sb = BNX2X_RX_SB_INDEX; - fp->tx_cons_sb = BNX2X_TX_SB_INDEX; /* Configure Queue State object */ __set_bit(BNX2X_Q_TYPE_HAS_RX, &q_type); __set_bit(BNX2X_Q_TYPE_HAS_TX, &q_type); - bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, fp->cid, BP_FUNC(bp), - bnx2x_sp(bp, q_rdata), bnx2x_sp_mapping(bp, q_rdata), - q_type); + + BUG_ON(fp->max_cos > BNX2X_MULTI_TX_COS); + + /* init tx data */ + for_each_cos_in_tx_queue(fp, cos) { + bnx2x_init_txdata(bp, &fp->txdata[cos], + CID_COS_TO_TX_ONLY_CID(fp->cid, cos), + FP_COS_TO_TXQ(fp, cos), + BNX2X_TX_SB_INDEX_BASE + cos); + cids[cos] = fp->txdata[cos].cid; + } + + bnx2x_init_queue_obj(bp, &fp->q_obj, fp->cl_id, cids, fp->max_cos, + BP_FUNC(bp), bnx2x_sp(bp, q_rdata), + bnx2x_sp_mapping(bp, q_rdata), q_type); /** * Configure classification DBs: Always enable Tx switching @@ -5096,7 +5171,7 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) int i; for_each_eth_queue(bp, i) - bnx2x_init_fp(bp, i); + bnx2x_init_eth_fp(bp, i); #ifdef BCM_CNIC if (!NO_FCOE(bp)) bnx2x_init_fcoe_fp(bp); @@ -6718,7 +6793,7 @@ int bnx2x_alloc_mem(struct bnx2x *bp) if (bnx2x_alloc_fw_stats_mem(bp)) goto alloc_mem_err; - bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count; + bp->context.size = sizeof(union cdu_context) * BNX2X_L2_CID_COUNT(bp); BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, bp->context.size); @@ -6837,7 +6912,7 @@ static void __devinit bnx2x_set_int_mode(struct bnx2x *bp) bnx2x_enable_msi(bp); /* falling through... */ case INT_MODE_INTx: - bp->num_queues = 1 + NONE_ETH_CONTEXT_USE; + bp->num_queues = 1 + NON_ETH_CONTEXT_USE; DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; default: @@ -6859,8 +6934,8 @@ static void __devinit bnx2x_set_int_mode(struct bnx2x *bp) "enable MSI-X (%d), " "set number of queues to %d\n", bp->num_queues, - 1 + NONE_ETH_CONTEXT_USE); - bp->num_queues = 1 + NONE_ETH_CONTEXT_USE; + 1 + NON_ETH_CONTEXT_USE); + bp->num_queues = 1 + NON_ETH_CONTEXT_USE; /* Try to enable MSI */ if (!(bp->flags & DISABLE_MSI_FLAG)) @@ -6988,6 +7063,8 @@ void bnx2x_ilt_set_info(struct bnx2x *bp) static inline void bnx2x_pf_q_prep_init(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct bnx2x_queue_init_params *init_params) { + + u8 cos; /* FCoE Queue uses Default SB, thus has no HC capabilities */ if (!IS_FCOE_FP(fp)) { __set_bit(BNX2X_Q_FLG_HC, &init_params->rx.flags); @@ -7013,13 +7090,56 @@ static inline void bnx2x_pf_q_prep_init(struct bnx2x *bp, * CQ index among the SB indices: FCoE clients uses the default * SB, therefore it's different. */ - init_params->rx.sb_cq_index = U_SB_ETH_RX_CQ_INDEX; - init_params->tx.sb_cq_index = C_SB_ETH_TX_CQ_INDEX; + init_params->rx.sb_cq_index = HC_INDEX_ETH_RX_CQ_CONS; + init_params->tx.sb_cq_index = HC_INDEX_ETH_FIRST_TX_CQ_CONS; } - init_params->cxt = &bp->context.vcxt[fp->cid].eth; + /* set maximum number of COSs supported by this queue */ + init_params->max_cos = fp->max_cos; + + DP(BNX2X_MSG_SP, "fp: %d setting queue params max cos to: %d", + fp->index, init_params->max_cos); + + /* set the context pointers queue object */ + for (cos = FIRST_TX_COS_INDEX; cos < init_params->max_cos; cos++) + init_params->cxts[cos] = + &bp->context.vcxt[fp->txdata[cos].cid].eth; } +int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp, + struct bnx2x_queue_state_params *q_params, + struct bnx2x_queue_setup_tx_only_params *tx_only_params, + int tx_index, bool leading) +{ + memset(tx_only_params, 0, sizeof(*tx_only_params)); + + /* Set the command */ + q_params->cmd = BNX2X_Q_CMD_SETUP_TX_ONLY; + + /* Set tx-only QUEUE flags: don't zero statistics */ + tx_only_params->flags = bnx2x_get_common_flags(bp, fp, false); + + /* choose the index of the cid to send the slow path on */ + tx_only_params->cid_index = tx_index; + + /* Set general TX_ONLY_SETUP parameters */ + bnx2x_pf_q_prep_general(bp, fp, &tx_only_params->gen_params, tx_index); + + /* Set Tx TX_ONLY_SETUP parameters */ + bnx2x_pf_tx_q_prep(bp, fp, &tx_only_params->txq_params, tx_index); + + DP(BNX2X_MSG_SP, "preparing to send tx-only ramrod for connection:" + "cos %d, primary cid %d, cid %d, " + "client id %d, sp-client id %d, flags %lx", + tx_index, q_params->q_obj->cids[FIRST_TX_COS_INDEX], + q_params->q_obj->cids[tx_index], q_params->q_obj->cl_id, + tx_only_params->gen_params.spcl_id, tx_only_params->flags); + + /* send the ramrod */ + return bnx2x_queue_state_change(bp, q_params); +} + + /** * bnx2x_setup_queue - setup queue * @@ -7037,7 +7157,12 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct bnx2x_queue_state_params q_params = {0}; struct bnx2x_queue_setup_params *setup_params = &q_params.params.setup; + struct bnx2x_queue_setup_tx_only_params *tx_only_params = + &q_params.params.tx_only; int rc; + u8 tx_index; + + DP(BNX2X_MSG_SP, "setting up queue %d", fp->index); /* reset IGU state skip FCoE L2 queue */ if (!IS_FCOE_FP(fp)) @@ -7057,10 +7182,13 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Change the state to INIT */ rc = bnx2x_queue_state_change(bp, &q_params); if (rc) { - BNX2X_ERR("Queue INIT failed\n"); + BNX2X_ERR("Queue(%d) INIT failed\n", fp->index); return rc; } + DP(BNX2X_MSG_SP, "init complete"); + + /* Now move the Queue to the SETUP state... */ memset(setup_params, 0, sizeof(*setup_params)); @@ -7068,20 +7196,39 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, setup_params->flags = bnx2x_get_q_flags(bp, fp, leading); /* Set general SETUP parameters */ - bnx2x_pf_q_prep_general(bp, fp, &setup_params->gen_params); + bnx2x_pf_q_prep_general(bp, fp, &setup_params->gen_params, + FIRST_TX_COS_INDEX); - bnx2x_pf_rx_q_prep(bp, fp, &setup_params->pause, + bnx2x_pf_rx_q_prep(bp, fp, &setup_params->pause_params, &setup_params->rxq_params); - bnx2x_pf_tx_q_prep(bp, fp, &setup_params->txq_params); + bnx2x_pf_tx_q_prep(bp, fp, &setup_params->txq_params, + FIRST_TX_COS_INDEX); /* Set the command */ q_params.cmd = BNX2X_Q_CMD_SETUP; /* Change the state to SETUP */ rc = bnx2x_queue_state_change(bp, &q_params); - if (rc) - BNX2X_ERR("Queue SETUP failed\n"); + if (rc) { + BNX2X_ERR("Queue(%d) SETUP failed\n", fp->index); + return rc; + } + + /* loop through the relevant tx-only indices */ + for (tx_index = FIRST_TX_ONLY_COS_INDEX; + tx_index < fp->max_cos; + tx_index++) { + + /* prepare and send tx-only ramrod*/ + rc = bnx2x_setup_tx_only(bp, fp, &q_params, + tx_only_params, tx_index, leading); + if (rc) { + BNX2X_ERR("Queue(%d.%d) TX_ONLY_SETUP failed\n", + fp->index, tx_index); + return rc; + } + } return rc; } @@ -7089,27 +7236,67 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, static int bnx2x_stop_queue(struct bnx2x *bp, int index) { struct bnx2x_fastpath *fp = &bp->fp[index]; + struct bnx2x_fp_txdata *txdata; struct bnx2x_queue_state_params q_params = {0}; - int rc; + int rc, tx_index; + + DP(BNX2X_MSG_SP, "stopping queue %d cid %d", index, fp->cid); q_params.q_obj = &fp->q_obj; /* We want to wait for completion in this context */ __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags); - /* halt the connection */ + + /* close tx-only connections */ + for (tx_index = FIRST_TX_ONLY_COS_INDEX; + tx_index < fp->max_cos; + tx_index++){ + + /* ascertain this is a normal queue*/ + txdata = &fp->txdata[tx_index]; + + DP(BNX2X_MSG_SP, "stopping tx-only queue %d", + txdata->txq_index); + + /* send halt terminate on tx-only connection */ + q_params.cmd = BNX2X_Q_CMD_TERMINATE; + memset(&q_params.params.terminate, 0, + sizeof(q_params.params.terminate)); + q_params.params.terminate.cid_index = tx_index; + + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) + return rc; + + /* send halt terminate on tx-only connection */ + q_params.cmd = BNX2X_Q_CMD_CFC_DEL; + memset(&q_params.params.cfc_del, 0, + sizeof(q_params.params.cfc_del)); + q_params.params.cfc_del.cid_index = tx_index; + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) + return rc; + } + /* Stop the primary connection: */ + /* ...halt the connection */ q_params.cmd = BNX2X_Q_CMD_HALT; rc = bnx2x_queue_state_change(bp, &q_params); if (rc) return rc; - /* terminate the connection */ + /* ...terminate the connection */ q_params.cmd = BNX2X_Q_CMD_TERMINATE; + memset(&q_params.params.terminate, 0, + sizeof(q_params.params.terminate)); + q_params.params.terminate.cid_index = FIRST_TX_COS_INDEX; rc = bnx2x_queue_state_change(bp, &q_params); if (rc) return rc; - - /* delete cfc entry */ + /* ...delete cfc entry */ q_params.cmd = BNX2X_Q_CMD_CFC_DEL; + memset(&q_params.params.cfc_del, 0, + sizeof(q_params.params.cfc_del)); + q_params.params.cfc_del.cid_index = FIRST_TX_COS_INDEX; return bnx2x_queue_state_change(bp, &q_params); } @@ -7130,8 +7317,8 @@ static void bnx2x_reset_func(struct bnx2x *bp) for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(fp->fw_sb_id), - SB_DISABLED); + CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(fp->fw_sb_id), + SB_DISABLED); } #ifdef BCM_CNIC @@ -7142,8 +7329,8 @@ static void bnx2x_reset_func(struct bnx2x *bp) #endif /* SP SB */ REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(func), - SB_DISABLED); + CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(func), + SB_DISABLED); for (i = 0; i < XSTORM_SPQ_DATA_SIZE / 4; i++) REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_DATA_OFFSET(func), @@ -7352,7 +7539,8 @@ void bnx2x_send_unload_done(struct bnx2x *bp) void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) { int port = BP_PORT(bp); - int i, rc; + int i, rc = 0; + u8 cos; struct bnx2x_mcast_ramrod_params rparam = {0}; u32 reset_code; @@ -7360,7 +7548,8 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - rc = bnx2x_clean_tx_queue(bp, fp); + for_each_cos_in_tx_queue(fp, cos) + rc = bnx2x_clean_tx_queue(bp, &fp->txdata[cos]); #ifdef BNX2X_STOP_ON_ERROR if (rc) return; @@ -7888,7 +8077,7 @@ static inline void bnx2x_recovery_failed(struct bnx2x *bp) /* * Assumption: runs under rtnl lock. This together with the fact - * that it's called only from bnx2x_reset_task() ensure that it + * that it's called only from bnx2x_sp_rtnl() ensure that it * will never be called when netif_running(bp->dev) is false. */ static void bnx2x_parity_recover(struct bnx2x *bp) @@ -8045,6 +8234,9 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work) if (!netif_running(bp->dev)) goto sp_rtnl_exit; + if (test_and_clear_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state)) + bnx2x_setup_tc(bp->dev, bp->dcbx_port_params.ets.num_of_cos); + /* if stop on error is defined no recovery flows should be executed */ #ifdef BNX2X_STOP_ON_ERROR BNX2X_ERR("recovery flow called but STOP_ON_ERROR defined " @@ -8387,14 +8579,11 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) int vn = BP_E1HVN(bp); int igu_sb_id; u32 val; - u8 fid; + u8 fid, igu_sb_cnt = 0; bp->igu_base_sb = 0xff; - bp->igu_sb_cnt = 0; if (CHIP_INT_MODE_IS_BC(bp)) { - bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, - NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); - + igu_sb_cnt = bp->igu_sb_cnt; bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) * FP_SB_MAX_E1x; @@ -8420,19 +8609,21 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) else { if (bp->igu_base_sb == 0xff) bp->igu_base_sb = igu_sb_id; - bp->igu_sb_cnt++; + igu_sb_cnt++; } } } - /* It's expected that number of CAM entries for this - * functions is equal to the MSI-X table size (which was a - * used during bp->l2_cid_count value calculation. - * We want a harsh warning if these values are different! +#ifdef CONFIG_PCI_MSI + /* + * It's expected that number of CAM entries for this functions is equal + * to the number evaluated based on the MSI-X table size. We want a + * harsh warning if these values are different! */ - WARN_ON(bp->igu_sb_cnt != NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); + WARN_ON(bp->igu_sb_cnt != igu_sb_cnt); +#endif - if (bp->igu_sb_cnt == 0) + if (igu_sb_cnt == 0) BNX2X_ERR("CAM configuration error\n"); } @@ -8961,13 +9152,14 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bnx2x_get_common_hwinfo(bp); + /* + * initialize IGU parameters + */ if (CHIP_IS_E1x(bp)) { bp->common.int_block = INT_BLOCK_HC; bp->igu_dsb_id = DEF_SB_IGU_ID; bp->igu_base_sb = 0; - bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, - NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); } else { bp->common.int_block = INT_BLOCK_IGU; val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); @@ -9260,10 +9452,8 @@ static void __devinit bnx2x_set_modes_bitmap(struct bnx2x *bp) SET_FLAGS(flags, MODE_E3); if (CHIP_REV(bp) == CHIP_REV_Ax) SET_FLAGS(flags, MODE_E3_A0); - else {/*if (CHIP_REV(bp) == CHIP_REV_Bx)*/ - SET_FLAGS(flags, MODE_E3_B0); - SET_FLAGS(flags, MODE_COS_BC); - } + else /*if (CHIP_REV(bp) == CHIP_REV_Bx)*/ + SET_FLAGS(flags, MODE_E3_B0 | MODE_COS3); } if (IS_MF(bp)) { @@ -9371,6 +9561,14 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->cnic_base_cl_id = FP_SB_MAX_E2; #endif + /* multiple tx priority */ + if (CHIP_IS_E1x(bp)) + bp->max_cos = BNX2X_MULTI_TX_COS_E1X; + if (CHIP_IS_E2(bp) || CHIP_IS_E3A0(bp)) + bp->max_cos = BNX2X_MULTI_TX_COS_E2_E3A0; + if (CHIP_IS_E3B0(bp)) + bp->max_cos = BNX2X_MULTI_TX_COS_E3B0; + return rc; } @@ -9696,6 +9894,8 @@ static const struct net_device_ops bnx2x_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2x, #endif + .ndo_setup_tc = bnx2x_setup_tc, + }; static inline int bnx2x_set_coherency_mask(struct bnx2x *bp) @@ -9797,16 +9997,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, goto err_out_release; } - bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2), - min_t(u64, BNX2X_DB_SIZE(bp), - pci_resource_len(pdev, 2))); - if (!bp->doorbells) { - dev_err(&bp->pdev->dev, - "Cannot map doorbell space, aborting\n"); - rc = -ENOMEM; - goto err_out_unmap; - } - bnx2x_set_power_state(bp, PCI_D0); /* clean indirect addresses */ @@ -9859,16 +10049,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, return 0; -err_out_unmap: - if (bp->regview) { - iounmap(bp->regview); - bp->regview = NULL; - } - if (bp->doorbells) { - iounmap(bp->doorbells); - bp->doorbells = NULL; - } - err_out_release: if (atomic_read(&pdev->enable_cnt) == 1) pci_release_regions(pdev); @@ -10143,9 +10323,9 @@ void bnx2x__init_func_obj(struct bnx2x *bp) } /* must be called after sriov-enable */ -static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) +static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp) { - int cid_count = L2_FP_COUNT(l2_cid_count); + int cid_count = BNX2X_L2_CID_COUNT(bp); #ifdef BCM_CNIC cid_count += CNIC_CID_MAX; @@ -10154,22 +10334,33 @@ static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) } /** - * bnx2x_pci_msix_table_size - get the size of the MSI-X table. + * bnx2x_get_num_none_def_sbs - return the number of none default SBs * * @dev: pci device * */ -static inline int bnx2x_pci_msix_table_size(struct pci_dev *pdev) +static inline int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev) { int pos; u16 control; pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + + /* + * If MSI-X is not supported - return number of SBs needed to support + * one fast path queue: one FP queue + SB for CNIC + */ if (!pos) - return 0; + return 1 + CNIC_PRESENT; + /* + * The value in the PCI configuration space is the index of the last + * entry, namely one less than the actual size of the table, which is + * exactly what we want to return from this function: number of all SBs + * without the default SB. + */ pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &control); - return (control & PCI_MSIX_FLAGS_QSIZE) + 1; + return control & PCI_MSIX_FLAGS_QSIZE; } static int __devinit bnx2x_init_one(struct pci_dev *pdev, @@ -10178,34 +10369,38 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, struct net_device *dev = NULL; struct bnx2x *bp; int pcie_width, pcie_speed; - int rc, cid_count; + int rc, max_non_def_sbs; + int rx_count, tx_count, rss_count; + /* + * An estimated maximum supported CoS number according to the chip + * version. + * We will try to roughly estimate the maximum number of CoSes this chip + * may support in order to minimize the memory allocated for Tx + * netdev_queue's. This number will be accurately calculated during the + * initialization of bp->max_cos based on the chip versions AND chip + * revision in the bnx2x_init_bp(). + */ + u8 max_cos_est = 0; switch (ent->driver_data) { case BCM57710: case BCM57711: case BCM57711E: + max_cos_est = BNX2X_MULTI_TX_COS_E1X; + break; + case BCM57712: case BCM57712_MF: + max_cos_est = BNX2X_MULTI_TX_COS_E2_E3A0; + break; + case BCM57800: case BCM57800_MF: case BCM57810: case BCM57810_MF: case BCM57840: case BCM57840_MF: - /* The size requested for the MSI-X table corresponds to the - * actual amount of avaliable IGU/HC status blocks. It includes - * the default SB vector but we want cid_count to contain the - * amount of only non-default SBs, that's what '-1' stands for. - */ - cid_count = bnx2x_pci_msix_table_size(pdev) - 1; - - /* do not allow initial cid_count grow above 16 - * since Special CIDs starts from this number - * use old FP_SB_MAX_E1x define for this matter - */ - cid_count = min_t(int, FP_SB_MAX_E1x, cid_count); - - WARN_ON(!cid_count); + max_cos_est = BNX2X_MULTI_TX_COS_E3B0; break; default: @@ -10214,26 +10409,44 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return -ENODEV; } - cid_count += FCOE_CONTEXT_USE; + max_non_def_sbs = bnx2x_get_num_non_def_sbs(pdev); + + /* !!! FIXME !!! + * Do not allow the maximum SB count to grow above 16 + * since Special CIDs starts from 16*BNX2X_MULTI_TX_COS=48. + * We will use the FP_SB_MAX_E1x macro for this matter. + */ + max_non_def_sbs = min_t(int, FP_SB_MAX_E1x, max_non_def_sbs); + + WARN_ON(!max_non_def_sbs); + + /* Maximum number of RSS queues: one IGU SB goes to CNIC */ + rss_count = max_non_def_sbs - CNIC_PRESENT; + + /* Maximum number of netdev Rx queues: RSS + FCoE L2 */ + rx_count = rss_count + FCOE_PRESENT; + + /* + * Maximum number of netdev Tx queues: + * Maximum TSS queues * Maximum supported number of CoS + FCoE L2 + */ + tx_count = MAX_TXQS_PER_COS * max_cos_est + FCOE_PRESENT; /* dev zeroed in init_etherdev */ - dev = alloc_etherdev_mq(sizeof(*bp), cid_count); + dev = alloc_etherdev_mqs(sizeof(*bp), tx_count, rx_count); if (!dev) { dev_err(&pdev->dev, "Cannot allocate net device\n"); return -ENOMEM; } - /* We don't need a Tx queue for a CNIC and an OOO Rx-only ring, - * so update a cid_count after a netdev allocation. - */ - cid_count += CNIC_CONTEXT_USE; - bp = netdev_priv(dev); - bp->msg_enable = debug; - pci_set_drvdata(pdev, dev); + DP(NETIF_MSG_DRV, "Allocated netdev with %d tx and %d rx queues\n", + tx_count, rx_count); - bp->l2_cid_count = cid_count; + bp->igu_sb_cnt = max_non_def_sbs; + bp->msg_enable = debug; + pci_set_drvdata(pdev, dev); rc = bnx2x_init_dev(pdev, dev, ent->driver_data); if (rc < 0) { @@ -10241,14 +10454,28 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return rc; } - BNX2X_DEV_INFO("cid_count=%d\n", cid_count); + DP(NETIF_MSG_DRV, "max_non_def_sbs %d", max_non_def_sbs); rc = bnx2x_init_bp(bp); if (rc) goto init_one_exit; + /* + * Map doorbels here as we need the real value of bp->max_cos which + * is initialized in bnx2x_init_bp(). + */ + bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2), + min_t(u64, BNX2X_DB_SIZE(bp), + pci_resource_len(pdev, 2))); + if (!bp->doorbells) { + dev_err(&bp->pdev->dev, + "Cannot map doorbell space, aborting\n"); + rc = -ENOMEM; + goto init_one_exit; + } + /* calc qm_cid_count */ - bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); + bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); #ifdef BCM_CNIC /* disable FCOE L2 queue for E1x*/ diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index f6322a15ed4..358c3399753 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -4195,15 +4195,29 @@ static int bnx2x_queue_comp_cmd(struct bnx2x *bp, if (!test_and_clear_bit(cmd, &cur_pending)) { BNX2X_ERR("Bad MC reply %d for queue %d in state %d " - "pending 0x%lx, next_state %d\n", cmd, o->cid, + "pending 0x%lx, next_state %d\n", cmd, + o->cids[BNX2X_PRIMARY_CID_INDEX], o->state, cur_pending, o->next_state); return -EINVAL; } + if (o->next_tx_only >= o->max_cos) + /* >= becuase tx only must always be smaller than cos since the + * primary connection suports COS 0 + */ + BNX2X_ERR("illegal value for next tx_only: %d. max cos was %d", + o->next_tx_only, o->max_cos); + DP(BNX2X_MSG_SP, "Completing command %d for queue %d, " - "setting state to %d\n", cmd, o->cid, o->next_state); + "setting state to %d\n", cmd, + o->cids[BNX2X_PRIMARY_CID_INDEX], o->next_state); + + if (o->next_tx_only) /* print num tx-only if any exist */ + DP(BNX2X_MSG_SP, "primary cid %d: num tx-only cons %d", + o->cids[BNX2X_PRIMARY_CID_INDEX], o->next_tx_only); o->state = o->next_state; + o->num_tx_only = o->next_tx_only; o->next_state = BNX2X_Q_STATE_MAX; /* It's important that o->state and o->next_state are @@ -4230,135 +4244,193 @@ static void bnx2x_q_fill_setup_data_e2(struct bnx2x *bp, CLIENT_INIT_RX_DATA_TPA_EN_IPV6; } -static void bnx2x_q_fill_setup_data_cmn(struct bnx2x *bp, - struct bnx2x_queue_state_params *cmd_params, - struct client_init_ramrod_data *data) -{ - struct bnx2x_queue_sp_obj *o = cmd_params->q_obj; - struct bnx2x_queue_setup_params *params = &cmd_params->params.setup; - - - /* general */ - data->general.client_id = o->cl_id; - - if (test_bit(BNX2X_Q_FLG_STATS, ¶ms->flags)) { - data->general.statistics_counter_id = - params->gen_params.stat_id; - data->general.statistics_en_flg = 1; - data->general.statistics_zero_flg = - test_bit(BNX2X_Q_FLG_ZERO_STATS, ¶ms->flags); +static void bnx2x_q_fill_init_general_data(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *o, + struct bnx2x_general_setup_params *params, + struct client_init_general_data *gen_data, + unsigned long *flags) +{ + gen_data->client_id = o->cl_id; + + if (test_bit(BNX2X_Q_FLG_STATS, flags)) { + gen_data->statistics_counter_id = + params->stat_id; + gen_data->statistics_en_flg = 1; + gen_data->statistics_zero_flg = + test_bit(BNX2X_Q_FLG_ZERO_STATS, flags); } else - data->general.statistics_counter_id = + gen_data->statistics_counter_id = DISABLE_STATISTIC_COUNTER_ID_VALUE; - data->general.is_fcoe_flg = test_bit(BNX2X_Q_FLG_FCOE, ¶ms->flags); - data->general.activate_flg = test_bit(BNX2X_Q_FLG_ACTIVE, - ¶ms->flags); - data->general.sp_client_id = params->gen_params.spcl_id; - data->general.mtu = cpu_to_le16(params->gen_params.mtu); - data->general.func_id = o->func_id; + gen_data->is_fcoe_flg = test_bit(BNX2X_Q_FLG_FCOE, flags); + gen_data->activate_flg = test_bit(BNX2X_Q_FLG_ACTIVE, flags); + gen_data->sp_client_id = params->spcl_id; + gen_data->mtu = cpu_to_le16(params->mtu); + gen_data->func_id = o->func_id; - data->general.cos = params->txq_params.cos; + gen_data->cos = params->cos; - data->general.traffic_type = - test_bit(BNX2X_Q_FLG_FCOE, ¶ms->flags) ? + gen_data->traffic_type = + test_bit(BNX2X_Q_FLG_FCOE, flags) ? LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; - /* Rx data */ - data->rx.tpa_en = test_bit(BNX2X_Q_FLG_TPA, ¶ms->flags) * + DP(BNX2X_MSG_SP, "flags: active %d, cos %d, stats en %d", + gen_data->activate_flg, gen_data->cos, gen_data->statistics_en_flg); +} + +static void bnx2x_q_fill_init_tx_data(struct bnx2x_queue_sp_obj *o, + struct bnx2x_txq_setup_params *params, + struct client_init_tx_data *tx_data, + unsigned long *flags) +{ + tx_data->enforce_security_flg = + test_bit(BNX2X_Q_FLG_TX_SEC, flags); + tx_data->default_vlan = + cpu_to_le16(params->default_vlan); + tx_data->default_vlan_flg = + test_bit(BNX2X_Q_FLG_DEF_VLAN, flags); + tx_data->tx_switching_flg = + test_bit(BNX2X_Q_FLG_TX_SWITCH, flags); + tx_data->anti_spoofing_flg = + test_bit(BNX2X_Q_FLG_ANTI_SPOOF, flags); + tx_data->tx_status_block_id = params->fw_sb_id; + tx_data->tx_sb_index_number = params->sb_cq_index; + tx_data->tss_leading_client_id = params->tss_leading_cl_id; + + tx_data->tx_bd_page_base.lo = + cpu_to_le32(U64_LO(params->dscr_map)); + tx_data->tx_bd_page_base.hi = + cpu_to_le32(U64_HI(params->dscr_map)); + + /* Don't configure any Tx switching mode during queue SETUP */ + tx_data->state = 0; +} + +static void bnx2x_q_fill_init_pause_data(struct bnx2x_queue_sp_obj *o, + struct rxq_pause_params *params, + struct client_init_rx_data *rx_data) +{ + /* flow control data */ + rx_data->cqe_pause_thr_low = cpu_to_le16(params->rcq_th_lo); + rx_data->cqe_pause_thr_high = cpu_to_le16(params->rcq_th_hi); + rx_data->bd_pause_thr_low = cpu_to_le16(params->bd_th_lo); + rx_data->bd_pause_thr_high = cpu_to_le16(params->bd_th_hi); + rx_data->sge_pause_thr_low = cpu_to_le16(params->sge_th_lo); + rx_data->sge_pause_thr_high = cpu_to_le16(params->sge_th_hi); + rx_data->rx_cos_mask = cpu_to_le16(params->pri_map); +} + +static void bnx2x_q_fill_init_rx_data(struct bnx2x_queue_sp_obj *o, + struct bnx2x_rxq_setup_params *params, + struct client_init_rx_data *rx_data, + unsigned long *flags) +{ + /* Rx data */ + rx_data->tpa_en = test_bit(BNX2X_Q_FLG_TPA, flags) * CLIENT_INIT_RX_DATA_TPA_EN_IPV4; - data->rx.vmqueue_mode_en_flg = 0; + rx_data->vmqueue_mode_en_flg = 0; - data->rx.cache_line_alignment_log_size = - params->rxq_params.cache_line_log; - data->rx.enable_dynamic_hc = - test_bit(BNX2X_Q_FLG_DHC, ¶ms->flags); - data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; - data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; - data->rx.max_agg_size = cpu_to_le16(params->rxq_params.tpa_agg_sz); + rx_data->cache_line_alignment_log_size = + params->cache_line_log; + rx_data->enable_dynamic_hc = + test_bit(BNX2X_Q_FLG_DHC, flags); + rx_data->max_sges_for_packet = params->max_sges_pkt; + rx_data->client_qzone_id = params->cl_qzone_id; + rx_data->max_agg_size = cpu_to_le16(params->tpa_agg_sz); /* Always start in DROP_ALL mode */ - data->rx.state = cpu_to_le16(CLIENT_INIT_RX_DATA_UCAST_DROP_ALL | + rx_data->state = cpu_to_le16(CLIENT_INIT_RX_DATA_UCAST_DROP_ALL | CLIENT_INIT_RX_DATA_MCAST_DROP_ALL); /* We don't set drop flags */ - data->rx.drop_ip_cs_err_flg = 0; - data->rx.drop_tcp_cs_err_flg = 0; - data->rx.drop_ttl0_flg = 0; - data->rx.drop_udp_cs_err_flg = 0; - data->rx.inner_vlan_removal_enable_flg = - test_bit(BNX2X_Q_FLG_VLAN, ¶ms->flags); - data->rx.outer_vlan_removal_enable_flg = - test_bit(BNX2X_Q_FLG_OV, ¶ms->flags); - data->rx.status_block_id = params->rxq_params.fw_sb_id; - data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; - data->rx.max_tpa_queues = params->rxq_params.max_tpa_queues; - data->rx.max_bytes_on_bd = cpu_to_le16(params->rxq_params.buf_sz); - data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); - data->rx.bd_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); - data->rx.bd_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); - data->rx.sge_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.sge_map)); - data->rx.sge_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.sge_map)); - data->rx.cqe_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); - data->rx.cqe_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); - data->rx.is_leading_rss = test_bit(BNX2X_Q_FLG_LEADING_RSS, - ¶ms->flags); - - if (test_bit(BNX2X_Q_FLG_MCAST, ¶ms->flags)) { - data->rx.approx_mcast_engine_id = o->func_id; - data->rx.is_approx_mcast = 1; + rx_data->drop_ip_cs_err_flg = 0; + rx_data->drop_tcp_cs_err_flg = 0; + rx_data->drop_ttl0_flg = 0; + rx_data->drop_udp_cs_err_flg = 0; + rx_data->inner_vlan_removal_enable_flg = + test_bit(BNX2X_Q_FLG_VLAN, flags); + rx_data->outer_vlan_removal_enable_flg = + test_bit(BNX2X_Q_FLG_OV, flags); + rx_data->status_block_id = params->fw_sb_id; + rx_data->rx_sb_index_number = params->sb_cq_index; + rx_data->max_tpa_queues = params->max_tpa_queues; + rx_data->max_bytes_on_bd = cpu_to_le16(params->buf_sz); + rx_data->sge_buff_size = cpu_to_le16(params->sge_buf_sz); + rx_data->bd_page_base.lo = + cpu_to_le32(U64_LO(params->dscr_map)); + rx_data->bd_page_base.hi = + cpu_to_le32(U64_HI(params->dscr_map)); + rx_data->sge_page_base.lo = + cpu_to_le32(U64_LO(params->sge_map)); + rx_data->sge_page_base.hi = + cpu_to_le32(U64_HI(params->sge_map)); + rx_data->cqe_page_base.lo = + cpu_to_le32(U64_LO(params->rcq_map)); + rx_data->cqe_page_base.hi = + cpu_to_le32(U64_HI(params->rcq_map)); + rx_data->is_leading_rss = test_bit(BNX2X_Q_FLG_LEADING_RSS, flags); + + if (test_bit(BNX2X_Q_FLG_MCAST, flags)) { + rx_data->approx_mcast_engine_id = o->func_id; + rx_data->is_approx_mcast = 1; } - data->rx.rss_engine_id = params->rxq_params.rss_engine_id; - - /* flow control data */ - data->rx.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); - data->rx.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); - data->rx.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); - data->rx.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); - data->rx.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); - data->rx.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); - data->rx.rx_cos_mask = cpu_to_le16(params->pause.pri_map); + rx_data->rss_engine_id = params->rss_engine_id; /* silent vlan removal */ - data->rx.silent_vlan_removal_flg = - test_bit(BNX2X_Q_FLG_SILENT_VLAN_REM, ¶ms->flags); - data->rx.silent_vlan_value = - cpu_to_le16(params->rxq_params.silent_removal_value); - data->rx.silent_vlan_mask = - cpu_to_le16(params->rxq_params.silent_removal_mask); - - /* Tx data */ - data->tx.enforce_security_flg = - test_bit(BNX2X_Q_FLG_TX_SEC, ¶ms->flags); - data->tx.default_vlan = - cpu_to_le16(params->txq_params.default_vlan); - data->tx.default_vlan_flg = - test_bit(BNX2X_Q_FLG_DEF_VLAN, ¶ms->flags); - data->tx.tx_switching_flg = - test_bit(BNX2X_Q_FLG_TX_SWITCH, ¶ms->flags); - data->tx.anti_spoofing_flg = - test_bit(BNX2X_Q_FLG_ANTI_SPOOF, ¶ms->flags); - data->tx.tx_status_block_id = params->txq_params.fw_sb_id; - data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; - data->tx.tss_leading_client_id = params->txq_params.tss_leading_cl_id; - - data->tx.tx_bd_page_base.lo = - cpu_to_le32(U64_LO(params->txq_params.dscr_map)); - data->tx.tx_bd_page_base.hi = - cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + rx_data->silent_vlan_removal_flg = + test_bit(BNX2X_Q_FLG_SILENT_VLAN_REM, flags); + rx_data->silent_vlan_value = + cpu_to_le16(params->silent_removal_value); + rx_data->silent_vlan_mask = + cpu_to_le16(params->silent_removal_mask); - /* Don't configure any Tx switching mode during queue SETUP */ - data->tx.state = 0; } +/* initialize the general, tx and rx parts of a queue object */ +static void bnx2x_q_fill_setup_data_cmn(struct bnx2x *bp, + struct bnx2x_queue_state_params *cmd_params, + struct client_init_ramrod_data *data) +{ + bnx2x_q_fill_init_general_data(bp, cmd_params->q_obj, + &cmd_params->params.setup.gen_params, + &data->general, + &cmd_params->params.setup.flags); + + bnx2x_q_fill_init_tx_data(cmd_params->q_obj, + &cmd_params->params.setup.txq_params, + &data->tx, + &cmd_params->params.setup.flags); + + bnx2x_q_fill_init_rx_data(cmd_params->q_obj, + &cmd_params->params.setup.rxq_params, + &data->rx, + &cmd_params->params.setup.flags); + + bnx2x_q_fill_init_pause_data(cmd_params->q_obj, + &cmd_params->params.setup.pause_params, + &data->rx); +} + +/* initialize the general and tx parts of a tx-only queue object */ +static void bnx2x_q_fill_setup_tx_only(struct bnx2x *bp, + struct bnx2x_queue_state_params *cmd_params, + struct tx_queue_init_ramrod_data *data) +{ + bnx2x_q_fill_init_general_data(bp, cmd_params->q_obj, + &cmd_params->params.tx_only.gen_params, + &data->general, + &cmd_params->params.tx_only.flags); + + bnx2x_q_fill_init_tx_data(cmd_params->q_obj, + &cmd_params->params.tx_only.txq_params, + &data->tx, + &cmd_params->params.tx_only.flags); + + DP(BNX2X_MSG_SP, "cid %d, tx bd page lo %x hi %x",cmd_params->q_obj->cids[0], + data->tx.tx_bd_page_base.lo, data->tx.tx_bd_page_base.hi); +} /** * bnx2x_q_init - init HW/FW queue @@ -4377,6 +4449,7 @@ static inline int bnx2x_q_init(struct bnx2x *bp, struct bnx2x_queue_sp_obj *o = params->q_obj; struct bnx2x_queue_init_params *init = ¶ms->params.init; u16 hc_usec; + u8 cos; /* Tx HC configuration */ if (test_bit(BNX2X_Q_TYPE_HAS_TX, &o->type) && @@ -4401,7 +4474,12 @@ static inline int bnx2x_q_init(struct bnx2x *bp, } /* Set CDU context validation values */ - bnx2x_set_ctx_validation(bp, init->cxt, o->cid); + for (cos = 0; cos < o->max_cos; cos++) { + DP(BNX2X_MSG_SP, "setting context validation. cid %d, cos %d", + o->cids[cos], cos); + DP(BNX2X_MSG_SP, "context pointer %p", init->cxts[cos]); + bnx2x_set_ctx_validation(bp, init->cxts[cos], o->cids[cos]); + } /* As no ramrod is sent, complete the command immediately */ o->complete_cmd(bp, o, BNX2X_Q_CMD_INIT); @@ -4429,7 +4507,8 @@ static inline int bnx2x_q_send_setup_e1x(struct bnx2x *bp, mb(); - return bnx2x_sp_post(bp, ramrod, o->cid, U64_HI(data_mapping), + return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], + U64_HI(data_mapping), U64_LO(data_mapping), ETH_CONNECTION_TYPE); } @@ -4449,9 +4528,57 @@ static inline int bnx2x_q_send_setup_e2(struct bnx2x *bp, bnx2x_q_fill_setup_data_cmn(bp, params, rdata); bnx2x_q_fill_setup_data_e2(bp, params, rdata); - mb(); - return bnx2x_sp_post(bp, ramrod, o->cid, U64_HI(data_mapping), + return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], + U64_HI(data_mapping), + U64_LO(data_mapping), ETH_CONNECTION_TYPE); +} + +static inline int bnx2x_q_send_setup_tx_only(struct bnx2x *bp, + struct bnx2x_queue_state_params *params) +{ + struct bnx2x_queue_sp_obj *o = params->q_obj; + struct tx_queue_init_ramrod_data *rdata = + (struct tx_queue_init_ramrod_data *)o->rdata; + dma_addr_t data_mapping = o->rdata_mapping; + int ramrod = RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP; + struct bnx2x_queue_setup_tx_only_params *tx_only_params = + ¶ms->params.tx_only; + u8 cid_index = tx_only_params->cid_index; + + + if (cid_index >= o->max_cos) { + BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", + o->cl_id, cid_index); + return -EINVAL; + } + + DP(BNX2X_MSG_SP, "parameters received: cos: %d sp-id: %d", + tx_only_params->gen_params.cos, + tx_only_params->gen_params.spcl_id); + + /* Clear the ramrod data */ + memset(rdata, 0, sizeof(*rdata)); + + /* Fill the ramrod data */ + bnx2x_q_fill_setup_tx_only(bp, params, rdata); + + DP(BNX2X_MSG_SP, "sending tx-only ramrod: cid %d, client-id %d," + "sp-client id %d, cos %d", + o->cids[cid_index], + rdata->general.client_id, + rdata->general.sp_client_id, rdata->general.cos); + + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ + + return bnx2x_sp_post(bp, ramrod, o->cids[cid_index], + U64_HI(data_mapping), U64_LO(data_mapping), ETH_CONNECTION_TYPE); } @@ -4521,17 +4648,27 @@ static inline int bnx2x_q_send_update(struct bnx2x *bp, struct client_update_ramrod_data *rdata = (struct client_update_ramrod_data *)o->rdata; dma_addr_t data_mapping = o->rdata_mapping; + struct bnx2x_queue_update_params *update_params = + ¶ms->params.update; + u8 cid_index = update_params->cid_index; + + if (cid_index >= o->max_cos) { + BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", + o->cl_id, cid_index); + return -EINVAL; + } + /* Clear the ramrod data */ memset(rdata, 0, sizeof(*rdata)); /* Fill the ramrod data */ - bnx2x_q_fill_update_data(bp, o, ¶ms->params.update, rdata); + bnx2x_q_fill_update_data(bp, o, update_params, rdata); mb(); - return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, o->cid, - U64_HI(data_mapping), + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, + o->cids[cid_index], U64_HI(data_mapping), U64_LO(data_mapping), ETH_CONNECTION_TYPE); } @@ -4588,7 +4725,8 @@ static inline int bnx2x_q_send_halt(struct bnx2x *bp, { struct bnx2x_queue_sp_obj *o = params->q_obj; - return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, o->cid, 0, o->cl_id, + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, + o->cids[BNX2X_PRIMARY_CID_INDEX], 0, o->cl_id, ETH_CONNECTION_TYPE); } @@ -4596,18 +4734,32 @@ static inline int bnx2x_q_send_cfc_del(struct bnx2x *bp, struct bnx2x_queue_state_params *params) { struct bnx2x_queue_sp_obj *o = params->q_obj; + u8 cid_idx = params->params.cfc_del.cid_index; - return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, o->cid, 0, 0, - NONE_CONNECTION_TYPE); + if (cid_idx >= o->max_cos) { + BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", + o->cl_id, cid_idx); + return -EINVAL; + } + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, + o->cids[cid_idx], 0, 0, NONE_CONNECTION_TYPE); } static inline int bnx2x_q_send_terminate(struct bnx2x *bp, struct bnx2x_queue_state_params *params) { struct bnx2x_queue_sp_obj *o = params->q_obj; + u8 cid_index = params->params.terminate.cid_index; - return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, o->cid, 0, 0, - ETH_CONNECTION_TYPE); + if (cid_index >= o->max_cos) { + BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n", + o->cl_id, cid_index); + return -EINVAL; + } + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, + o->cids[cid_index], 0, 0, ETH_CONNECTION_TYPE); } static inline int bnx2x_q_send_empty(struct bnx2x *bp, @@ -4615,7 +4767,8 @@ static inline int bnx2x_q_send_empty(struct bnx2x *bp, { struct bnx2x_queue_sp_obj *o = params->q_obj; - return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_EMPTY, o->cid, 0, 0, + return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_EMPTY, + o->cids[BNX2X_PRIMARY_CID_INDEX], 0, 0, ETH_CONNECTION_TYPE); } @@ -4625,6 +4778,8 @@ static inline int bnx2x_queue_send_cmd_cmn(struct bnx2x *bp, switch (params->cmd) { case BNX2X_Q_CMD_INIT: return bnx2x_q_init(bp, params); + case BNX2X_Q_CMD_SETUP_TX_ONLY: + return bnx2x_q_send_setup_tx_only(bp, params); case BNX2X_Q_CMD_DEACTIVATE: return bnx2x_q_send_deactivate(bp, params); case BNX2X_Q_CMD_ACTIVATE: @@ -4654,6 +4809,7 @@ static int bnx2x_queue_send_cmd_e1x(struct bnx2x *bp, case BNX2X_Q_CMD_SETUP: return bnx2x_q_send_setup_e1x(bp, params); case BNX2X_Q_CMD_INIT: + case BNX2X_Q_CMD_SETUP_TX_ONLY: case BNX2X_Q_CMD_DEACTIVATE: case BNX2X_Q_CMD_ACTIVATE: case BNX2X_Q_CMD_UPDATE: @@ -4676,6 +4832,7 @@ static int bnx2x_queue_send_cmd_e2(struct bnx2x *bp, case BNX2X_Q_CMD_SETUP: return bnx2x_q_send_setup_e2(bp, params); case BNX2X_Q_CMD_INIT: + case BNX2X_Q_CMD_SETUP_TX_ONLY: case BNX2X_Q_CMD_DEACTIVATE: case BNX2X_Q_CMD_ACTIVATE: case BNX2X_Q_CMD_UPDATE: @@ -4713,6 +4870,9 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, { enum bnx2x_q_state state = o->state, next_state = BNX2X_Q_STATE_MAX; enum bnx2x_queue_cmd cmd = params->cmd; + struct bnx2x_queue_update_params *update_params = + ¶ms->params.update; + u8 next_tx_only = o->num_tx_only; switch (state) { case BNX2X_Q_STATE_RESET: @@ -4738,13 +4898,42 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, (cmd == BNX2X_Q_CMD_UPDATE_TPA)) next_state = BNX2X_Q_STATE_ACTIVE; + else if (cmd == BNX2X_Q_CMD_SETUP_TX_ONLY) { + next_state = BNX2X_Q_STATE_MULTI_COS; + next_tx_only = 1; + } + else if (cmd == BNX2X_Q_CMD_HALT) next_state = BNX2X_Q_STATE_STOPPED; else if (cmd == BNX2X_Q_CMD_UPDATE) { - struct bnx2x_queue_update_params *update_params = - ¶ms->params.update; + /* If "active" state change is requested, update the + * state accordingly. + */ + if (test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, + &update_params->update_flags) && + !test_bit(BNX2X_Q_UPDATE_ACTIVATE, + &update_params->update_flags)) + next_state = BNX2X_Q_STATE_INACTIVE; + else + next_state = BNX2X_Q_STATE_ACTIVE; + } + break; + case BNX2X_Q_STATE_MULTI_COS: + if (cmd == BNX2X_Q_CMD_TERMINATE) + next_state = BNX2X_Q_STATE_MCOS_TERMINATED; + + else if (cmd == BNX2X_Q_CMD_SETUP_TX_ONLY) { + next_state = BNX2X_Q_STATE_MULTI_COS; + next_tx_only = o->num_tx_only + 1; + } + + else if ((cmd == BNX2X_Q_CMD_EMPTY) || + (cmd == BNX2X_Q_CMD_UPDATE_TPA)) + next_state = BNX2X_Q_STATE_MULTI_COS; + + else if (cmd == BNX2X_Q_CMD_UPDATE) { /* If "active" state change is requested, update the * state accordingly. */ @@ -4754,7 +4943,17 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, &update_params->update_flags)) next_state = BNX2X_Q_STATE_INACTIVE; else + next_state = BNX2X_Q_STATE_MULTI_COS; + } + + break; + case BNX2X_Q_STATE_MCOS_TERMINATED: + if (cmd == BNX2X_Q_CMD_CFC_DEL) { + next_tx_only = o->num_tx_only - 1; + if (next_tx_only == 0) next_state = BNX2X_Q_STATE_ACTIVE; + else + next_state = BNX2X_Q_STATE_MULTI_COS; } break; @@ -4770,18 +4969,18 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, next_state = BNX2X_Q_STATE_STOPPED; else if (cmd == BNX2X_Q_CMD_UPDATE) { - struct bnx2x_queue_update_params *update_params = - ¶ms->params.update; - /* If "active" state change is requested, update the * state accordingly. */ if (test_bit(BNX2X_Q_UPDATE_ACTIVATE_CHNG, &update_params->update_flags) && test_bit(BNX2X_Q_UPDATE_ACTIVATE, - &update_params->update_flags)) - next_state = BNX2X_Q_STATE_ACTIVE; - else + &update_params->update_flags)){ + if (o->num_tx_only == 0) + next_state = BNX2X_Q_STATE_ACTIVE; + else /* tx only queues exist for this queue */ + next_state = BNX2X_Q_STATE_MULTI_COS; + } else next_state = BNX2X_Q_STATE_INACTIVE; } @@ -4805,6 +5004,7 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, DP(BNX2X_MSG_SP, "Good state transition: %d(%d)->%d\n", state, cmd, next_state); o->next_state = next_state; + o->next_tx_only = next_tx_only; return 0; } @@ -4815,12 +5015,17 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, void bnx2x_init_queue_obj(struct bnx2x *bp, struct bnx2x_queue_sp_obj *obj, - u8 cl_id, u32 cid, u8 func_id, void *rdata, + u8 cl_id, u32 *cids, u8 cid_cnt, u8 func_id, + void *rdata, dma_addr_t rdata_mapping, unsigned long type) { memset(obj, 0, sizeof(*obj)); - obj->cid = cid; + /* We support only BNX2X_MULTI_TX_COS Tx CoS at the moment */ + BUG_ON(BNX2X_MULTI_TX_COS < cid_cnt); + + memcpy(obj->cids, cids, sizeof(obj->cids[0]) * cid_cnt); + obj->max_cos = cid_cnt; obj->cl_id = cl_id; obj->func_id = func_id; obj->rdata = rdata; @@ -4840,6 +5045,13 @@ void bnx2x_init_queue_obj(struct bnx2x *bp, obj->set_pending = bnx2x_queue_set_pending; } +void bnx2x_queue_set_cos_cid(struct bnx2x *bp, + struct bnx2x_queue_sp_obj *obj, + u32 cid, u8 index) +{ + obj->cids[index] = cid; +} + /********************** Function state object *********************************/ static int bnx2x_func_wait_comp(struct bnx2x *bp, diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h index 86eaa80721e..83f3b0b4421 100644 --- a/drivers/net/bnx2x/bnx2x_sp.h +++ b/drivers/net/bnx2x/bnx2x_sp.h @@ -721,6 +721,8 @@ enum bnx2x_q_state { BNX2X_Q_STATE_RESET, BNX2X_Q_STATE_INITIALIZED, BNX2X_Q_STATE_ACTIVE, + BNX2X_Q_STATE_MULTI_COS, + BNX2X_Q_STATE_MCOS_TERMINATED, BNX2X_Q_STATE_INACTIVE, BNX2X_Q_STATE_STOPPED, BNX2X_Q_STATE_TERMINATED, @@ -732,6 +734,7 @@ enum bnx2x_q_state { enum bnx2x_queue_cmd { BNX2X_Q_CMD_INIT, BNX2X_Q_CMD_SETUP, + BNX2X_Q_CMD_SETUP_TX_ONLY, BNX2X_Q_CMD_DEACTIVATE, BNX2X_Q_CMD_ACTIVATE, BNX2X_Q_CMD_UPDATE, @@ -774,6 +777,13 @@ enum bnx2x_q_type { BNX2X_Q_TYPE_HAS_TX, }; +#define BNX2X_PRIMARY_CID_INDEX 0 +#define BNX2X_MULTI_TX_COS_E1X 1 +#define BNX2X_MULTI_TX_COS_E2_E3A0 2 +#define BNX2X_MULTI_TX_COS_E3B0 3 +#define BNX2X_MULTI_TX_COS BNX2X_MULTI_TX_COS_E3B0 + + struct bnx2x_queue_init_params { struct { unsigned long flags; @@ -790,7 +800,20 @@ struct bnx2x_queue_init_params { } rx; /* CID context in the host memory */ - struct eth_context *cxt; + struct eth_context *cxts[BNX2X_MULTI_TX_COS]; + + /* maximum number of cos supported by hardware */ + u8 max_cos; +}; + +struct bnx2x_queue_terminate_params { + /* index within the tx_only cids of this queue object */ + u8 cid_index; +}; + +struct bnx2x_queue_cfc_del_params { + /* index within the tx_only cids of this queue object */ + u8 cid_index; }; struct bnx2x_queue_update_params { @@ -798,6 +821,8 @@ struct bnx2x_queue_update_params { u16 def_vlan; u16 silent_removal_value; u16 silent_removal_mask; +/* index within the tx_only cids of this queue object */ + u8 cid_index; }; struct rxq_pause_params { @@ -817,6 +842,7 @@ struct bnx2x_general_setup_params { u8 spcl_id; u16 mtu; + u8 cos; }; struct bnx2x_rxq_setup_params { @@ -863,13 +889,20 @@ struct bnx2x_txq_setup_params { }; struct bnx2x_queue_setup_params { - struct rxq_pause_params pause; struct bnx2x_general_setup_params gen_params; - struct bnx2x_rxq_setup_params rxq_params; struct bnx2x_txq_setup_params txq_params; + struct bnx2x_rxq_setup_params rxq_params; + struct rxq_pause_params pause_params; unsigned long flags; }; +struct bnx2x_queue_setup_tx_only_params { + struct bnx2x_general_setup_params gen_params; + struct bnx2x_txq_setup_params txq_params; + unsigned long flags; + /* index within the tx_only cids of this queue object */ + u8 cid_index; +}; struct bnx2x_queue_state_params { struct bnx2x_queue_sp_obj *q_obj; @@ -878,21 +911,36 @@ struct bnx2x_queue_state_params { enum bnx2x_queue_cmd cmd; /* may have RAMROD_COMP_WAIT set only */ - unsigned long ramrod_flags; + unsigned long ramrod_flags; /* Params according to the current command */ union { - struct bnx2x_queue_update_params update; - struct bnx2x_queue_setup_params setup; - struct bnx2x_queue_init_params init; + struct bnx2x_queue_update_params update; + struct bnx2x_queue_setup_params setup; + struct bnx2x_queue_init_params init; + struct bnx2x_queue_setup_tx_only_params tx_only; + struct bnx2x_queue_terminate_params terminate; + struct bnx2x_queue_cfc_del_params cfc_del; } params; }; struct bnx2x_queue_sp_obj { - u32 cid; + u32 cids[BNX2X_MULTI_TX_COS]; u8 cl_id; u8 func_id; + /* + * number of traffic classes supported by queue. + * The primary connection of the queue suppotrs the first traffic + * class. Any further traffic class is suppoted by a tx-only + * connection. + * + * Therefore max_cos is also a number of valid entries in the cids + * array. + */ + u8 max_cos; + u8 num_tx_only, next_tx_only; + enum bnx2x_q_state state, next_state; /* bits from enum bnx2x_q_type */ @@ -1106,9 +1154,9 @@ int bnx2x_func_state_change(struct bnx2x *bp, /******************* Queue State **************/ void bnx2x_init_queue_obj(struct bnx2x *bp, - struct bnx2x_queue_sp_obj *obj, u8 cl_id, u32 cid, - u8 func_id, void *rdata, dma_addr_t rdata_mapping, - unsigned long type); + struct bnx2x_queue_sp_obj *obj, u8 cl_id, u32 *cids, + u8 cid_cnt, u8 func_id, void *rdata, + dma_addr_t rdata_mapping, unsigned long type); int bnx2x_queue_state_change(struct bnx2x *bp, struct bnx2x_queue_state_params *params); diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 54c07f557ad..771f6803b23 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -1185,7 +1185,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) if (netif_msg_timer(bp)) { struct bnx2x_eth_stats *estats = &bp->eth_stats; - int i; + int i, cos; netdev_dbg(bp->dev, "brb drops %u brb truncate %u\n", estats->brb_drop_lo, estats->brb_truncate_lo); @@ -1206,20 +1206,32 @@ static void bnx2x_stats_update(struct bnx2x *bp) for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; + struct bnx2x_fp_txdata *txdata; struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; - struct netdev_queue *txq = - netdev_get_tx_queue(bp->dev, i); - - printk(KERN_DEBUG "%s: tx avail(%4u) *tx_cons_sb(%u)" - " tx pkt(%lu) tx calls (%lu)" - " %s (Xoff events %u)\n", - fp->name, bnx2x_tx_avail(fp), - le16_to_cpu(*fp->tx_cons_sb), - bnx2x_hilo(&qstats-> - total_unicast_packets_transmitted_hi), - fp->tx_pkt, - (netif_tx_queue_stopped(txq) ? "Xoff" : "Xon"), - qstats->driver_xoff); + struct netdev_queue *txq; + + printk(KERN_DEBUG "%s: tx pkt(%lu) (Xoff events %u)", + fp->name, bnx2x_hilo( + &qstats->total_unicast_packets_transmitted_hi), + qstats->driver_xoff); + + for_each_cos_in_tx_queue(fp, cos) { + txdata = &fp->txdata[cos]; + txq = netdev_get_tx_queue(bp->dev, + FP_COS_TO_TXQ(fp, cos)); + + printk(KERN_DEBUG "%d: tx avail(%4u)" + " *tx_cons_sb(%u)" + " tx calls (%lu)" + " %s\n", + cos, + bnx2x_tx_avail(bp, txdata), + le16_to_cpu(*txdata->tx_cons_sb), + txdata->tx_pkt, + (netif_tx_queue_stopped(txq) ? + "Xoff" : "Xon") + ); + } } } -- cgit v1.2.3-70-g09d2 From ecae42d37045ec71831d0e0e493e00b0e0732edd Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 14 Jul 2011 16:03:29 -0700 Subject: net/ps3: Fix gelic RX DMA restart Fix the condition where PS3 network RX hangs when no network TX is occurring by calling gelic_card_enable_rxdmac() during RX_DMA_CHAIN_END event processing. The gelic hardware automatically clears its RX_DMA_EN flag when it detects an RX_DMA_CHAIN_END event. In its processing of RX_DMA_CHAIN_END the gelic driver is required to set RX_DMA_EN (with a call to gelic_card_enable_rxdmac()) to restart RX DMA transfers. The existing gelic driver code does not set RX_DMA_EN directly in its processing of the RX_DMA_CHAIN_END event, but uses a flag variable card->rx_dma_restart_required to schedule the setting of RX_DMA_EN until next inside the interrupt handler. It seems this delayed setting of RX_DMA_EN causes the hang since the next RX interrupt after the RX_DMA_CHAIN_END event where RX_DMA_EN is scheduled to be set will not occur since RX_DMA_EN was not set. In the case were network TX is occuring, RX_DMA_EN is set in the next TX interrupt and RX processing continues. Signed-off-by: Geoff Levand Signed-off-by: David S. Miller --- drivers/net/ps3_gelic_net.c | 21 ++++++++------------- drivers/net/ps3_gelic_net.h | 1 - 2 files changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 4acc17bffc4..d82a82d9870 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -993,10 +993,6 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) int dmac_chain_ended; status = gelic_descr_get_status(descr); - /* is this descriptor terminated with next_descr == NULL? */ - dmac_chain_ended = - be32_to_cpu(descr->dmac_cmd_status) & - GELIC_DESCR_RX_DMA_CHAIN_END; if (status == GELIC_DESCR_DMA_CARDOWNED) return 0; @@ -1059,6 +1055,11 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) /* ok, we've got a packet in descr */ gelic_net_pass_skb_up(descr, card, netdev); refill: + + /* is the current descriptor terminated with next_descr == NULL? */ + dmac_chain_ended = + be32_to_cpu(descr->dmac_cmd_status) & + GELIC_DESCR_RX_DMA_CHAIN_END; /* * So that always DMAC can see the end * of the descriptor chain to avoid @@ -1087,10 +1088,9 @@ refill: * If dmac chain was met, DMAC stopped. * thus re-enable it */ - if (dmac_chain_ended) { - card->rx_dma_restart_required = 1; - dev_dbg(ctodev(card), "reenable rx dma scheduled\n"); - } + + if (dmac_chain_ended) + gelic_card_enable_rxdmac(card); return 1; } @@ -1156,11 +1156,6 @@ static irqreturn_t gelic_card_interrupt(int irq, void *ptr) status &= card->irq_mask; - if (card->rx_dma_restart_required) { - card->rx_dma_restart_required = 0; - gelic_card_enable_rxdmac(card); - } - if (status & GELIC_CARD_RXINT) { gelic_card_rx_irq_off(card); napi_schedule(&card->napi); diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h index d9a55b93898..d3fadfbc3bc 100644 --- a/drivers/net/ps3_gelic_net.h +++ b/drivers/net/ps3_gelic_net.h @@ -289,7 +289,6 @@ struct gelic_card { struct gelic_descr_chain tx_chain; struct gelic_descr_chain rx_chain; - int rx_dma_restart_required; /* * tx_lock guards tx descriptor list and * tx_dma_progress. -- cgit v1.2.3-70-g09d2 From 8279171a5fe95902be12f4018907f246d51616d4 Mon Sep 17 00:00:00 2001 From: Shyam Iyer Date: Thu, 14 Jul 2011 15:00:32 +0000 Subject: Separate handling of irq type flags variable from the irq_flags request_irq variable Commit 5f77898de17ff983ff0e2988b73a6bdf4b6f9f8b does not completely fix the problem of handling allocations with irqs disabled.. The below patch on top of it fixes the problem completely. Based on review by "Ivan Vecera" .. " Small note, the root of the problem was that non-atomic allocation was requested with IRQs disabled. Your patch description does not contain wwhy were the IRQs disabled. The function bnad_mbox_irq_alloc incorrectly uses 'flags' var for two different things, 1) to save current CPU flags and 2) for request_irq call. First the spin_lock_irqsave disables the IRQs and saves _all_ CPU flags (including one that enables/disables interrupts) to 'flags'. Then the 'flags' is overwritten by 0 or 0x80 (IRQF_SHARED). Finally the spin_unlock_irqrestore should restore saved flags, but these flags are now either 0x00 or 0x80. The interrupt bit value in flags register on x86 arch is 0x100. This means that the interrupt bit is zero (IRQs disabled) after spin_unlock_irqrestore so the request_irq function is called with disabled interrupts. " Signed-off-by: Shyam Iyer Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 795b93b73b1..fa997bfc2e5 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -1109,7 +1109,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, struct bna_intr_info *intr_info) { int err = 0; - unsigned long irq_flags = 0, flags; + unsigned long irq_flags, flags; u32 irq; irq_handler_t irq_handler; @@ -1123,6 +1123,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, if (bnad->cfg_flags & BNAD_CF_MSIX) { irq_handler = (irq_handler_t)bnad_msix_mbox_handler; irq = bnad->msix_table[bnad->msix_num - 1].vector; + irq_flags = 0; intr_info->intr_type = BNA_INTR_T_MSIX; intr_info->idl[0].vector = bnad->msix_num - 1; } else { @@ -1133,7 +1134,6 @@ bnad_mbox_irq_alloc(struct bnad *bnad, /* intr_info->idl.vector = 0 ? */ } spin_unlock_irqrestore(&bnad->bna_lock, flags); - flags = irq_flags; sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); /* @@ -1144,7 +1144,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); - err = request_irq(irq, irq_handler, flags, + err = request_irq(irq, irq_handler, irq_flags, bnad->mbox_irq_name, bnad); if (err) { -- cgit v1.2.3-70-g09d2 From 2af4ba85913bb1755a06193109917c3ddc130265 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Thu, 14 Jul 2011 21:49:19 +0000 Subject: slcan: remove obsolete code in slcan initialisation This patch removes obsolete code in the initialisation/creation of slcan devices. It follows the suggested cleanups from Ilya Matvejchikov in drivers/net/slip.c that where recently applied to net-next-2.6: - slip: remove dead code within the slip initialization - slip: remove redundant check slip_devs for NULL Signed-off-by: Oliver Hartkopp Signed-off-by: David S. Miller --- drivers/net/can/slcan.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 1b49df6b247..aa8ad73477b 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -473,12 +473,10 @@ static void slc_sync(void) static struct slcan *slc_alloc(dev_t line) { int i; + char name[IFNAMSIZ]; struct net_device *dev = NULL; struct slcan *sl; - if (slcan_devs == NULL) - return NULL; /* Master array missing ! */ - for (i = 0; i < maxdev; i++) { dev = slcan_devs[i]; if (dev == NULL) @@ -490,25 +488,12 @@ static struct slcan *slc_alloc(dev_t line) if (i >= maxdev) return NULL; - if (dev) { - sl = netdev_priv(dev); - if (test_bit(SLF_INUSE, &sl->flags)) { - unregister_netdevice(dev); - dev = NULL; - slcan_devs[i] = NULL; - } - } - - if (!dev) { - char name[IFNAMSIZ]; - sprintf(name, "slcan%d", i); - - dev = alloc_netdev(sizeof(*sl), name, slc_setup); - if (!dev) - return NULL; - dev->base_addr = i; - } + sprintf(name, "slcan%d", i); + dev = alloc_netdev(sizeof(*sl), name, slc_setup); + if (!dev) + return NULL; + dev->base_addr = i; sl = netdev_priv(dev); /* Initialize channel control data */ -- cgit v1.2.3-70-g09d2 From 6864ddb2d3089739d29418a1ff52adb2fbf9c0ca Mon Sep 17 00:00:00 2001 From: françois romieu Date: Fri, 15 Jul 2011 00:21:44 +0000 Subject: 8139cp: convert to new VLAN model. The registers and descriptors bits are identical to the pre-8168 8169 chipsets : {RxDesc / TxDesc}.opts2 can only contain VLAN information. Signed-off-by: Francois Romieu Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/8139cp.c | 83 +++++++++++++++++----------------------------------- 1 file changed, 27 insertions(+), 56 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 73b10b07f9b..cc4c210a91f 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -78,17 +78,6 @@ #include #include -/* VLAN tagging feature enable/disable */ -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define CP_VLAN_TAG_USED 1 -#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \ - do { (tx_desc)->opts2 = cpu_to_le32(vlan_tag_value); } while (0) -#else -#define CP_VLAN_TAG_USED 0 -#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \ - do { (tx_desc)->opts2 = 0; } while (0) -#endif - /* These identify the driver base version and may not be removed. */ static char version[] = DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; @@ -356,9 +345,6 @@ struct cp_private { unsigned rx_buf_sz; unsigned wol_enabled : 1; /* Is Wake-on-LAN enabled? */ -#if CP_VLAN_TAG_USED - struct vlan_group *vlgrp; -#endif dma_addr_t ring_dma; struct mii_if_info mii_if; @@ -423,24 +409,6 @@ static struct { }; -#if CP_VLAN_TAG_USED -static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct cp_private *cp = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&cp->lock, flags); - cp->vlgrp = grp; - if (grp) - cp->cpcmd |= RxVlanOn; - else - cp->cpcmd &= ~RxVlanOn; - - cpw16(CpCmd, cp->cpcmd); - spin_unlock_irqrestore(&cp->lock, flags); -} -#endif /* CP_VLAN_TAG_USED */ - static inline void cp_set_rxbufsize (struct cp_private *cp) { unsigned int mtu = cp->dev->mtu; @@ -455,18 +423,17 @@ static inline void cp_set_rxbufsize (struct cp_private *cp) static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb, struct cp_desc *desc) { + u32 opts2 = le32_to_cpu(desc->opts2); + skb->protocol = eth_type_trans (skb, cp->dev); cp->dev->stats.rx_packets++; cp->dev->stats.rx_bytes += skb->len; -#if CP_VLAN_TAG_USED - if (cp->vlgrp && (desc->opts2 & cpu_to_le32(RxVlanTagged))) { - vlan_hwaccel_receive_skb(skb, cp->vlgrp, - swab16(le32_to_cpu(desc->opts2) & 0xffff)); - } else -#endif - netif_receive_skb(skb); + if (opts2 & RxVlanTagged) + __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); + + napi_gro_receive(&cp->napi, skb); } static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail, @@ -730,6 +697,12 @@ static void cp_tx (struct cp_private *cp) netif_wake_queue(cp->dev); } +static inline u32 cp_tx_vlan_tag(struct sk_buff *skb) +{ + return vlan_tx_tag_present(skb) ? + TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; +} + static netdev_tx_t cp_start_xmit (struct sk_buff *skb, struct net_device *dev) { @@ -737,9 +710,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, unsigned entry; u32 eor, flags; unsigned long intr_flags; -#if CP_VLAN_TAG_USED - u32 vlan_tag = 0; -#endif + __le32 opts2; int mss = 0; spin_lock_irqsave(&cp->lock, intr_flags); @@ -752,15 +723,12 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, return NETDEV_TX_BUSY; } -#if CP_VLAN_TAG_USED - if (vlan_tx_tag_present(skb)) - vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb)); -#endif - entry = cp->tx_head; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; mss = skb_shinfo(skb)->gso_size; + opts2 = cpu_to_le32(cp_tx_vlan_tag(skb)); + if (skb_shinfo(skb)->nr_frags == 0) { struct cp_desc *txd = &cp->tx_ring[entry]; u32 len; @@ -768,7 +736,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, len = skb->len; mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE); - CP_VLAN_TX_TAG(txd, vlan_tag); + txd->opts2 = opts2; txd->addr = cpu_to_le64(mapping); wmb(); @@ -839,7 +807,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, ctrl |= LastFrag; txd = &cp->tx_ring[entry]; - CP_VLAN_TX_TAG(txd, vlan_tag); + txd->opts2 = opts2; txd->addr = cpu_to_le64(mapping); wmb(); @@ -851,7 +819,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, } txd = &cp->tx_ring[first_entry]; - CP_VLAN_TX_TAG(txd, vlan_tag); + txd->opts2 = opts2; txd->addr = cpu_to_le64(first_mapping); wmb(); @@ -1431,6 +1399,11 @@ static int cp_set_features(struct net_device *dev, u32 features) else cp->cpcmd &= ~RxChkSum; + if (features & NETIF_F_HW_VLAN_RX) + cp->cpcmd |= RxVlanOn; + else + cp->cpcmd &= ~RxVlanOn; + cpw16_f(CpCmd, cp->cpcmd); spin_unlock_irqrestore(&cp->lock, flags); @@ -1818,9 +1791,6 @@ static const struct net_device_ops cp_netdev_ops = { .ndo_start_xmit = cp_start_xmit, .ndo_tx_timeout = cp_tx_timeout, .ndo_set_features = cp_set_features, -#if CP_VLAN_TAG_USED - .ndo_vlan_rx_register = cp_vlan_rx_register, -#endif #ifdef BROKEN .ndo_change_mtu = cp_change_mtu, #endif @@ -1949,15 +1919,16 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev->ethtool_ops = &cp_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT; -#if CP_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif if (pci_using_dac) dev->features |= NETIF_F_HIGHDMA; /* disabled by default until verified */ - dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; + dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HIGHDMA; dev->irq = pdev->irq; -- cgit v1.2.3-70-g09d2 From cd6340199f65cad63262db0fd561bdcfd69df3bd Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 15 Jul 2011 06:53:58 +0000 Subject: bnx2: Close device if tx_timeout reset fails Based on original patch and description from Flavio Leitner When bnx2_reset_task() is called, it will stop, (re)initialize and start the interface to restore the working condition. The bnx2_init_nic() calls bnx2_reset_nic() which will reset the chip and then calls bnx2_free_skbs() to free all the skbs. The problem happens when bnx2_init_chip() fails because bnx2_reset_nic() will just return skipping the ring initializations at bnx2_init_all_rings(). Later, the reset task starts the interface again and the system crashes due a NULL pointer access (no skb in the ring). To fix it, we call dev_close() if bnx2_init_nic() fails. One minor wrinkle to deal with is the cancel_work_sync() call in bnx2_close() to cancel bnx2_reset_task(). The call will wait forever because it is trying to cancel itself and the workqueue will be stuck. Since bnx2_reset_task() holds the rtnl_lock() and checks for netif_running() before proceeding, there is no need to cancel bnx2_reset_task() in bnx2_close() even if bnx2_close() and bnx2_reset_task() are running concurrently. The rtnl_lock() serializes the 2 calls. We need to move the cancel_work_sync() call to bnx2_remove_one() to make sure it is canceled before freeing the netdev struct. Signed-off-by: Michael Chan Signed-off-by: Matt Carlson Cc: Flavio Leitner Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4816d6a5fe6..3ad9b70ef1b 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6342,6 +6342,7 @@ static void bnx2_reset_task(struct work_struct *work) { struct bnx2 *bp = container_of(work, struct bnx2, reset_task); + int rc; rtnl_lock(); if (!netif_running(bp->dev)) { @@ -6351,7 +6352,14 @@ bnx2_reset_task(struct work_struct *work) bnx2_netif_stop(bp, true); - bnx2_init_nic(bp, 1); + rc = bnx2_init_nic(bp, 1); + if (rc) { + netdev_err(bp->dev, "failed to reset NIC, closing\n"); + bnx2_napi_enable(bp); + dev_close(bp->dev); + rtnl_unlock(); + return; + } atomic_set(&bp->intr_sem, 1); bnx2_netif_start(bp, true); @@ -6573,8 +6581,6 @@ bnx2_close(struct net_device *dev) { struct bnx2 *bp = netdev_priv(dev); - cancel_work_sync(&bp->reset_task); - bnx2_disable_int_sync(bp); bnx2_napi_disable(bp); del_timer_sync(&bp->timer); @@ -8404,6 +8410,7 @@ bnx2_remove_one(struct pci_dev *pdev) unregister_netdev(dev); del_timer_sync(&bp->timer); + cancel_work_sync(&bp->reset_task); if (bp->mips_firmware) release_firmware(bp->mips_firmware); -- cgit v1.2.3-70-g09d2 From 2d9a8db54c4b1e206adb3b7942aefd544306560f Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Sat, 16 Jul 2011 12:35:27 -0700 Subject: 68360enet: Remove Kconfig/Makefile references 68360enet.c no longer exists, and from the research, it appears that 68360enet.c became fec.c back in 2004. The Kconfig and Makefile references were never cleaned up. This patch removes this "dead" references. Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/Kconfig | 7 ------- drivers/net/Makefile | 1 - 2 files changed, 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 17ed4dda7c0..8d0314dbd94 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1934,13 +1934,6 @@ config DECLANCE DEC (now Compaq) based on the AMD Lance chipset, including the DEPCA series. (This chipset is better known via the NE2100 cards.) -config 68360_ENET - bool "Motorola 68360 ethernet controller" - depends on M68360 - help - Say Y here if you want to use the built-in ethernet controller of - the Motorola 68360 processor. - config FEC bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" depends on M523x || M527x || M5272 || M528x || M520x || M532x || \ diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 86f6c8d0840..b7622c3745f 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -127,7 +127,6 @@ obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y) obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o endif -obj-$(CONFIG_68360_ENET) += 68360enet.o obj-$(CONFIG_WD80x3) += wd.o 8390.o obj-$(CONFIG_EL2) += 3c503.o 8390p.o obj-$(CONFIG_NE2000) += ne.o 8390p.o -- cgit v1.2.3-70-g09d2 From faa2831445cdc95774584045fe10f749fa62244e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sat, 16 Jul 2011 13:35:51 -0700 Subject: bnx2x: Fix compilation when CNIC is not selected in config Reported-by: Randy Dunlap Signed-off-by: Dmitry Kravkov Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index e5fac6244f4..b05ce9306de 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1403,8 +1403,8 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) { -#ifdef BCM_CNIC struct bnx2x *bp = netdev_priv(dev); +#ifdef BCM_CNIC if (NO_FCOE(bp)) return skb_tx_hash(dev, skb); else { -- cgit v1.2.3-70-g09d2 From 69ecca86da4890c13a5e29c51b4ac76a1a8a62c9 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 17 Jul 2011 08:53:12 +0000 Subject: net: vlan, qlcnic: make vlan_find_dev private there is only one user of vlan_find_dev outside of the actual vlan code: qlcnic uses it to iterate over some VLANs it knows. let's just make vlan_find_dev private to the VLAN code and have the iteration in qlcnic be a bit more direct. (a few rcu dereferences less too) Signed-off-by: David Lamparter Cc: Patrick McHardy Cc: Amit Kumar Salecha Cc: Anirban Chakraborty Cc: linux-driver@qlogic.com Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 7 ++++++- include/linux/if_vlan.h | 11 ----------- net/8021q/vlan.h | 12 ++++++++++++ 3 files changed, 18 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 006a693d49a..3579229db4a 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -4198,13 +4198,18 @@ static void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) { struct qlcnic_adapter *adapter = netdev_priv(netdev); + struct vlan_group *grp; struct net_device *dev; u16 vid; qlcnic_config_indev_addr(adapter, netdev, event); + grp = rcu_dereference_rtnl(netdev->vlgrp); + if (!grp) + return; + for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { - dev = vlan_find_dev(netdev, vid); + dev = vlan_group_get_device(grp, vid); if (!dev) continue; qlcnic_config_indev_addr(adapter, dev, event); diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index affa27380b7..bc03e40fd7f 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -119,17 +119,6 @@ static inline int is_vlan_dev(struct net_device *dev) #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -/* Must be invoked with rcu_read_lock or with RTNL. */ -static inline struct net_device *vlan_find_dev(struct net_device *real_dev, - u16 vlan_id) -{ - struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); - - if (grp) - return vlan_group_get_device(grp, vlan_id); - - return NULL; -} extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 9da07e30d1a..b132f542b44 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -74,6 +74,18 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) return netdev_priv(dev); } +/* Must be invoked with rcu_read_lock or with RTNL. */ +static inline struct net_device *vlan_find_dev(struct net_device *real_dev, + u16 vlan_id) +{ + struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); + + if (grp) + return vlan_group_get_device(grp, vlan_id); + + return NULL; +} + /* found in vlan_dev.c */ void vlan_dev_set_ingress_priority(const struct net_device *dev, u32 skb_prio, u16 vlan_prio); -- cgit v1.2.3-70-g09d2 From 69cce1d1404968f78b177a0314f5822d5afdbbfb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Jul 2011 23:09:49 -0700 Subject: net: Abstract dst->neighbour accesses behind helpers. dst_{get,set}_neighbour() Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 7 +++-- drivers/infiniband/hw/cxgb3/iwch_cm.c | 12 +++++--- drivers/infiniband/hw/cxgb4/cm.c | 42 +++++++++++++------------- drivers/infiniband/hw/nes/nes_cm.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 41 ++++++++++++++++--------- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 20 +++++++----- drivers/net/cxgb3/cxgb3_offload.c | 8 ++--- drivers/s390/net/qeth_l3_main.c | 25 ++++++++++----- drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 2 +- drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 2 +- drivers/scsi/cxgbi/libcxgbi.c | 4 +-- include/net/dst.h | 18 +++++++++-- net/atm/clip.c | 16 ++++++---- net/bridge/br_netfilter.c | 2 +- net/core/dst.c | 10 +++--- net/core/neighbour.c | 7 +++-- net/decnet/dn_neigh.c | 2 +- net/decnet/dn_route.c | 18 ++++++----- net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_output.c | 2 +- net/ipv4/route.c | 25 +++++++-------- net/ipv6/addrconf.c | 2 +- net/ipv6/ip6_fib.c | 2 +- net/ipv6/ip6_output.c | 16 ++++++---- net/ipv6/ndisc.c | 4 +-- net/ipv6/route.c | 39 ++++++++++++------------ net/ipv6/sit.c | 4 +-- net/sched/sch_teql.c | 4 +-- net/xfrm/xfrm_policy.c | 2 +- 29 files changed, 200 insertions(+), 140 deletions(-) (limited to 'drivers/net') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 8e21d457b89..236ad9a89c0 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -215,7 +215,7 @@ static int addr4_resolve(struct sockaddr_in *src_in, neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); if (!neigh || !(neigh->nud_state & NUD_VALID)) { - neigh_event_send(rt->dst.neighbour, NULL); + neigh_event_send(dst_get_neighbour(&rt->dst), NULL); ret = -ENODATA; if (neigh) goto release; @@ -273,9 +273,10 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; } - neigh = dst->neighbour; + neigh = dst_get_neighbour(dst); if (!neigh || !(neigh->nud_state & NUD_VALID)) { - neigh_event_send(dst->neighbour, NULL); + if (neigh) + neigh_event_send(neigh, NULL); ret = -ENODATA; goto put; } diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 0a5008fbeba..17bf9d95463 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -1328,6 +1328,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) struct iwch_ep *child_ep, *parent_ep = ctx; struct cpl_pass_accept_req *req = cplhdr(skb); unsigned int hwtid = GET_TID(req); + struct neighbour *neigh; struct dst_entry *dst; struct l2t_entry *l2t; struct rtable *rt; @@ -1364,7 +1365,8 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) goto reject; } dst = &rt->dst; - l2t = t3_l2t_get(tdev, dst->neighbour, dst->neighbour->dev); + neigh = dst_get_neighbour(dst); + l2t = t3_l2t_get(tdev, neigh, neigh->dev); if (!l2t) { printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", __func__); @@ -1874,10 +1876,11 @@ static int is_loopback_dst(struct iw_cm_id *cm_id) int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) { - int err = 0; struct iwch_dev *h = to_iwch_dev(cm_id->device); + struct neighbour *neigh; struct iwch_ep *ep; struct rtable *rt; + int err = 0; if (is_loopback_dst(cm_id)) { err = -ENOSYS; @@ -1933,9 +1936,10 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) } ep->dst = &rt->dst; + neigh = dst_get_neighbour(ep->dst); + /* get a l2t entry */ - ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst->neighbour, - ep->dst->neighbour->dev); + ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev); if (!ep->l2t) { printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); err = -ENOMEM; diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 31fb44085c9..77f769d9227 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1325,6 +1325,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid)); struct tid_info *t = dev->rdev.lldi.tids; unsigned int hwtid = GET_TID(req); + struct neighbour *neigh; struct dst_entry *dst; struct l2t_entry *l2t; struct rtable *rt; @@ -1357,11 +1358,11 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) goto reject; } dst = &rt->dst; - if (dst->neighbour->dev->flags & IFF_LOOPBACK) { + neigh = dst_get_neighbour(dst); + if (neigh->dev->flags & IFF_LOOPBACK) { pdev = ip_dev_find(&init_net, peer_ip); BUG_ON(!pdev); - l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour, - pdev, 0); + l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, pdev, 0); mtu = pdev->mtu; tx_chan = cxgb4_port_chan(pdev); smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; @@ -1372,17 +1373,16 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) rss_qid = dev->rdev.lldi.rxq_ids[cxgb4_port_idx(pdev) * step]; dev_put(pdev); } else { - l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour, - dst->neighbour->dev, 0); + l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, neigh->dev, 0); mtu = dst_mtu(dst); - tx_chan = cxgb4_port_chan(dst->neighbour->dev); - smac_idx = (cxgb4_port_viid(dst->neighbour->dev) & 0x7F) << 1; + tx_chan = cxgb4_port_chan(neigh->dev); + smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1; step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan; - txq_idx = cxgb4_port_idx(dst->neighbour->dev) * step; - ctrlq_idx = cxgb4_port_idx(dst->neighbour->dev); + txq_idx = cxgb4_port_idx(neigh->dev) * step; + ctrlq_idx = cxgb4_port_idx(neigh->dev); step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan; rss_qid = dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(dst->neighbour->dev) * step]; + cxgb4_port_idx(neigh->dev) * step]; } if (!l2t) { printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", @@ -1847,6 +1847,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct c4iw_ep *ep; struct rtable *rt; struct net_device *pdev; + struct neighbour *neigh; int step; if ((conn_param->ord > c4iw_max_read_depth) || @@ -1908,14 +1909,15 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) } ep->dst = &rt->dst; + neigh = dst_get_neighbour(ep->dst); + /* get a l2t entry */ - if (ep->dst->neighbour->dev->flags & IFF_LOOPBACK) { + if (neigh->dev->flags & IFF_LOOPBACK) { PDBG("%s LOOPBACK\n", __func__); pdev = ip_dev_find(&init_net, cm_id->remote_addr.sin_addr.s_addr); ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - ep->dst->neighbour, - pdev, 0); + neigh, pdev, 0); ep->mtu = pdev->mtu; ep->tx_chan = cxgb4_port_chan(pdev); ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1; @@ -1930,20 +1932,18 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) dev_put(pdev); } else { ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t, - ep->dst->neighbour, - ep->dst->neighbour->dev, 0); + neigh, neigh->dev, 0); ep->mtu = dst_mtu(ep->dst); - ep->tx_chan = cxgb4_port_chan(ep->dst->neighbour->dev); - ep->smac_idx = (cxgb4_port_viid(ep->dst->neighbour->dev) & - 0x7F) << 1; + ep->tx_chan = cxgb4_port_chan(neigh->dev); + ep->smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1; step = ep->com.dev->rdev.lldi.ntxq / ep->com.dev->rdev.lldi.nchan; - ep->txq_idx = cxgb4_port_idx(ep->dst->neighbour->dev) * step; - ep->ctrlq_idx = cxgb4_port_idx(ep->dst->neighbour->dev); + ep->txq_idx = cxgb4_port_idx(neigh->dev) * step; + ep->ctrlq_idx = cxgb4_port_idx(neigh->dev); step = ep->com.dev->rdev.lldi.nrxq / ep->com.dev->rdev.lldi.nchan; ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[ - cxgb4_port_idx(ep->dst->neighbour->dev) * step]; + cxgb4_port_idx(neigh->dev) * step]; } if (!ep->l2t) { printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index e74cdf9ef47..73bc18465c9 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1151,7 +1151,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi } if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) - neigh_event_send(rt->dst.neighbour, NULL); + neigh_event_send(dst_get_neighbour(&rt->dst), NULL); ip_rt_put(rt); return rc; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 86addca9ddf..43f89ba0a90 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -560,9 +560,11 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_path *path; struct ipoib_neigh *neigh; + struct neighbour *n; unsigned long flags; - neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev); + n = dst_get_neighbour(skb_dst(skb)); + neigh = ipoib_neigh_alloc(n, skb->dev); if (!neigh) { ++dev->stats.tx_dropped; dev_kfree_skb_any(skb); @@ -571,9 +573,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&priv->lock, flags); - path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4); + path = __path_find(dev, n->ha + 4); if (!path) { - path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4); + path = path_rec_create(dev, n->ha + 4); if (!path) goto err_path; @@ -607,7 +609,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) } } else { spin_unlock_irqrestore(&priv->lock, flags); - ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha)); + ipoib_send(dev, skb, path->ah, IPOIB_QPN(n->ha)); return; } } else { @@ -637,17 +639,20 @@ err_drop: static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(skb->dev); + struct dst_entry *dst = skb_dst(skb); + struct neighbour *n; /* Look up path record for unicasts */ - if (skb_dst(skb)->neighbour->ha[4] != 0xff) { + n = dst_get_neighbour(dst); + if (n->ha[4] != 0xff) { neigh_add_path(skb, dev); return; } /* Add in the P_Key for multicasts */ - skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff; - skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff; - ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb); + n->ha[8] = (priv->pkey >> 8) & 0xff; + n->ha[9] = priv->pkey & 0xff; + ipoib_mcast_send(dev, n->ha + 4, skb); } static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, @@ -712,18 +717,20 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_neigh *neigh; + struct neighbour *n; unsigned long flags; - if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) { - if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) { + n = dst_get_neighbour(skb_dst(skb)); + if (likely(skb_dst(skb) && n)) { + if (unlikely(!*to_ipoib_neigh(n))) { ipoib_path_lookup(skb, dev); return NETDEV_TX_OK; } - neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour); + neigh = *to_ipoib_neigh(n); if (unlikely((memcmp(&neigh->dgid.raw, - skb_dst(skb)->neighbour->ha + 4, + n->ha + 4, sizeof(union ib_gid))) || (neigh->dev != dev))) { spin_lock_irqsave(&priv->lock, flags); @@ -749,7 +756,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } } else if (neigh->ah) { - ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha)); + ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha)); return NETDEV_TX_OK; } @@ -812,6 +819,8 @@ static int ipoib_hard_header(struct sk_buff *skb, const void *daddr, const void *saddr, unsigned len) { struct ipoib_header *header; + struct dst_entry *dst; + struct neighbour *n; header = (struct ipoib_header *) skb_push(skb, sizeof *header); @@ -823,7 +832,11 @@ static int ipoib_hard_header(struct sk_buff *skb, * destination address onto the front of the skb so we can * figure out where to send the packet later. */ - if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) { + dst = skb_dst(skb); + n = NULL; + if (dst) + n = dst_get_neighbour(dst); + if ((!dst || !n) && daddr) { struct ipoib_pseudoheader *phdr = (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 3871ac66355..ecea4fe1ed0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -258,11 +258,15 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, netif_tx_lock_bh(dev); while (!skb_queue_empty(&mcast->pkt_queue)) { struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); + struct dst_entry *dst = skb_dst(skb); + struct neighbour *n = NULL; + netif_tx_unlock_bh(dev); skb->dev = dev; - - if (!skb_dst(skb) || !skb_dst(skb)->neighbour) { + if (dst) + n = dst_get_neighbour(dst); + if (!dst || !n) { /* put pseudoheader back on for next time */ skb_push(skb, sizeof (struct ipoib_pseudoheader)); } @@ -715,11 +719,13 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) out: if (mcast && mcast->ah) { - if (skb_dst(skb) && - skb_dst(skb)->neighbour && - !*to_ipoib_neigh(skb_dst(skb)->neighbour)) { - struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, - skb->dev); + struct dst_entry *dst = skb_dst(skb); + struct neighbour *n = NULL; + if (dst) + n = dst_get_neighbour(dst); + if (n && !*to_ipoib_neigh(n)) { + struct ipoib_neigh *neigh = ipoib_neigh_alloc(n, + skb->dev); if (neigh) { kref_get(&mcast->ah->ref); diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 9db9068d29d..fa1b450af82 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -971,7 +971,7 @@ static int nb_callback(struct notifier_block *self, unsigned long event, case (NETEVENT_REDIRECT):{ struct netevent_redirect *nr = ctx; cxgb_redirect(nr->old, nr->new); - cxgb_neigh_update(nr->new->neighbour); + cxgb_neigh_update(dst_get_neighbour(nr->new)); break; } default: @@ -1116,8 +1116,8 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) struct l2t_entry *e; struct t3c_tid_entry *te; - olddev = old->neighbour->dev; - newdev = new->neighbour->dev; + olddev = dst_get_neighbour(old)->dev; + newdev = dst_get_neighbour(new)->dev; if (!is_offloading(olddev)) return; if (!is_offloading(newdev)) { @@ -1134,7 +1134,7 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) } /* Add new L2T entry */ - e = t3_l2t_get(tdev, new->neighbour, newdev); + e = t3_l2t_get(tdev, dst_get_neighbour(new), newdev); if (!e) { printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n", __func__); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index fd69da3fa6b..e2c9ac5fcb3 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2742,9 +2742,14 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb) { int cast_type = RTN_UNSPEC; - - if (skb_dst(skb) && skb_dst(skb)->neighbour) { - cast_type = skb_dst(skb)->neighbour->type; + struct neighbour *n = NULL; + struct dst_entry *dst; + + dst = skb_dst(skb); + if (dst) + n = dst_get_neighbour(dst); + if (n) { + cast_type = n->type; if ((cast_type == RTN_BROADCAST) || (cast_type == RTN_MULTICAST) || (cast_type == RTN_ANYCAST)) @@ -2787,6 +2792,9 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb) static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, struct sk_buff *skb, int ipv, int cast_type) { + struct neighbour *n = NULL; + struct dst_entry *dst; + memset(hdr, 0, sizeof(struct qeth_hdr)); hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3; hdr->hdr.l3.ext_flags = 0; @@ -2804,13 +2812,16 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, } hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr); + dst = skb_dst(skb); + if (dst) + n = dst_get_neighbour(dst); if (ipv == 4) { /* IPv4 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); memset(hdr->hdr.l3.dest_addr, 0, 12); - if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) { + if (n) { *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - *((u32 *) skb_dst(skb)->neighbour->primary_key); + *((u32 *) n->primary_key); } else { /* fill in destination address used in ip header */ *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = @@ -2821,9 +2832,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); if (card->info.type == QETH_CARD_TYPE_IQD) hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; - if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) { + if (n) { memcpy(hdr->hdr.l3.dest_addr, - skb_dst(skb)->neighbour->primary_key, 16); + n->primary_key, 16); } else { /* fill in destination address used in ip header */ memcpy(hdr->hdr.l3.dest_addr, diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index fc2cdb62f53..abc7b122e05 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c @@ -985,7 +985,7 @@ static int init_act_open(struct cxgbi_sock *csk) csk->saddr.sin_addr.s_addr = chba->ipv4addr; csk->rss_qid = 0; - csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev); + csk->l2t = t3_l2t_get(t3dev, dst_get_neighbour(dst), ndev); if (!csk->l2t) { pr_err("NO l2t available.\n"); return -EINVAL; diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index f3a4cd7cf78..ae13c4993aa 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -1160,7 +1160,7 @@ static int init_act_open(struct cxgbi_sock *csk) cxgbi_sock_set_flag(csk, CTPF_HAS_ATID); cxgbi_sock_get(csk); - csk->l2t = cxgb4_l2t_get(lldi->l2t, csk->dst->neighbour, ndev, 0); + csk->l2t = cxgb4_l2t_get(lldi->l2t, dst_get_neighbour(csk->dst), ndev, 0); if (!csk->l2t) { pr_err("%s, cannot alloc l2t.\n", ndev->name); goto rel_resource; diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index a2a9c7c6c64..77ac217ad5c 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -492,7 +492,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) goto err_out; } dst = &rt->dst; - ndev = dst->neighbour->dev; + ndev = dst_get_neighbour(dst)->dev; if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { pr_info("multi-cast route %pI4, port %u, dev %s.\n", @@ -506,7 +506,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr); mtu = ndev->mtu; pr_info("rt dev %s, loopback -> %s, mtu %u.\n", - dst->neighbour->dev->name, ndev->name, mtu); + dst_get_neighbour(dst)->dev->name, ndev->name, mtu); } cdev = cxgbi_device_find_by_netdev(ndev, &port); diff --git a/include/net/dst.h b/include/net/dst.h index 0dd7ccbc0dd..8147206eefb 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -37,7 +37,7 @@ struct dst_entry { unsigned long _metrics; unsigned long expires; struct dst_entry *path; - struct neighbour *neighbour; + struct neighbour *_neighbour; #ifdef CONFIG_XFRM struct xfrm_state *xfrm; #else @@ -86,6 +86,16 @@ struct dst_entry { }; }; +static inline struct neighbour *dst_get_neighbour(struct dst_entry *dst) +{ + return dst->_neighbour; +} + +static inline void dst_set_neighbour(struct dst_entry *dst, struct neighbour *neigh) +{ + dst->_neighbour = neigh; +} + extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old); extern const u32 dst_default_metrics[RTAX_MAX]; @@ -371,8 +381,10 @@ static inline void dst_rcu_free(struct rcu_head *head) static inline void dst_confirm(struct dst_entry *dst) { - if (dst) - neigh_confirm(dst->neighbour); + if (dst) { + struct neighbour *n = dst_get_neighbour(dst); + neigh_confirm(n); + } } static inline void dst_link_failure(struct sk_buff *skb) diff --git a/net/atm/clip.c b/net/atm/clip.c index c6cd5318be3..4bc8c67ecb1 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -362,33 +362,37 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct clip_priv *clip_priv = PRIV(dev); + struct dst_entry *dst = skb_dst(skb); struct atmarp_entry *entry; + struct neighbour *n; struct atm_vcc *vcc; int old; unsigned long flags; pr_debug("(skb %p)\n", skb); - if (!skb_dst(skb)) { + if (!dst) { pr_err("skb_dst(skb) == NULL\n"); dev_kfree_skb(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; } - if (!skb_dst(skb)->neighbour) { + n = dst_get_neighbour(dst); + if (!n) { #if 0 - skb_dst(skb)->neighbour = clip_find_neighbour(skb_dst(skb), 1); - if (!skb_dst(skb)->neighbour) { + n = clip_find_neighbour(skb_dst(skb), 1); + if (!n) { dev_kfree_skb(skb); /* lost that one */ dev->stats.tx_dropped++; return 0; } + dst_set_neighbour(dst, n); #endif pr_err("NO NEIGHBOUR !\n"); dev_kfree_skb(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; } - entry = NEIGH2ENTRY(skb_dst(skb)->neighbour); + entry = NEIGH2ENTRY(n); if (!entry->vccs) { if (time_after(jiffies, entry->expires)) { /* should be resolved */ @@ -405,7 +409,7 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb, } pr_debug("neigh %p, vccs %p\n", entry, entry->vccs); ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc; - pr_debug("using neighbour %p, vcc %p\n", skb_dst(skb)->neighbour, vcc); + pr_debug("using neighbour %p, vcc %p\n", n, vcc); if (entry->vccs->encap) { void *here; diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 1fe43fdf997..b1a5f9777b7 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -350,7 +350,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) if (!skb->dev) goto free_skb; dst = skb_dst(skb); - neigh = dst->neighbour; + neigh = dst_get_neighbour(dst); if (neigh->hh.hh_len) { neigh_hh_bridge(&neigh->hh, skb); skb->dev = nf_bridge->physindev; diff --git a/net/core/dst.c b/net/core/dst.c index 4aacc14936a..14b33baf073 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -171,7 +171,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, dst_init_metrics(dst, dst_default_metrics, true); dst->expires = 0UL; dst->path = dst; - dst->neighbour = NULL; + dst->_neighbour = NULL; #ifdef CONFIG_XFRM dst->xfrm = NULL; #endif @@ -229,11 +229,11 @@ struct dst_entry *dst_destroy(struct dst_entry * dst) smp_rmb(); again: - neigh = dst->neighbour; + neigh = dst->_neighbour; child = dst->child; if (neigh) { - dst->neighbour = NULL; + dst->_neighbour = NULL; neigh_release(neigh); } @@ -363,8 +363,8 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev, dst->dev = dev_net(dst->dev)->loopback_dev; dev_hold(dst->dev); dev_put(dev); - if (dst->neighbour && dst->neighbour->dev == dev) { - dst->neighbour->dev = dst->dev; + if (dst->_neighbour && dst->_neighbour->dev == dev) { + dst->_neighbour->dev = dst->dev; dev_hold(dst->dev); dev_put(dev); } diff --git a/net/core/neighbour.c b/net/core/neighbour.c index cefb8e52615..8fab9b0bb20 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1153,11 +1153,12 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, while (neigh->nud_state & NUD_VALID && (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { - struct neighbour *n1 = neigh; + struct dst_entry *dst = skb_dst(skb); + struct neighbour *n2, *n1 = neigh; write_unlock_bh(&neigh->lock); /* On shaper/eql skb->dst->neighbour != neigh :( */ - if (skb_dst(skb) && skb_dst(skb)->neighbour) - n1 = skb_dst(skb)->neighbour; + if (dst && (n2 = dst_get_neighbour(dst)) != NULL) + n1 = n2; n1->output(n1, skb); write_lock_bh(&neigh->lock); } diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 5d61e8965b6..0dc3fe61085 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -202,7 +202,7 @@ static int dn_neigh_output_packet(struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); struct dn_route *rt = (struct dn_route *)dst; - struct neighbour *neigh = dst->neighbour; + struct neighbour *neigh = dst_get_neighbour(dst); struct net_device *dev = neigh->dev; char mac_addr[ETH_ALEN]; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 3b6400d17dc..9bd45fcb3b8 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -241,9 +241,11 @@ static int dn_dst_gc(struct dst_ops *ops) */ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) { + struct neighbour *n = dst_get_neighbour(dst); u32 min_mtu = 230; - struct dn_dev *dn = dst->neighbour ? - rcu_dereference_raw(dst->neighbour->dev->dn_ptr) : NULL; + struct dn_dev *dn; + + dn = n ? rcu_dereference_raw(n->dev->dn_ptr) : NULL; if (dn && dn->use_long == 0) min_mtu -= 6; @@ -708,7 +710,7 @@ out: static int dn_to_neigh_output(struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); - struct neighbour *n = dst->neighbour; + struct neighbour *n = dst_get_neighbour(dst); return n->output(n, skb); } @@ -723,7 +725,7 @@ static int dn_output(struct sk_buff *skb) int err = -EINVAL; - if ((neigh = dst->neighbour) == NULL) + if ((neigh = dst_get_neighbour(dst)) == NULL) goto error; skb->dev = dev; @@ -840,11 +842,11 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) } rt->rt_type = res->type; - if (dev != NULL && rt->dst.neighbour == NULL) { + if (dev != NULL && dst_get_neighbour(&rt->dst) == NULL) { n = __neigh_lookup_errno(&dn_neigh_table, &rt->rt_gateway, dev); if (IS_ERR(n)) return PTR_ERR(n); - rt->dst.neighbour = n; + dst_set_neighbour(&rt->dst, n); } if (dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu) @@ -1151,7 +1153,7 @@ make_route: rt->rt_dst_map = fld.daddr; rt->rt_src_map = fld.saddr; - rt->dst.neighbour = neigh; + dst_set_neighbour(&rt->dst, neigh); neigh = NULL; rt->dst.lastuse = jiffies; @@ -1423,7 +1425,7 @@ make_route: rt->fld.flowidn_iif = in_dev->ifindex; rt->fld.flowidn_mark = fld.flowidn_mark; - rt->dst.neighbour = neigh; + dst_set_neighbour(&rt->dst, neigh); rt->dst.lastuse = jiffies; rt->dst.output = dn_rt_bug; switch (res.type) { diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 8871067560d..d7bb94c4834 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -731,9 +731,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) else if (skb->protocol == htons(ETH_P_IPV6)) { + struct neighbour *neigh = dst_get_neighbour(skb_dst(skb)); const struct in6_addr *addr6; int addr_type; - struct neighbour *neigh = skb_dst(skb)->neighbour; if (neigh == NULL) goto tx_error; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index db296a98b23..be27e609a98 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -204,7 +204,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) skb = skb2; } - neigh = dst->neighbour; + neigh = dst_get_neighbour(dst); if (neigh) return neigh_output(neigh, skb); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index bcf9bb50820..1d4cd3b4fd6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -412,8 +412,10 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) "HHUptod\tSpecDst"); else { struct rtable *r = v; + struct neighbour *n; int len; + n = dst_get_neighbour(&r->dst); seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t" "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n", r->dst.dev ? r->dst.dev->name : "*", @@ -427,9 +429,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) dst_metric(&r->dst, RTAX_RTTVAR)), r->rt_key_tos, -1, - (r->dst.neighbour && - (r->dst.neighbour->nud_state & NUD_CONNECTED)) ? - 1 : 0, + (n && (n->nud_state & NUD_CONNECTED)) ? 1 : 0, r->rt_spec_dst, &len); seq_printf(seq, "%*s\n", 127 - len, ""); @@ -1026,7 +1026,7 @@ static int rt_bind_neighbour(struct rtable *rt) n = ipv4_neigh_lookup(tbl, dev, nexthop); if (IS_ERR(n)) return PTR_ERR(n); - rt->dst.neighbour = n; + dst_set_neighbour(&rt->dst, n); return 0; } @@ -1617,23 +1617,24 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) { struct rtable *rt = (struct rtable *) dst; __be32 orig_gw = rt->rt_gateway; + struct neighbour *n; dst_confirm(&rt->dst); - neigh_release(rt->dst.neighbour); - rt->dst.neighbour = NULL; + neigh_release(dst_get_neighbour(&rt->dst)); + dst_set_neighbour(&rt->dst, NULL); rt->rt_gateway = peer->redirect_learned.a4; - if (rt_bind_neighbour(rt) || - !(rt->dst.neighbour->nud_state & NUD_VALID)) { - if (rt->dst.neighbour) - neigh_event_send(rt->dst.neighbour, NULL); + rt_bind_neighbour(rt); + n = dst_get_neighbour(&rt->dst); + if (!n || !(n->nud_state & NUD_VALID)) { + if (n) + neigh_event_send(n, NULL); rt->rt_gateway = orig_gw; return -EAGAIN; } else { rt->rt_flags |= RTCF_REDIRECTED; - call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, - rt->dst.neighbour); + call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } return 0; } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 48cd03df895..a06c53c14d8 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, * layer address of our nexhop router */ - if (rt->dst.neighbour == NULL) + if (dst_get_neighbour(&rt->dst) == NULL) ifa->flags &= ~IFA_F_OPTIMISTIC; ifa->idev = idev; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 158df2365d5..54a4678955b 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg) RT6_TRACE("aging clone %p\n", rt); return -1; } else if ((rt->rt6i_flags & RTF_GATEWAY) && - (!(rt->dst.neighbour->flags & NTF_ROUTER))) { + (!(dst_get_neighbour(&rt->dst)->flags & NTF_ROUTER))) { RT6_TRACE("purging route %p via non-router but gateway\n", rt); return -1; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index eb50bb07ab2..8db0e4875ad 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -135,7 +135,7 @@ static int ip6_finish_output2(struct sk_buff *skb) skb->len); } - neigh = dst->neighbour; + neigh = dst_get_neighbour(dst); if (neigh) return neigh_output(neigh, skb); @@ -385,6 +385,7 @@ int ip6_forward(struct sk_buff *skb) struct ipv6hdr *hdr = ipv6_hdr(skb); struct inet6_skb_parm *opt = IP6CB(skb); struct net *net = dev_net(dst->dev); + struct neighbour *n; u32 mtu; if (net->ipv6.devconf_all->forwarding == 0) @@ -459,11 +460,10 @@ int ip6_forward(struct sk_buff *skb) send redirects to source routed frames. We don't send redirects to frames decapsulated from IPsec. */ - if (skb->dev == dst->dev && dst->neighbour && opt->srcrt == 0 && - !skb_sec_path(skb)) { + n = dst_get_neighbour(dst); + if (skb->dev == dst->dev && n && opt->srcrt == 0 && !skb_sec_path(skb)) { struct in6_addr *target = NULL; struct rt6_info *rt; - struct neighbour *n = dst->neighbour; /* * incoming and outgoing devices are the same @@ -920,8 +920,11 @@ out: static int ip6_dst_lookup_tail(struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6) { - int err; struct net *net = sock_net(sk); +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + struct neighbour *n; +#endif + int err; if (*dst == NULL) *dst = ip6_route_output(net, sk, fl6); @@ -947,7 +950,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, * dst entry and replace it instead with the * dst entry of the nexthop router */ - if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { + n = dst_get_neighbour(*dst); + if (n && !(n->nud_state & NUD_VALID)) { struct inet6_ifaddr *ifp; struct flowi6 fl_gw6; int redirect; diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index a997d414f52..9da6e02eaae 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1238,7 +1238,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev); if (rt) - neigh = rt->dst.neighbour; + neigh = dst_get_neighbour(&rt->dst); if (rt && lifetime == 0) { neigh_clone(neigh); @@ -1259,7 +1259,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) return; } - neigh = rt->dst.neighbour; + neigh = dst_get_neighbour(&rt->dst); if (neigh == NULL) { ND_PRINTK0(KERN_ERR "ICMPv6 RA: %s() got default router without neighbour.\n", diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c1515a3c130..2998cb5be90 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -356,7 +356,7 @@ out: #ifdef CONFIG_IPV6_ROUTER_PREF static void rt6_probe(struct rt6_info *rt) { - struct neighbour *neigh = rt ? rt->dst.neighbour : NULL; + struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; /* * Okay, this does not seem to be appropriate * for now, however, we need to check if it @@ -404,7 +404,7 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif) static inline int rt6_check_neigh(struct rt6_info *rt) { - struct neighbour *neigh = rt->dst.neighbour; + struct neighbour *neigh = dst_get_neighbour(&rt->dst); int m; if (rt->rt6i_flags & RTF_NONEXTHOP || !(rt->rt6i_flags & RTF_GATEWAY)) @@ -745,7 +745,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add dst_free(&rt->dst); return NULL; } - rt->dst.neighbour = neigh; + dst_set_neighbour(&rt->dst, neigh); } @@ -760,7 +760,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_a rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; - rt->dst.neighbour = neigh_clone(ort->dst.neighbour); + dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst))); } return rt; } @@ -794,7 +794,7 @@ restart: dst_hold(&rt->dst); read_unlock_bh(&table->tb6_lock); - if (!rt->dst.neighbour && !(rt->rt6i_flags & RTF_NONEXTHOP)) + if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); else if (!(rt->dst.flags & DST_HOST)) nrt = rt6_alloc_clone(rt, &fl6->daddr); @@ -1058,7 +1058,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, } rt->rt6i_idev = idev; - rt->dst.neighbour = neigh; + dst_set_neighbour(&rt->dst, neigh); atomic_set(&rt->dst.__refcnt, 1); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); rt->dst.output = ip6_output; @@ -1338,12 +1338,12 @@ int ip6_route_add(struct fib6_config *cfg) rt->rt6i_prefsrc.plen = 0; if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) { - rt->dst.neighbour = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); - if (IS_ERR(rt->dst.neighbour)) { - err = PTR_ERR(rt->dst.neighbour); - rt->dst.neighbour = NULL; + struct neighbour *n = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); + if (IS_ERR(n)) { + err = PTR_ERR(n); goto out; } + dst_set_neighbour(&rt->dst, n); } rt->rt6i_flags = cfg->fc_flags; @@ -1574,7 +1574,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, dst_confirm(&rt->dst); /* Duplicate redirect: silently ignore. */ - if (neigh == rt->dst.neighbour) + if (neigh == dst_get_neighbour(&rt->dst)) goto out; nrt = ip6_rt_copy(rt); @@ -1590,7 +1590,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, nrt->dst.flags |= DST_HOST; ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); - nrt->dst.neighbour = neigh_clone(neigh); + dst_set_neighbour(&nrt->dst, neigh_clone(neigh)); if (ip6_ins_rt(nrt)) goto out; @@ -1670,7 +1670,7 @@ again: 1. It is connected route. Action: COW 2. It is gatewayed route or NONEXTHOP route. Action: clone it. */ - if (!rt->dst.neighbour && !(rt->rt6i_flags & RTF_NONEXTHOP)) + if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) nrt = rt6_alloc_cow(rt, daddr, saddr); else nrt = rt6_alloc_clone(rt, daddr); @@ -2035,7 +2035,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, return ERR_CAST(neigh); } - rt->dst.neighbour = neigh; + dst_set_neighbour(&rt->dst, neigh); ipv6_addr_copy(&rt->rt6i_dst.addr, addr); rt->rt6i_dst.plen = 128; @@ -2400,8 +2400,8 @@ static int rt6_fill_node(struct net *net, if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) goto nla_put_failure; - if (rt->dst.neighbour) - NLA_PUT(skb, RTA_GATEWAY, 16, &rt->dst.neighbour->primary_key); + if (dst_get_neighbour(&rt->dst)) + NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key); if (rt->dst.dev) NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); @@ -2585,6 +2585,7 @@ struct rt6_proc_arg static int rt6_info_route(struct rt6_info *rt, void *p_arg) { struct seq_file *m = p_arg; + struct neighbour *n; seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen); @@ -2593,9 +2594,9 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) #else seq_puts(m, "00000000000000000000000000000000 00 "); #endif - - if (rt->dst.neighbour) { - seq_printf(m, "%pi6", rt->dst.neighbour->primary_key); + n = dst_get_neighbour(&rt->dst); + if (n) { + seq_printf(m, "%pi6", n->primary_key); } else { seq_puts(m, "00000000000000000000000000000000"); } diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1cca5761aea..07bf1085458 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -677,7 +677,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct neighbour *neigh = NULL; if (skb_dst(skb)) - neigh = skb_dst(skb)->neighbour; + neigh = dst_get_neighbour(skb_dst(skb)); if (neigh == NULL) { if (net_ratelimit()) @@ -702,7 +702,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct neighbour *neigh = NULL; if (skb_dst(skb)) - neigh = skb_dst(skb)->neighbour; + neigh = dst_get_neighbour(skb_dst(skb)); if (neigh == NULL) { if (net_ratelimit()) diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 45cd30098e3..a3b7120fcc7 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -229,7 +229,7 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * { struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, 0); struct teql_sched_data *q = qdisc_priv(dev_queue->qdisc); - struct neighbour *mn = skb_dst(skb)->neighbour; + struct neighbour *mn = dst_get_neighbour(skb_dst(skb)); struct neighbour *n = q->ncache; if (mn->tbl == NULL) @@ -270,7 +270,7 @@ static inline int teql_resolve(struct sk_buff *skb, if (dev->header_ops == NULL || skb_dst(skb) == NULL || - skb_dst(skb)->neighbour == NULL) + dst_get_neighbour(skb_dst(skb)) == NULL) return 0; return __teql_resolve(skb, skb_res, dev); } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 5ce74a38552..7803eb6af41 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1497,7 +1497,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, goto free_dst; /* Copy neighbour for reachability confirmation */ - dst0->neighbour = neigh_clone(dst->neighbour); + dst_set_neighbour(dst0, neigh_clone(dst_get_neighbour(dst))); xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len); xfrm_init_pmtu(dst_prev); -- cgit v1.2.3-70-g09d2 From eb0dc4bb2e22c04964d6e9545e86f629f117108b Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sun, 17 Jul 2011 20:54:08 +0000 Subject: stmmac: add memory barriers at appropriate places This patch, provided by ST SPEAr developers, has fixed a problem raised on ARM CA9 where happened that the dma_transmission was enabled before the dma descriptors were properly filled. To guarantee this data memory barriers have been explicity used in the driver. Signed-off-by: Shiraz Hashim Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index d4adc806f6f..c8c9e5bc660 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1045,6 +1045,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) len, DMA_TO_DEVICE); priv->tx_skbuff[entry] = NULL; priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); + wmb(); priv->hw->desc->set_tx_owner(desc); } @@ -1056,6 +1057,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) if (likely(priv->tm->enable)) priv->hw->desc->clear_tx_ic(desc); #endif + + wmb(); + /* To avoid raise condition */ priv->hw->desc->set_tx_owner(first); @@ -1118,6 +1122,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) } RX_DBG(KERN_INFO "\trefill entry #%d\n", entry); } + wmb(); priv->hw->desc->set_rx_owner(p + entry); } } -- cgit v1.2.3-70-g09d2 From 61b8013a114cb041db2c56f747953cac69637f26 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Sun, 17 Jul 2011 20:54:09 +0000 Subject: stmmac: Allow SOCs to use Store forward mode eventhough tx_coe is 0. (V2) This patch adds new field 'force_sf_dma_mode' to plat_stmmacenet_data struct to allow users to specify if they want to use force store forward eventhough tx_coe is not available in hw. without this flag stmmac driver will use cut-thru mode not use store-forward mode. Signed-off-by: Srinivas Kandagatla Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 8 +++++--- include/linux/stmmac.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index c8c9e5bc660..d37ebc80623 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -557,9 +557,11 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) */ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) { - if (likely((priv->plat->tx_coe) && (!priv->no_csum_insertion))) { - /* In case of GMAC, SF mode has to be enabled - * to perform the TX COE. This depends on: + if (likely(priv->plat->force_sf_dma_mode || + ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) { + /* + * In case of GMAC, SF mode can be enabled + * to perform the TX COE in HW. This depends on: * 1) TX COE if actually supported * 2) There is no bugged Jumbo frame support * that needs to not insert csum in the TDES. diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 9529e49b038..05d775690b7 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -40,6 +40,7 @@ struct plat_stmmacenet_data { int tx_coe; int bugged_jumbo; int pmt; + int force_sf_dma_mode; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); int (*init)(struct platform_device *pdev); -- cgit v1.2.3-70-g09d2 From 81fc70d86527a1450560709500ca5f52e661da1f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sun, 17 Jul 2011 22:26:37 +0000 Subject: net: can: remove custom hex_to_bin() Signed-off-by: Andy Shevchenko Cc: Wolfgang Grandegger Acked-by: Oliver Hartkopp Signed-off-by: David S. Miller --- drivers/net/can/slcan.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index aa8ad73477b..65e54fd0a8d 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -56,6 +56,7 @@ #include #include #include +#include #include static __initdata const char banner[] = @@ -142,21 +143,6 @@ static struct net_device **slcan_devs; * STANDARD SLCAN DECAPSULATION * ************************************************************************/ -static int asc2nibble(char c) -{ - - if ((c >= '0') && (c <= '9')) - return c - '0'; - - if ((c >= 'A') && (c <= 'F')) - return c - 'A' + 10; - - if ((c >= 'a') && (c <= 'f')) - return c - 'a' + 10; - - return 16; /* error */ -} - /* Send one completely decapsulated can_frame to the network layer */ static void slc_bump(struct slcan *sl) { @@ -195,18 +181,16 @@ static void slc_bump(struct slcan *sl) *(u64 *) (&cf.data) = 0; /* clear payload */ for (i = 0, dlc_pos++; i < cf.can_dlc; i++) { - - tmp = asc2nibble(sl->rbuff[dlc_pos++]); - if (tmp > 0x0F) + tmp = hex_to_bin(sl->rbuff[dlc_pos++]); + if (tmp < 0) return; cf.data[i] = (tmp << 4); - tmp = asc2nibble(sl->rbuff[dlc_pos++]); - if (tmp > 0x0F) + tmp = hex_to_bin(sl->rbuff[dlc_pos++]); + if (tmp < 0) return; cf.data[i] |= tmp; } - skb = dev_alloc_skb(sizeof(struct can_frame)); if (!skb) return; -- cgit v1.2.3-70-g09d2 From 1687b56679880a47164ae149530abee543f9d6b1 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 19 Jul 2011 17:21:29 +0200 Subject: r8169: fix sticky accepts packet bits in RxConfig. e542a2269f232d61270ceddd42b73a4348dee2bb (r8169: adjust the RxConfig settings) broke the return from promiscuous mode to physical address match mode. Signed-off-by: Francois Romieu Cc: Signed-off-by: Hayes Wang --- drivers/net/r8169.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 3ddd33936aa..40bcb82d911 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -435,6 +435,7 @@ enum rtl_register_content { AcceptMulticast = 0x04, AcceptMyPhys = 0x02, AcceptAllPhys = 0x01, +#define RX_CONFIG_ACCEPT_MASK 0x3f /* TxConfigBits */ TxInterFrameGapShift = 24, @@ -3943,11 +3944,8 @@ err_pm_runtime_put: static void rtl_rx_close(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - u32 rxcfg = RTL_R32(RxConfig); - rxcfg &= ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | - AcceptMyPhys | AcceptAllPhys); - RTL_W32(RxConfig, rxcfg); + RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK); } static void rtl8169_hw_reset(struct rtl8169_private *tp) @@ -5586,7 +5584,7 @@ static void rtl_set_rx_mode(struct net_device *dev) spin_lock_irqsave(&tp->lock, flags); - tmp = RTL_R32(RxConfig) | rx_mode; + tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; if (tp->mac_version > RTL_GIGA_MAC_VER_06) { u32 data = mc_filter[0]; -- cgit v1.2.3-70-g09d2 From 9924cafc403ca74614c0a8b1ad198406ae02c68b Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 19 Jul 2011 01:37:42 +0000 Subject: bnx2x: use correct dma_sync function Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_ethtool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index b05ce9306de..150147aa73b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -676,7 +676,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) /* non TPA */ len = le16_to_cpu(cqe_fp->pkt_len); pad = cqe_fp->placement_offset; - dma_sync_single_for_device(&bp->pdev->dev, + dma_sync_single_for_cpu(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), pad + RX_COPY_THRESH, DMA_FROM_DEVICE); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ac0223135b7..eda0f7b82c5 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1752,7 +1752,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) goto test_loopback_rx_exit; rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)]; - dma_sync_single_for_device(&bp->pdev->dev, + dma_sync_single_for_cpu(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), fp_rx->rx_buf_size, DMA_FROM_DEVICE); skb = rx_buf->skb; -- cgit v1.2.3-70-g09d2 From c636322b24eb69b7c1ccdc070164de51cee3f37c Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 19 Jul 2011 01:38:53 +0000 Subject: bnx2x: add missing command in error handling flow Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 150147aa73b..5854a6c3422 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1828,6 +1828,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_func_start(bp); if (rc) { BNX2X_ERR("Function start failed!\n"); + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); LOAD_ERROR_EXIT(bp, load_error3); } -- cgit v1.2.3-70-g09d2 From 9505ee376739c26cf1d7d4e551d2f63b9d7e5729 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 19 Jul 2011 01:39:41 +0000 Subject: bnx2x: stop tx before CNIC_STOP It may take some time to cnic to respond, this prevents tx_timeout when it happens. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 5854a6c3422..8b079dcd5b9 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1989,6 +1989,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) return -EINVAL; } + /* Stop Tx */ + bnx2x_tx_disable(bp); + #ifdef BCM_CNIC bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); #endif @@ -1997,9 +2000,6 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->rx_mode = BNX2X_RX_MODE_NONE; - /* Stop Tx */ - bnx2x_tx_disable(bp); - del_timer_sync(&bp->timer); /* Set ALWAYS_ALIVE bit in shmem */ -- cgit v1.2.3-70-g09d2 From f13ac41f5165c0ac0441f9d42f7d6f6f9ee7c075 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 19 Jul 2011 01:40:27 +0000 Subject: bnx2x: remove unnecessary dma_sync Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 595d4cdada3..83d7d1bb7b1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -936,16 +936,11 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, u16 cons, u16 prod) { - struct bnx2x *bp = fp->bp; struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons]; struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; - dma_sync_single_for_device(&bp->pdev->dev, - dma_unmap_addr(cons_rx_buf, mapping), - RX_COPY_THRESH, DMA_FROM_DEVICE); - dma_unmap_addr_set(prod_rx_buf, mapping, dma_unmap_addr(cons_rx_buf, mapping)); prod_rx_buf->skb = cons_rx_buf->skb; -- cgit v1.2.3-70-g09d2 From 6debea870a66be4aac2e28be0e3952dad6c7fcdb Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 19 Jul 2011 01:42:04 +0000 Subject: bnx2x: DCB rework create DCB related states in function state-machine allow handling of DCB errors from FW allow disablement of DCB in FW, when peer disappears or error clean up unused functions/variables as pointed by David Binderman Reported-by: David Binderman Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 7 +- drivers/net/bnx2x/bnx2x_dcb.c | 171 +++++++++++++++++------------------------ drivers/net/bnx2x/bnx2x_hsi.h | 1 + drivers/net/bnx2x/bnx2x_main.c | 98 +++++++++++++++++++++-- drivers/net/bnx2x/bnx2x_sp.c | 90 ++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_sp.h | 13 ++++ 6 files changed, 268 insertions(+), 112 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 53fa8ea983e..333f5d6c6b8 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -966,6 +966,8 @@ struct bnx2x_slowpath { union { struct function_start_data func_start; + /* pfc configuration for DCBX ramrod */ + struct flow_control_configuration pfc_config; } func_rdata; /* used by dmae command executer */ @@ -980,8 +982,6 @@ struct bnx2x_slowpath { u32 wb_comp; u32 wb_data[4]; - /* pfc configuration for DCBX ramrod */ - struct flow_control_configuration pfc_config; }; #define bnx2x_sp(bp, var) (&bp->slowpath->var) @@ -1417,9 +1417,6 @@ struct bnx2x { char fw_ver[32]; const struct firmware *firmware; - /* LLDP params */ - struct bnx2x_config_lldp_params lldp_config_params; - /* DCB support on/off */ u16 dcb_state; #define BNX2X_DCB_STATE_OFF 0 diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 3bfba44961d..d028794a229 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -29,10 +29,10 @@ #endif /* forward declarations of dcbx related functions */ -static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); +static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); static void bnx2x_pfc_set_pfc(struct bnx2x *bp); static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp); -static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); +static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, u32 *set_configuration_ets_pg, u32 *pri_pg_tbl); @@ -47,8 +47,25 @@ static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, struct cos_help_data *cos_data, u32 *pg_pri_orginal_spread, struct dcbx_ets_feature *ets); -static void bnx2x_dcbx_fw_struct(struct bnx2x *bp); +static void bnx2x_dcbx_fw_struct(struct bnx2x *bp, + struct bnx2x_func_tx_start_params*); +/* helpers: read/write len bytes from addr into buff by REG_RD/REG_WR */ +static void bnx2x_read_data(struct bnx2x *bp, u32 *buff, + u32 addr, u32 len) +{ + int i; + for (i = 0; i < len; i += 4, buff++) + *buff = REG_RD(bp, addr + i); +} + +static void bnx2x_write_data(struct bnx2x *bp, u32 *buff, + u32 addr, u32 len) +{ + int i; + for (i = 0; i < len; i += 4, buff++) + REG_WR(bp, addr + i, *buff); +} static void bnx2x_pfc_set(struct bnx2x *bp) { @@ -205,7 +222,11 @@ static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp, if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_ERROR\n"); - if (app->enabled && !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) { + if (GET_FLAGS(error, DCBX_LOCAL_APP_MISMATCH)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_MISMATCH\n"); + + if (app->enabled && + !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR | DCBX_LOCAL_APP_MISMATCH)) { bp->dcbx_port_params.app.enabled = true; @@ -300,7 +321,7 @@ static void bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp, DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_ERROR\n"); if (bp->dcbx_port_params.app.enabled && - !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR) && + !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR | DCBX_LOCAL_PFC_MISMATCH) && pfc->enabled) { bp->dcbx_port_params.pfc.enabled = true; bp->dcbx_port_params.pfc.priority_non_pauseable_mask = @@ -329,8 +350,8 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, u32 offset, int read_mib_type) { - int max_try_read = 0, i; - u32 *buff, mib_size, prefix_seq_num, suffix_seq_num; + int max_try_read = 0; + u32 mib_size, prefix_seq_num, suffix_seq_num; struct lldp_remote_mib *remote_mib ; struct lldp_local_mib *local_mib; @@ -349,9 +370,7 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, offset += BP_PORT(bp) * mib_size; do { - buff = base_mib_addr; - for (i = 0; i < mib_size; i += 4, buff++) - *buff = REG_RD(bp, offset + i); + bnx2x_read_data(bp, base_mib_addr, offset, mib_size); max_try_read++; @@ -382,12 +401,8 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp, static void bnx2x_pfc_set_pfc(struct bnx2x *bp) { - if (BP_PORT(bp)) { - BNX2X_ERR("4 port mode is not supported"); - return; - } - - if (bp->dcbx_port_params.pfc.enabled) + if (bp->dcbx_port_params.pfc.enabled && + !(bp->dcbx_error & DCBX_REMOTE_MIB_ERROR)) /* * 1. Fills up common PFC structures if required * 2. Configure NIG, MAC and BRB via the elink @@ -397,25 +412,30 @@ static void bnx2x_pfc_set_pfc(struct bnx2x *bp) bnx2x_pfc_clear(bp); } -static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) +static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) { - DP(NETIF_MSG_LINK, "sending STOP TRAFFIC\n"); - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, - 0 /* connectionless */, - 0 /* dataHi is zero */, - 0 /* dataLo is zero */, - NONE_CONNECTION_TYPE); + struct bnx2x_func_state_params func_params = {0}; + + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_TX_STOP; + + DP(NETIF_MSG_LINK, "STOP TRAFFIC\n"); + return bnx2x_func_state_change(bp, &func_params); } -static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) +static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) { - bnx2x_dcbx_fw_struct(bp); - DP(NETIF_MSG_LINK, "sending START TRAFFIC\n"); - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, - 0, /* connectionless */ - U64_HI(bnx2x_sp_mapping(bp, pfc_config)), - U64_LO(bnx2x_sp_mapping(bp, pfc_config)), - NONE_CONNECTION_TYPE); + struct bnx2x_func_state_params func_params = {0}; + struct bnx2x_func_tx_start_params *tx_params = + &func_params.params.tx_start; + + func_params.f_obj = &bp->func_obj; + func_params.cmd = BNX2X_F_CMD_TX_START; + + bnx2x_dcbx_fw_struct(bp, tx_params); + + DP(NETIF_MSG_LINK, "START TRAFFIC\n"); + return bnx2x_func_state_change(bp, &func_params); } static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp) @@ -522,7 +542,8 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) { bnx2x_ets_disabled(&bp->link_params, &bp->link_vars); - if (!bp->dcbx_port_params.ets.enabled) + if (!bp->dcbx_port_params.ets.enabled || + (bp->dcbx_error & DCBX_REMOTE_MIB_ERROR)) return; if (CHIP_IS_E3B0(bp)) @@ -739,61 +760,14 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) } } - -#define LLDP_STATS_OFFSET(bp) (BP_PORT(bp)*\ - sizeof(struct lldp_dcbx_stat)) - -/* calculate struct offset in array according to chip information */ -#define LLDP_PARAMS_OFFSET(bp) (BP_PORT(bp)*sizeof(struct lldp_params)) - #define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \ BP_PORT(bp)*sizeof(struct lldp_admin_mib)) -static void bnx2x_dcbx_lldp_updated_params(struct bnx2x *bp, - u32 dcbx_lldp_params_offset) -{ - struct lldp_params lldp_params = {0}; - u32 i = 0, *buff = NULL; - u32 offset = dcbx_lldp_params_offset + LLDP_PARAMS_OFFSET(bp); - - DP(NETIF_MSG_LINK, "lldp_offset 0x%x\n", offset); - - if ((bp->lldp_config_params.overwrite_settings == - BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE)) { - /* Read the data first */ - buff = (u32 *)&lldp_params; - for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) - *buff = REG_RD(bp, (offset + i)); - - lldp_params.msg_tx_hold = - (u8)bp->lldp_config_params.msg_tx_hold; - lldp_params.msg_fast_tx_interval = - (u8)bp->lldp_config_params.msg_fast_tx; - lldp_params.tx_crd_max = - (u8)bp->lldp_config_params.tx_credit_max; - lldp_params.msg_tx_interval = - (u8)bp->lldp_config_params.msg_tx_interval; - lldp_params.tx_fast = - (u8)bp->lldp_config_params.tx_fast; - - /* Write the data.*/ - buff = (u32 *)&lldp_params; - for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) - REG_WR(bp, (offset + i) , *buff); - - - } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == - bp->lldp_config_params.overwrite_settings) - bp->lldp_config_params.overwrite_settings = - BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; -} - static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, u32 dcbx_lldp_params_offset) { struct lldp_admin_mib admin_mib; u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0; - u32 *buff; u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp); /*shortcuts*/ @@ -801,18 +775,18 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params; memset(&admin_mib, 0, sizeof(struct lldp_admin_mib)); - buff = (u32 *)&admin_mib; + /* Read the data first */ - for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) - *buff = REG_RD(bp, (offset + i)); + bnx2x_read_data(bp, (u32 *)&admin_mib, offset, + sizeof(struct lldp_admin_mib)); if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON) SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); else RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); - if ((BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == - dp->overwrite_settings)) { + if (dp->overwrite_settings == BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE) { + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK); admin_mib.ver_cfg_flags |= (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) & @@ -908,19 +882,17 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, af->app.default_pri = (u8)dp->admin_default_priority; - } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == - dp->overwrite_settings) - dp->overwrite_settings = BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; + } /* Write the data. */ - buff = (u32 *)&admin_mib; - for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) - REG_WR(bp, (offset + i), *buff); + bnx2x_write_data(bp, (u32 *)&admin_mib, offset, + sizeof(struct lldp_admin_mib)); + } void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) { - if (!CHIP_IS_E1x(bp) && !CHIP_MODE_IS_4_PORT(bp)) { + if (!CHIP_IS_E1x(bp)) { bp->dcb_state = dcb_on; bp->dcbx_enabled = dcbx_enabled; } else { @@ -1029,9 +1001,6 @@ void bnx2x_dcbx_init(struct bnx2x *bp) bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { - bnx2x_dcbx_lldp_updated_params(bp, - dcbx_lldp_params_offset); - bnx2x_dcbx_admin_mib_updated_params(bp, dcbx_lldp_params_offset); @@ -1043,7 +1012,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp) } static void bnx2x_dcbx_print_cos_params(struct bnx2x *bp, - struct flow_control_configuration *pfc_fw_cfg) + struct bnx2x_func_tx_start_params *pfc_fw_cfg) { u8 pri = 0; u8 cos = 0; @@ -1821,17 +1790,19 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, } } -static void bnx2x_dcbx_fw_struct(struct bnx2x *bp) +static void bnx2x_dcbx_fw_struct(struct bnx2x *bp, + struct bnx2x_func_tx_start_params *pfc_fw_cfg) { - struct flow_control_configuration *pfc_fw_cfg = NULL; u16 pri_bit = 0; u8 cos = 0, pri = 0; struct priority_cos *tt2cos; u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; - pfc_fw_cfg = (struct flow_control_configuration *) - bnx2x_sp(bp, pfc_config); - memset(pfc_fw_cfg, 0, sizeof(struct flow_control_configuration)); + memset(pfc_fw_cfg, 0, sizeof(*pfc_fw_cfg)); + + /* to disable DCB - the structure must be zeroed */ + if (bp->dcbx_error & DCBX_REMOTE_MIB_ERROR) + return; /*shortcut*/ tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index ce3b5662ca5..06727f32e50 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -1834,6 +1834,7 @@ struct lldp_local_mib { #define DCBX_LOCAL_APP_ERROR 0x00000004 #define DCBX_LOCAL_PFC_MISMATCH 0x00000010 #define DCBX_LOCAL_APP_MISMATCH 0x00000020 + #define DCBX_REMOTE_MIB_ERROR 0x00000040 struct dcbx_features features; u32 suffix_seq_num; }; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 8a374a77cdc..a86517cffd4 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4403,11 +4403,17 @@ static void bnx2x_eq_int(struct bnx2x *bp) case EVENT_RING_OPCODE_STOP_TRAFFIC: DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n"); + if (f_obj->complete_cmd(bp, f_obj, + BNX2X_F_CMD_TX_STOP)) + break; bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); goto next_spqe; case EVENT_RING_OPCODE_START_TRAFFIC: DP(NETIF_MSG_IFUP, "got START TRAFFIC\n"); + if (f_obj->complete_cmd(bp, f_obj, + BNX2X_F_CMD_TX_START)) + break; bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); goto next_spqe; case EVENT_RING_OPCODE_FUNCTION_START: @@ -7536,6 +7542,71 @@ void bnx2x_send_unload_done(struct bnx2x *bp) bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); } +static inline int bnx2x_func_wait_started(struct bnx2x *bp) +{ + int tout = 50; + int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; + + if (!bp->port.pmf) + return 0; + + /* + * (assumption: No Attention from MCP at this stage) + * PMF probably in the middle of TXdisable/enable transaction + * 1. Sync IRS for default SB + * 2. Sync SP queue - this guarantes us that attention handling started + * 3. Wait, that TXdisable/enable transaction completes + * + * 1+2 guranty that if DCBx attention was scheduled it already changed + * pending bit of transaction from STARTED-->TX_STOPPED, if we alredy + * received complettion for the transaction the state is TX_STOPPED. + * State will return to STARTED after completion of TX_STOPPED-->STARTED + * transaction. + */ + + /* make sure default SB ISR is done */ + if (msix) + synchronize_irq(bp->msix_table[0].vector); + else + synchronize_irq(bp->pdev->irq); + + flush_workqueue(bnx2x_wq); + + while (bnx2x_func_get_state(bp, &bp->func_obj) != + BNX2X_F_STATE_STARTED && tout--) + msleep(20); + + if (bnx2x_func_get_state(bp, &bp->func_obj) != + BNX2X_F_STATE_STARTED) { +#ifdef BNX2X_STOP_ON_ERROR + return -EBUSY; +#else + /* + * Failed to complete the transaction in a "good way" + * Force both transactions with CLR bit + */ + struct bnx2x_func_state_params func_params = {0}; + + DP(BNX2X_MSG_SP, "Hmmm... unexpected function state! " + "Forcing STARTED-->TX_ST0PPED-->STARTED\n"); + + func_params.f_obj = &bp->func_obj; + __set_bit(RAMROD_DRV_CLR_ONLY, + &func_params.ramrod_flags); + + /* STARTED-->TX_ST0PPED */ + func_params.cmd = BNX2X_F_CMD_TX_STOP; + bnx2x_func_state_change(bp, &func_params); + + /* TX_ST0PPED-->STARTED */ + func_params.cmd = BNX2X_F_CMD_TX_START; + return bnx2x_func_state_change(bp, &func_params); +#endif + } + + return 0; +} + void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) { int port = BP_PORT(bp); @@ -7595,6 +7666,26 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) netif_addr_unlock_bh(bp->dev); + + /* + * Send the UNLOAD_REQUEST to the MCP. This will return if + * this function should perform FUNC, PORT or COMMON HW + * reset. + */ + reset_code = bnx2x_send_unload_req(bp, unload_mode); + + /* + * (assumption: No Attention from MCP at this stage) + * PMF probably in the middle of TXdisable/enable transaction + */ + rc = bnx2x_func_wait_started(bp); + if (rc) { + BNX2X_ERR("bnx2x_func_wait_started failed\n"); +#ifdef BNX2X_STOP_ON_ERROR + return; +#endif + } + /* Close multi and leading connections * Completions for ramrods are collected in a synchronous way */ @@ -7622,13 +7713,6 @@ unload_error: #endif } - /* - * Send the UNLOAD_REQUEST to the MCP. This will return if - * this function should perform FUNC, PORT or COMMON HW - * reset. - */ - reset_code = bnx2x_send_unload_req(bp, unload_mode); - /* Disable HW interrupts, NAPI */ bnx2x_netif_stop(bp, 1); diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index 358c3399753..6306ff59de0 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -4874,6 +4874,22 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp, ¶ms->params.update; u8 next_tx_only = o->num_tx_only; + /* + * Forget all pending for completion commands if a driver only state + * transition has been requested. + */ + if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { + o->pending = 0; + o->next_state = BNX2X_Q_STATE_MAX; + } + + /* + * Don't allow a next state transition if we are in the middle of + * the previous one. + */ + if (o->pending) + return -EBUSY; + switch (state) { case BNX2X_Q_STATE_RESET: if (cmd == BNX2X_Q_CMD_INIT) @@ -5053,6 +5069,21 @@ void bnx2x_queue_set_cos_cid(struct bnx2x *bp, } /********************** Function state object *********************************/ +enum bnx2x_func_state bnx2x_func_get_state(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o) +{ + /* in the middle of transaction - return INVALID state */ + if (o->pending) + return BNX2X_F_STATE_MAX; + + /* + * unsure the order of reading of o->pending and o->state + * o->pending should be read first + */ + rmb(); + + return o->state; +} static int bnx2x_func_wait_comp(struct bnx2x *bp, struct bnx2x_func_sp_obj *o, @@ -5143,6 +5174,22 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, enum bnx2x_func_state state = o->state, next_state = BNX2X_F_STATE_MAX; enum bnx2x_func_cmd cmd = params->cmd; + /* + * Forget all pending for completion commands if a driver only state + * transition has been requested. + */ + if (test_bit(RAMROD_DRV_CLR_ONLY, ¶ms->ramrod_flags)) { + o->pending = 0; + o->next_state = BNX2X_F_STATE_MAX; + } + + /* + * Don't allow a next state transition if we are in the middle of + * the previous one. + */ + if (o->pending) + return -EBUSY; + switch (state) { case BNX2X_F_STATE_RESET: if (cmd == BNX2X_F_CMD_HW_INIT) @@ -5160,6 +5207,13 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, case BNX2X_F_STATE_STARTED: if (cmd == BNX2X_F_CMD_STOP) next_state = BNX2X_F_STATE_INITIALIZED; + else if (cmd == BNX2X_F_CMD_TX_STOP) + next_state = BNX2X_F_STATE_TX_STOPPED; + + break; + case BNX2X_F_STATE_TX_STOPPED: + if (cmd == BNX2X_F_CMD_TX_START) + next_state = BNX2X_F_STATE_STARTED; break; default: @@ -5444,6 +5498,38 @@ static inline int bnx2x_func_send_stop(struct bnx2x *bp, NONE_CONNECTION_TYPE); } +static inline int bnx2x_func_send_tx_stop(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, 0, 0, 0, + NONE_CONNECTION_TYPE); +} +static inline int bnx2x_func_send_tx_start(struct bnx2x *bp, + struct bnx2x_func_state_params *params) +{ + struct bnx2x_func_sp_obj *o = params->f_obj; + struct flow_control_configuration *rdata = + (struct flow_control_configuration *)o->rdata; + dma_addr_t data_mapping = o->rdata_mapping; + struct bnx2x_func_tx_start_params *tx_start_params = + ¶ms->params.tx_start; + int i; + + memset(rdata, 0, sizeof(*rdata)); + + rdata->dcb_enabled = tx_start_params->dcb_enabled; + rdata->dcb_version = tx_start_params->dcb_version; + rdata->dont_add_pri_0_en = tx_start_params->dont_add_pri_0_en; + + for (i = 0; i < ARRAY_SIZE(rdata->traffic_type_to_priority_cos); i++) + rdata->traffic_type_to_priority_cos[i] = + tx_start_params->traffic_type_to_priority_cos[i]; + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0, + U64_HI(data_mapping), + U64_LO(data_mapping), NONE_CONNECTION_TYPE); +} + static int bnx2x_func_send_cmd(struct bnx2x *bp, struct bnx2x_func_state_params *params) { @@ -5456,6 +5542,10 @@ static int bnx2x_func_send_cmd(struct bnx2x *bp, return bnx2x_func_send_stop(bp, params); case BNX2X_F_CMD_HW_RESET: return bnx2x_func_hw_reset(bp, params); + case BNX2X_F_CMD_TX_STOP: + return bnx2x_func_send_tx_stop(bp, params); + case BNX2X_F_CMD_TX_START: + return bnx2x_func_send_tx_start(bp, params); default: BNX2X_ERR("Unknown command: %d\n", params->cmd); return -EINVAL; diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h index 83f3b0b4421..73400dd77b2 100644 --- a/drivers/net/bnx2x/bnx2x_sp.h +++ b/drivers/net/bnx2x/bnx2x_sp.h @@ -996,6 +996,7 @@ enum bnx2x_func_state { BNX2X_F_STATE_RESET, BNX2X_F_STATE_INITIALIZED, BNX2X_F_STATE_STARTED, + BNX2X_F_STATE_TX_STOPPED, BNX2X_F_STATE_MAX, }; @@ -1005,6 +1006,8 @@ enum bnx2x_func_cmd { BNX2X_F_CMD_START, BNX2X_F_CMD_STOP, BNX2X_F_CMD_HW_RESET, + BNX2X_F_CMD_TX_STOP, + BNX2X_F_CMD_TX_START, BNX2X_F_CMD_MAX, }; @@ -1047,6 +1050,13 @@ struct bnx2x_func_start_params { u8 network_cos_mode; }; +struct bnx2x_func_tx_start_params { + struct priority_cos traffic_type_to_priority_cos[MAX_TRAFFIC_TYPES]; + u8 dcb_enabled; + u8 dcb_version; + u8 dont_add_pri_0_en; +}; + struct bnx2x_func_state_params { struct bnx2x_func_sp_obj *f_obj; @@ -1061,6 +1071,7 @@ struct bnx2x_func_state_params { struct bnx2x_func_hw_init_params hw_init; struct bnx2x_func_hw_reset_params hw_reset; struct bnx2x_func_start_params start; + struct bnx2x_func_tx_start_params tx_start; } params; }; @@ -1152,6 +1163,8 @@ void bnx2x_init_func_obj(struct bnx2x *bp, int bnx2x_func_state_change(struct bnx2x *bp, struct bnx2x_func_state_params *params); +enum bnx2x_func_state bnx2x_func_get_state(struct bnx2x *bp, + struct bnx2x_func_sp_obj *o); /******************* Queue State **************/ void bnx2x_init_queue_obj(struct bnx2x *bp, struct bnx2x_queue_sp_obj *obj, u8 cl_id, u32 *cids, -- cgit v1.2.3-70-g09d2 From d1c228d9b9b915a14cf362ebd817c10166be01e6 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 19 Jul 2011 01:42:40 +0000 Subject: bnx2x: fix MB index for 4-port devices Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 333f5d6c6b8..4b255e5f8f1 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1104,7 +1104,7 @@ struct bnx2x { #define BP_VN(bp) (BP_E1HVN(bp)) /*remove when approved*/ #define BP_L_ID(bp) (BP_E1HVN(bp) << 2) #define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\ - BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1)) + BP_VN(bp) * ((CHIP_IS_E1x(bp) || (CHIP_MODE_IS_4_PORT(bp))) ? 2 : 1)) struct net_device *dev; struct pci_dev *pdev; -- cgit v1.2.3-70-g09d2 From 019dbb4c0106f11b5c6543bffaedf10067e28398 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 19 Jul 2011 01:43:25 +0000 Subject: bnx2x: disable loacal BH when scheduling FCOE napi Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index a86517cffd4..b8f8793912c 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4520,8 +4520,15 @@ static void bnx2x_sp_task(struct work_struct *work) struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); if ((!NO_FCOE(bp)) && - (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) + (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { + /* + * Prevent local bottom-halves from running as + * we are going to change the local NAPI list. + */ + local_bh_disable(); napi_schedule(&bnx2x_fcoe(bp, napi)); + local_bh_enable(); + } #endif /* Handle EQ completions */ bnx2x_eq_int(bp); -- cgit v1.2.3-70-g09d2 From f5219d8eb8b32eb32522063d2163f95e1cf7bb5c Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 19 Jul 2011 01:44:11 +0000 Subject: bnx2x: use BNX2X_Q_FLG_TPA_IPV6 for TPA queue configuration Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 4 +++- drivers/net/bnx2x/bnx2x_sp.c | 2 +- drivers/net/bnx2x/bnx2x_sp.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index b8f8793912c..7a891824fab 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2699,8 +2699,10 @@ static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp, if (IS_FCOE_FP(fp)) __set_bit(BNX2X_Q_FLG_FCOE, &flags); - if (!fp->disable_tpa) + if (!fp->disable_tpa) { __set_bit(BNX2X_Q_FLG_TPA, &flags); + __set_bit(BNX2X_Q_FLG_TPA_IPV6, &flags); + } if (leading) { __set_bit(BNX2X_Q_FLG_LEADING_RSS, &flags); diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index 6306ff59de0..5a213e476d8 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -4240,7 +4240,7 @@ static void bnx2x_q_fill_setup_data_e2(struct bnx2x *bp, /* Rx data */ /* IPv6 TPA supported for E2 and above only */ - data->rx.tpa_en |= test_bit(BNX2X_Q_FLG_TPA, ¶ms->flags) * + data->rx.tpa_en |= test_bit(BNX2X_Q_FLG_TPA_IPV6, ¶ms->flags) * CLIENT_INIT_RX_DATA_TPA_EN_IPV6; } diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h index 73400dd77b2..9a517c2e9f1 100644 --- a/drivers/net/bnx2x/bnx2x_sp.h +++ b/drivers/net/bnx2x/bnx2x_sp.h @@ -749,6 +749,7 @@ enum bnx2x_queue_cmd { /* queue SETUP + INIT flags */ enum { BNX2X_Q_FLG_TPA, + BNX2X_Q_FLG_TPA_IPV6, BNX2X_Q_FLG_STATS, BNX2X_Q_FLG_ZERO_STATS, BNX2X_Q_FLG_ACTIVE, -- cgit v1.2.3-70-g09d2 From 53e51e2f480aaa000b0a7d2704ce2b4b646a73c7 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 19 Jul 2011 01:45:02 +0000 Subject: bnx2x: fix memory barriers Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 8 +++- drivers/net/bnx2x/bnx2x_sp.c | 86 +++++++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 7a891824fab..e4dea114d04 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2984,8 +2984,12 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) { int func = BP_FUNC(bp); - /* Make sure that BD data is updated before writing the producer */ - wmb(); + /* + * Make sure that BD data is updated before writing the producer: + * BD data is written to the memory, the producer is read from the + * memory, thus we need a full memory barrier to ensure the ordering. + */ + mb(); REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), bp->spq_prod_idx); diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index 5a213e476d8..cce87d5e760 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -1563,8 +1563,13 @@ static int bnx2x_execute_vlan_mac(struct bnx2x *bp, idx++; } - /* Commit the data writes towards the memory */ - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ rc = bnx2x_sp_post(bp, o->ramrod_cmd, r->cid, U64_HI(r->rdata_mapping), @@ -2224,8 +2229,13 @@ static int bnx2x_set_rx_mode_e2(struct bnx2x *bp, data->header.rule_cnt, p->rx_accept_flags, p->tx_accept_flags); - /* Commit writes towards the memory before sending a ramrod */ - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_FILTER_RULES, p->cid, @@ -2918,16 +2928,22 @@ static int bnx2x_mcast_setup_e2(struct bnx2x *bp, if (!o->total_pending_num) bnx2x_mcast_refresh_registry_e2(bp, o); - /* Commit writes towards the memory before sending a ramrod */ - mb(); - - /* If CLEAR_ONLY was requested - don't send a ramrod and clear + /* + * If CLEAR_ONLY was requested - don't send a ramrod and clear * RAMROD_PENDING status immediately. */ if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { raw->clear_pending(raw); return 0; } else { + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ + /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_MULTICAST_RULES, raw->cid, U64_HI(raw->rdata_mapping), @@ -3404,16 +3420,22 @@ static int bnx2x_mcast_setup_e1(struct bnx2x *bp, if (rc) return rc; - /* Commit writes towards the memory before sending a ramrod */ - mb(); - - /* If CLEAR_ONLY was requested - don't send a ramrod and clear + /* + * If CLEAR_ONLY was requested - don't send a ramrod and clear * RAMROD_PENDING status immediately. */ if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) { raw->clear_pending(raw); return 0; } else { + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ + /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, raw->cid, U64_HI(raw->rdata_mapping), @@ -4038,8 +4060,13 @@ static int bnx2x_setup_rss(struct bnx2x *bp, data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY; } - /* Commit writes towards the memory before sending a ramrod */ - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ /* Send a ramrod */ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_RSS_UPDATE, r->cid, @@ -4505,7 +4532,13 @@ static inline int bnx2x_q_send_setup_e1x(struct bnx2x *bp, /* Fill the ramrod data */ bnx2x_q_fill_setup_data_cmn(bp, params, rdata); - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], U64_HI(data_mapping), @@ -4528,6 +4561,13 @@ static inline int bnx2x_q_send_setup_e2(struct bnx2x *bp, bnx2x_q_fill_setup_data_cmn(bp, params, rdata); bnx2x_q_fill_setup_data_e2(bp, params, rdata); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX], U64_HI(data_mapping), @@ -4665,7 +4705,13 @@ static inline int bnx2x_q_send_update(struct bnx2x *bp, /* Fill the ramrod data */ bnx2x_q_fill_update_data(bp, o, update_params, rdata); - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE, o->cids[cid_index], U64_HI(data_mapping), @@ -5484,7 +5530,13 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, rdata->path_id = BP_PATH(bp); rdata->network_cos_mode = start_params->network_cos_mode; - mb(); + /* + * No need for an explicit memory barrier here as long we would + * need to ensure the ordering of writing to the SPQ element + * and updating of the SPQ producer which involves a memory + * read and we will have to put a full memory barrier there + * (inside bnx2x_sp_post()). + */ return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, U64_HI(data_mapping), -- cgit v1.2.3-70-g09d2 From 928ad22a3b033a994081dbf49f3c046195dd2349 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 19 Jul 2011 01:46:11 +0000 Subject: bnx2x: disable FCoE for 578xx devices since not yet supported Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index e4dea114d04..28ef7faf448 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -10575,8 +10575,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); #ifdef BCM_CNIC - /* disable FCOE L2 queue for E1x*/ - if (CHIP_IS_E1x(bp)) + /* disable FCOE L2 queue for E1x and E3*/ + if (CHIP_IS_E1x(bp) || CHIP_IS_E3(bp)) bp->flags |= NO_FCOE_FLAG; #endif -- cgit v1.2.3-70-g09d2 From a9481a38b1474aab0f686b30e4e2b57880065ad2 Mon Sep 17 00:00:00 2001 From: Matvejchikov Ilya Date: Mon, 18 Jul 2011 21:56:44 +0000 Subject: slip: remove unused 'line' field from the 'slip' structure Signed-off-by: Matvejchikov Ilya Signed-off-by: David S. Miller --- drivers/net/slip.c | 3 --- drivers/net/slip.h | 1 - 2 files changed, 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8befe697bd7..f11b3f3df24 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -807,7 +807,6 @@ static int slip_open(struct tty_struct *tty) sl->tty = tty; tty->disc_data = sl; - sl->line = tty_devnum(tty); sl->pid = current->pid; if (!test_bit(SLF_INUSE, &sl->flags)) { @@ -874,8 +873,6 @@ static void slip_close(struct tty_struct *tty) tty->disc_data = NULL; sl->tty = NULL; - if (!sl->leased) - sl->line = 0; /* VSV = very important to remove timers */ #ifdef CONFIG_SLIP_SMART diff --git a/drivers/net/slip.h b/drivers/net/slip.h index 914e958abbf..aa0764ce234 100644 --- a/drivers/net/slip.h +++ b/drivers/net/slip.h @@ -90,7 +90,6 @@ struct slip { unsigned char mode; /* SLIP mode */ unsigned char leased; - dev_t line; pid_t pid; #define SL_MODE_SLIP 0 #define SL_MODE_CSLIP 1 -- cgit v1.2.3-70-g09d2 From 7ad711b49e661a0979ed1a84bed16bc9fa7f872b Mon Sep 17 00:00:00 2001 From: Matvejchikov Ilya Date: Mon, 18 Jul 2011 21:58:48 +0000 Subject: slcan: remove unused 'leased', 'line' and 'pid' fields from the 'slcan' structure Signed-off-by: Matvejchikov Ilya Acked-by: Oliver Hartkopp Signed-off-by: David S. Miller --- drivers/net/can/slcan.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 65e54fd0a8d..f523f1cc514 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -96,10 +96,6 @@ struct slcan { unsigned long flags; /* Flag values/ mode etc */ #define SLF_INUSE 0 /* Channel in use */ #define SLF_ERROR 1 /* Parity, etc. error */ - - unsigned char leased; - dev_t line; - pid_t pid; }; static struct net_device **slcan_devs; @@ -446,7 +442,7 @@ static void slc_sync(void) break; sl = netdev_priv(dev); - if (sl->tty || sl->leased) + if (sl->tty) continue; if (dev->flags & IFF_UP) dev_close(dev); @@ -534,8 +530,6 @@ static int slcan_open(struct tty_struct *tty) sl->tty = tty; tty->disc_data = sl; - sl->line = tty_devnum(tty); - sl->pid = current->pid; if (!test_bit(SLF_INUSE, &sl->flags)) { /* Perform the low-level SLCAN initialization. */ @@ -586,8 +580,6 @@ static void slcan_close(struct tty_struct *tty) tty->disc_data = NULL; sl->tty = NULL; - if (!sl->leased) - sl->line = 0; /* Flush network side */ unregister_netdev(sl->dev); -- cgit v1.2.3-70-g09d2 From bf61ee146749de86a5ac46b25d28f8da5bb39d03 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Thu, 21 Jul 2011 07:56:51 +0000 Subject: bnx2x: Implementation for netdev->ndo_fcoe_get_wwn Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 23 ++++++++++++++++ drivers/net/bnx2x/bnx2x_cmn.h | 11 ++++++++ drivers/net/bnx2x/bnx2x_main.c | 60 +++++++++++++++++++++++++++++++++++++++--- drivers/net/cnic_if.h | 5 ++++ 4 files changed, 96 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 8b079dcd5b9..3aadc306c8d 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -3327,6 +3327,29 @@ int bnx2x_get_link_cfg_idx(struct bnx2x *bp) return LINK_CONFIG_IDX(sel_phy_idx); } +#if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC) +int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) +{ + struct bnx2x *bp = netdev_priv(dev); + struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + + switch (type) { + case NETDEV_FCOE_WWNN: + *wwn = HILO_U64(cp->fcoe_wwn_node_name_hi, + cp->fcoe_wwn_node_name_lo); + break; + case NETDEV_FCOE_WWPN: + *wwn = HILO_U64(cp->fcoe_wwn_port_name_hi, + cp->fcoe_wwn_port_name_lo); + break; + default: + return -EINVAL; + } + + return 0; +} +#endif + /* called with rtnl_lock */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 83d7d1bb7b1..223bfeebc59 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -522,6 +522,17 @@ void bnx2x_free_mem_bp(struct bnx2x *bp); */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu); +#if defined(BCM_CNIC) && (defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)) +/** + * bnx2x_fcoe_get_wwn - return the requested WWN value for this port + * + * @dev: net_device + * @wwn: output buffer + * @type: WWN type: NETDEV_FCOE_WWNN (node) or NETDEV_FCOE_WWPN (port) + * + */ +int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type); +#endif u32 bnx2x_fix_features(struct net_device *dev, u32 features); int bnx2x_set_features(struct net_device *dev, u32 features); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 28ef7faf448..121df1f676e 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -9104,10 +9104,13 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) #ifdef BCM_CNIC static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) { + int port = BP_PORT(bp); + int func = BP_ABS_FUNC(bp); + u32 max_iscsi_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, - drv_lic_key[BP_PORT(bp)].max_iscsi_conn); + drv_lic_key[port].max_iscsi_conn); u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, - drv_lic_key[BP_PORT(bp)].max_fcoe_conn); + drv_lic_key[port].max_fcoe_conn); /* Get the number of maximum allowed iSCSI and FCoE connections */ bp->cnic_eth_dev.max_iscsi_conn = @@ -9118,11 +9121,59 @@ static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) (max_fcoe_conn & BNX2X_MAX_FCOE_INIT_CONN_MASK) >> BNX2X_MAX_FCOE_INIT_CONN_SHIFT; + /* Read the WWN: */ + if (!IS_MF(bp)) { + /* Port info */ + bp->cnic_eth_dev.fcoe_wwn_port_name_hi = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_port_name_upper); + bp->cnic_eth_dev.fcoe_wwn_port_name_lo = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_port_name_lower); + + /* Node info */ + bp->cnic_eth_dev.fcoe_wwn_node_name_hi = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_node_name_upper); + bp->cnic_eth_dev.fcoe_wwn_node_name_lo = + SHMEM_RD(bp, + dev_info.port_hw_config[port]. + fcoe_wwn_node_name_lower); + } else if (!IS_MF_SD(bp)) { + u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); + + /* + * Read the WWN info only if the FCoE feature is enabled for + * this function. + */ + if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) { + /* Port info */ + bp->cnic_eth_dev.fcoe_wwn_port_name_hi = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_port_name_upper); + bp->cnic_eth_dev.fcoe_wwn_port_name_lo = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_port_name_lower); + + /* Node info */ + bp->cnic_eth_dev.fcoe_wwn_node_name_hi = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_node_name_upper); + bp->cnic_eth_dev.fcoe_wwn_node_name_lo = + MF_CFG_RD(bp, func_ext_config[func]. + fcoe_wwn_node_name_lower); + } + } + BNX2X_DEV_INFO("max_iscsi_conn 0x%x max_fcoe_conn 0x%x\n", bp->cnic_eth_dev.max_iscsi_conn, bp->cnic_eth_dev.max_fcoe_conn); - /* If mamimum allowed number of connections is zero - + /* + * If maximum allowed number of connections is zero - * disable the feature. */ if (!bp->cnic_eth_dev.max_iscsi_conn) @@ -9993,6 +10044,9 @@ static const struct net_device_ops bnx2x_netdev_ops = { #endif .ndo_setup_tc = bnx2x_setup_tc, +#if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC) + .ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn, +#endif }; static inline int bnx2x_set_coherency_mask(struct bnx2x *bp) diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 642b9d56a1c..8a1ffbe123b 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -181,6 +181,11 @@ struct cnic_eth_dev { u32 max_fcoe_conn; u32 max_rdma_conn; u32 fcoe_init_cid; + u32 fcoe_wwn_port_name_hi; + u32 fcoe_wwn_port_name_lo; + u32 fcoe_wwn_node_name_hi; + u32 fcoe_wwn_node_name_lo; + u16 iscsi_l2_client_id; u16 iscsi_l2_cid; u8 iscsi_mac[ETH_ALEN]; -- cgit v1.2.3-70-g09d2 From 0fea29c129bdae7aca217551acb1108e00cc5ff1 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Thu, 21 Jul 2011 07:57:23 +0000 Subject: bnx2x: Fixed ethtool -d for 578xx Registers dump code erroneously treated 578xx as 57712. This patch fixes the above and also removes unused data structures. Signed-off-by: Vladislav Zolotarov Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_dump.h | 1784 ++++++++++++++++++++++--------------- drivers/net/bnx2x/bnx2x_ethtool.c | 229 +++-- 2 files changed, 1202 insertions(+), 811 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h index 407531a9ab1..b983825d0ee 100644 --- a/drivers/net/bnx2x/bnx2x_dump.h +++ b/drivers/net/bnx2x/bnx2x_dump.h @@ -37,39 +37,78 @@ #define RI_E1H 0x2 #define RI_E2 0x4 #define RI_E3 0x8 +#define RI_E3B0 0x10 #define RI_ONLINE 0x100 +#define RI_OFFLINE 0x0 #define RI_PATH0_DUMP 0x200 #define RI_PATH1_DUMP 0x400 -#define RI_E1_OFFLINE (RI_E1) -#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) -#define RI_E1H_OFFLINE (RI_E1H) -#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) -#define RI_E2_OFFLINE (RI_E2) -#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) -#define RI_E3_OFFLINE (RI_E3) -#define RI_E3_ONLINE (RI_E3 | RI_ONLINE) -#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) -#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) -#define RI_E1E1HE2_OFFLINE (RI_E1 | RI_E1H | RI_E2) -#define RI_E1E1HE2_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) -#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) -#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) -#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) -#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) -#define RI_E1E3_OFFLINE (RI_E1 | RI_E3) -#define RI_E1E3_ONLINE (RI_E1 | RI_E3 | RI_ONLINE) -#define RI_E1HE3_OFFLINE (RI_E1H | RI_E3) -#define RI_E1HE3_ONLINE (RI_E1H | RI_E3 | RI_ONLINE) -#define RI_E2E3_OFFLINE (RI_E2 | RI_E3) -#define RI_E2E3_ONLINE (RI_E2 | RI_E3 | RI_ONLINE) -#define RI_E1E1HE3_OFFLINE (RI_E1 | RI_E1H | RI_E3) -#define RI_E1E1HE3_ONLINE (RI_E1 | RI_E1H | RI_E3 | RI_ONLINE) -#define RI_E1HE2E3_OFFLINE (RI_E2 | RI_E1H | RI_E3) -#define RI_E1HE2E3_ONLINE (RI_E2 | RI_E1H | RI_E3 | RI_ONLINE) -#define RI_E1E2E3_OFFLINE (RI_E2 | RI_E1 | RI_E3) -#define RI_E1E2E3_ONLINE (RI_E2 | RI_E1 | RI_E3 | RI_ONLINE) -#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3) -#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_ONLINE) + +#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) +#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) +#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) +#define RI_E1E2_ONLINE (RI_E1 | RI_E2 | RI_ONLINE) +#define RI_E1HE2_ONLINE (RI_E1H | RI_E2 | RI_ONLINE) +#define RI_E1E1HE2_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) +#define RI_E3_ONLINE (RI_E3 | RI_ONLINE) +#define RI_E1E3_ONLINE (RI_E1 | RI_E3 | RI_ONLINE) +#define RI_E1HE3_ONLINE (RI_E1H | RI_E3 | RI_ONLINE) +#define RI_E1E1HE3_ONLINE (RI_E1 | RI_E1H | RI_E3 | RI_ONLINE) +#define RI_E2E3_ONLINE (RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E1E2E3_ONLINE (RI_E1 | RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E1HE2E3_ONLINE (RI_E1H | RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E1E1HE2E3_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_ONLINE) +#define RI_E3B0_ONLINE (RI_E3B0 | RI_ONLINE) +#define RI_E1E3B0_ONLINE (RI_E1 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE3B0_ONLINE (RI_E1H | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE3B0_ONLINE (RI_E1 | RI_E1H | RI_E3B0 | RI_ONLINE) +#define RI_E2E3B0_ONLINE (RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E1E2E3B0_ONLINE (RI_E1 | RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE2E3B0_ONLINE (RI_E1H | RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE2E3B0_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3B0 | RI_ONLINE) +#define RI_E3E3B0_ONLINE (RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E3E3B0_ONLINE (RI_E1 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE3E3B0_ONLINE (RI_E1H | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE3E3B0_ONLINE (RI_E1 | RI_E1H | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E2E3E3B0_ONLINE (RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E2E3E3B0_ONLINE (RI_E1 | RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1HE2E3E3B0_ONLINE (RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1E1HE2E3E3B0_ONLINE \ + (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_ONLINE) +#define RI_E1_OFFLINE (RI_E1 | RI_OFFLINE) +#define RI_E1H_OFFLINE (RI_E1H | RI_OFFLINE) +#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H | RI_OFFLINE) +#define RI_E2_OFFLINE (RI_E2 | RI_OFFLINE) +#define RI_E1E2_OFFLINE (RI_E1 | RI_E2 | RI_OFFLINE) +#define RI_E1HE2_OFFLINE (RI_E1H | RI_E2 | RI_OFFLINE) +#define RI_E1E1HE2_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_OFFLINE) +#define RI_E3_OFFLINE (RI_E3 | RI_OFFLINE) +#define RI_E1E3_OFFLINE (RI_E1 | RI_E3 | RI_OFFLINE) +#define RI_E1HE3_OFFLINE (RI_E1H | RI_E3 | RI_OFFLINE) +#define RI_E1E1HE3_OFFLINE (RI_E1 | RI_E1H | RI_E3 | RI_OFFLINE) +#define RI_E2E3_OFFLINE (RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E1E2E3_OFFLINE (RI_E1 | RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E1HE2E3_OFFLINE (RI_E1H | RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E1E1HE2E3_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_OFFLINE) +#define RI_E3B0_OFFLINE (RI_E3B0 | RI_OFFLINE) +#define RI_E1E3B0_OFFLINE (RI_E1 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE3B0_OFFLINE (RI_E1H | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE3B0_OFFLINE (RI_E1 | RI_E1H | RI_E3B0 | RI_OFFLINE) +#define RI_E2E3B0_OFFLINE (RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E2E3B0_OFFLINE (RI_E1 | RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE2E3B0_OFFLINE (RI_E1H | RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE2E3B0_OFFLINE (RI_E1 | RI_E1H | RI_E2 | RI_E3B0 | RI_OFFLINE) +#define RI_E3E3B0_OFFLINE (RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E3E3B0_OFFLINE (RI_E1 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE3E3B0_OFFLINE (RI_E1H | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE3E3B0_OFFLINE (RI_E1 | RI_E1H | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E2E3E3B0_OFFLINE (RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E2E3E3B0_OFFLINE (RI_E1 | RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1HE2E3E3B0_OFFLINE (RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_E1E1HE2E3E3B0_OFFLINE \ + (RI_E1 | RI_E1H | RI_E2 | RI_E3 | RI_E3B0 | RI_OFFLINE) +#define RI_ALL_ONLINE RI_E1E1HE2E3E3B0_ONLINE +#define RI_ALL_OFFLINE RI_E1E1HE2E3E3B0_OFFLINE #define DBG_DMP_TRACE_BUFFER_SIZE 0x800 #define DBG_DMP_TRACE_BUFFER_OFFSET(shmem0_offset) \ @@ -108,716 +147,991 @@ struct wreg_addr { }; static const struct reg_addr reg_addrs[] = { - { 0x2000, 341, RI_ALL_ONLINE }, { 0x2800, 103, RI_ALL_ONLINE }, - { 0x3000, 287, RI_ALL_ONLINE }, { 0x3800, 331, RI_ALL_ONLINE }, - { 0x8800, 6, RI_ALL_ONLINE }, { 0x8818, 1, RI_E1HE2E3_ONLINE }, - { 0x9000, 147, RI_E2E3_ONLINE }, { 0x924c, 1, RI_E2_ONLINE }, - { 0x9250, 16, RI_E2E3_ONLINE }, { 0x9400, 33, RI_E2E3_ONLINE }, - { 0x9484, 5, RI_E3_ONLINE }, { 0xa000, 27, RI_ALL_ONLINE }, - { 0xa06c, 1, RI_E1E1H_ONLINE }, { 0xa070, 71, RI_ALL_ONLINE }, - { 0xa18c, 4, RI_E1E1H_ONLINE }, { 0xa19c, 62, RI_ALL_ONLINE }, - { 0xa294, 2, RI_E1E1H_ONLINE }, { 0xa29c, 2, RI_ALL_ONLINE }, - { 0xa2a4, 2, RI_E1E1HE2_ONLINE }, { 0xa2ac, 52, RI_ALL_ONLINE }, - { 0xa39c, 7, RI_E1HE2E3_ONLINE }, { 0xa3b8, 2, RI_E3_ONLINE }, - { 0xa3c0, 3, RI_E1HE2E3_ONLINE }, { 0xa3d0, 1, RI_E1HE2E3_ONLINE }, - { 0xa3d8, 1, RI_E1HE2E3_ONLINE }, { 0xa3e0, 1, RI_E1HE2E3_ONLINE }, - { 0xa3e8, 1, RI_E1HE2E3_ONLINE }, { 0xa3f0, 1, RI_E1HE2E3_ONLINE }, - { 0xa3f8, 1, RI_E1HE2E3_ONLINE }, { 0xa400, 40, RI_ALL_ONLINE }, - { 0xa4a0, 1, RI_E1E1HE2_ONLINE }, { 0xa4a4, 2, RI_ALL_ONLINE }, - { 0xa4ac, 2, RI_E1E1H_ONLINE }, { 0xa4b4, 1, RI_E1E1HE2_ONLINE }, - { 0xa4b8, 2, RI_E1E1H_ONLINE }, { 0xa4c0, 3, RI_ALL_ONLINE }, - { 0xa4cc, 5, RI_E1E1H_ONLINE }, { 0xa4e0, 3, RI_ALL_ONLINE }, - { 0xa4fc, 2, RI_ALL_ONLINE }, { 0xa504, 1, RI_E1E1H_ONLINE }, - { 0xa508, 3, RI_ALL_ONLINE }, { 0xa518, 1, RI_ALL_ONLINE }, - { 0xa520, 1, RI_ALL_ONLINE }, { 0xa528, 1, RI_ALL_ONLINE }, - { 0xa530, 1, RI_ALL_ONLINE }, { 0xa538, 1, RI_ALL_ONLINE }, - { 0xa540, 1, RI_ALL_ONLINE }, { 0xa548, 1, RI_E1E1H_ONLINE }, - { 0xa550, 1, RI_E1E1H_ONLINE }, { 0xa558, 1, RI_E1E1H_ONLINE }, - { 0xa560, 1, RI_E1E1H_ONLINE }, { 0xa568, 1, RI_E1E1H_ONLINE }, - { 0xa570, 1, RI_ALL_ONLINE }, { 0xa580, 1, RI_ALL_ONLINE }, - { 0xa590, 1, RI_ALL_ONLINE }, { 0xa5a0, 1, RI_E1E1HE2_ONLINE }, - { 0xa5c0, 1, RI_ALL_ONLINE }, { 0xa5e0, 1, RI_E1HE2E3_ONLINE }, - { 0xa5e8, 1, RI_E1HE2E3_ONLINE }, { 0xa5f0, 1, RI_E1HE2E3_ONLINE }, - { 0xa5f8, 1, RI_E1HE2_ONLINE }, { 0xa5fc, 9, RI_E1HE2E3_ONLINE }, - { 0xa620, 6, RI_E2E3_ONLINE }, { 0xa638, 20, RI_E2_ONLINE }, - { 0xa688, 42, RI_E2E3_ONLINE }, { 0xa730, 1, RI_E2_ONLINE }, - { 0xa734, 2, RI_E2E3_ONLINE }, { 0xa73c, 4, RI_E2_ONLINE }, - { 0xa74c, 5, RI_E2E3_ONLINE }, { 0xa760, 5, RI_E2_ONLINE }, - { 0xa774, 7, RI_E2E3_ONLINE }, { 0xa790, 15, RI_E2_ONLINE }, - { 0xa7cc, 4, RI_E2E3_ONLINE }, { 0xa7e0, 6, RI_E3_ONLINE }, - { 0xa800, 18, RI_E2_ONLINE }, { 0xa848, 33, RI_E2E3_ONLINE }, - { 0xa8cc, 2, RI_E3_ONLINE }, { 0xa8d4, 4, RI_E2E3_ONLINE }, - { 0xa8e4, 1, RI_E3_ONLINE }, { 0xa8e8, 1, RI_E2E3_ONLINE }, - { 0xa8f0, 1, RI_E2E3_ONLINE }, { 0xa8f8, 30, RI_E3_ONLINE }, - { 0xa974, 73, RI_E3_ONLINE }, { 0xac30, 1, RI_E3_ONLINE }, - { 0xac40, 1, RI_E3_ONLINE }, { 0xac50, 1, RI_E3_ONLINE }, - { 0x10000, 9, RI_ALL_ONLINE }, { 0x10024, 1, RI_E1E1HE2_ONLINE }, - { 0x10028, 5, RI_ALL_ONLINE }, { 0x1003c, 6, RI_E1E1HE2_ONLINE }, - { 0x10054, 20, RI_ALL_ONLINE }, { 0x100a4, 4, RI_E1E1HE2_ONLINE }, - { 0x100b4, 11, RI_ALL_ONLINE }, { 0x100e0, 4, RI_E1E1HE2_ONLINE }, - { 0x100f0, 8, RI_ALL_ONLINE }, { 0x10110, 6, RI_E1E1HE2_ONLINE }, - { 0x10128, 110, RI_ALL_ONLINE }, { 0x102e0, 4, RI_E1E1HE2_ONLINE }, - { 0x102f0, 18, RI_ALL_ONLINE }, { 0x10338, 20, RI_E1E1HE2_ONLINE }, - { 0x10388, 10, RI_ALL_ONLINE }, { 0x10400, 6, RI_E1E1HE2_ONLINE }, - { 0x10418, 6, RI_ALL_ONLINE }, { 0x10430, 10, RI_E1E1HE2_ONLINE }, - { 0x10458, 22, RI_ALL_ONLINE }, { 0x104b0, 12, RI_E1E1HE2_ONLINE }, - { 0x104e0, 1, RI_ALL_ONLINE }, { 0x104e8, 2, RI_ALL_ONLINE }, - { 0x104f4, 2, RI_ALL_ONLINE }, { 0x10500, 146, RI_ALL_ONLINE }, - { 0x10750, 2, RI_E1E1HE2_ONLINE }, { 0x10760, 2, RI_E1E1HE2_ONLINE }, - { 0x10770, 2, RI_E1E1HE2_ONLINE }, { 0x10780, 2, RI_E1E1HE2_ONLINE }, - { 0x10790, 2, RI_ALL_ONLINE }, { 0x107a0, 2, RI_E1E1HE2_ONLINE }, - { 0x107b0, 2, RI_E1E1HE2_ONLINE }, { 0x107c0, 2, RI_E1E1HE2_ONLINE }, - { 0x107d0, 2, RI_E1E1HE2_ONLINE }, { 0x107e0, 2, RI_ALL_ONLINE }, - { 0x10880, 2, RI_ALL_ONLINE }, { 0x10900, 2, RI_ALL_ONLINE }, - { 0x16000, 1, RI_E1HE2_ONLINE }, { 0x16004, 25, RI_E1HE2E3_ONLINE }, - { 0x16070, 18, RI_E1HE2E3_ONLINE }, { 0x160c0, 7, RI_E1HE2E3_ONLINE }, - { 0x160dc, 2, RI_E1HE2_ONLINE }, { 0x160e4, 10, RI_E1HE2E3_ONLINE }, - { 0x1610c, 2, RI_E1HE2_ONLINE }, { 0x16114, 6, RI_E1HE2E3_ONLINE }, - { 0x16140, 48, RI_E1HE2E3_ONLINE }, { 0x16204, 5, RI_E1HE2E3_ONLINE }, - { 0x18000, 1, RI_E1HE2E3_ONLINE }, { 0x18008, 1, RI_E1HE2E3_ONLINE }, - { 0x18010, 35, RI_E2E3_ONLINE }, { 0x180a4, 2, RI_E2E3_ONLINE }, - { 0x180c0, 109, RI_E2E3_ONLINE }, { 0x18274, 1, RI_E2_ONLINE }, - { 0x18278, 81, RI_E2E3_ONLINE }, { 0x18440, 63, RI_E2E3_ONLINE }, - { 0x18570, 42, RI_E3_ONLINE }, { 0x20000, 24, RI_ALL_ONLINE }, - { 0x20060, 8, RI_ALL_ONLINE }, { 0x20080, 94, RI_ALL_ONLINE }, - { 0x201f8, 1, RI_E1E1H_ONLINE }, { 0x201fc, 1, RI_ALL_ONLINE }, - { 0x20200, 1, RI_E1E1H_ONLINE }, { 0x20204, 1, RI_ALL_ONLINE }, - { 0x20208, 1, RI_E1E1H_ONLINE }, { 0x2020c, 39, RI_ALL_ONLINE }, - { 0x202c8, 1, RI_E2E3_ONLINE }, { 0x202d8, 4, RI_E2E3_ONLINE }, - { 0x20400, 2, RI_ALL_ONLINE }, { 0x2040c, 8, RI_ALL_ONLINE }, - { 0x2042c, 18, RI_E1HE2E3_ONLINE }, { 0x20480, 1, RI_ALL_ONLINE }, - { 0x20500, 1, RI_ALL_ONLINE }, { 0x20600, 1, RI_ALL_ONLINE }, - { 0x28000, 1, RI_ALL_ONLINE }, { 0x28004, 8191, RI_ALL_OFFLINE }, - { 0x30000, 1, RI_ALL_ONLINE }, { 0x30004, 16383, RI_ALL_OFFLINE }, - { 0x40000, 98, RI_ALL_ONLINE }, { 0x401a8, 8, RI_E1HE2E3_ONLINE }, - { 0x401c8, 1, RI_E1H_ONLINE }, { 0x401cc, 2, RI_E1HE2E3_ONLINE }, - { 0x401d4, 2, RI_E2E3_ONLINE }, { 0x40200, 4, RI_ALL_ONLINE }, - { 0x40220, 18, RI_E2E3_ONLINE }, { 0x40268, 2, RI_E3_ONLINE }, - { 0x40400, 43, RI_ALL_ONLINE }, { 0x404cc, 3, RI_E1HE2E3_ONLINE }, - { 0x404e0, 1, RI_E2E3_ONLINE }, { 0x40500, 2, RI_ALL_ONLINE }, - { 0x40510, 2, RI_ALL_ONLINE }, { 0x40520, 2, RI_ALL_ONLINE }, - { 0x40530, 2, RI_ALL_ONLINE }, { 0x40540, 2, RI_ALL_ONLINE }, - { 0x40550, 10, RI_E2E3_ONLINE }, { 0x40610, 2, RI_E2E3_ONLINE }, - { 0x42000, 164, RI_ALL_ONLINE }, { 0x422c0, 4, RI_E2E3_ONLINE }, - { 0x422d4, 5, RI_E1HE2E3_ONLINE }, { 0x422e8, 1, RI_E2E3_ONLINE }, - { 0x42400, 49, RI_ALL_ONLINE }, { 0x424c8, 38, RI_ALL_ONLINE }, - { 0x42568, 2, RI_ALL_ONLINE }, { 0x42640, 5, RI_E2E3_ONLINE }, - { 0x42800, 1, RI_ALL_ONLINE }, { 0x50000, 1, RI_ALL_ONLINE }, - { 0x50004, 19, RI_ALL_ONLINE }, { 0x50050, 8, RI_ALL_ONLINE }, - { 0x50070, 88, RI_ALL_ONLINE }, { 0x501f0, 4, RI_E1HE2E3_ONLINE }, - { 0x50200, 2, RI_ALL_ONLINE }, { 0x5020c, 7, RI_ALL_ONLINE }, - { 0x50228, 6, RI_E1HE2E3_ONLINE }, { 0x50240, 1, RI_ALL_ONLINE }, - { 0x50280, 1, RI_ALL_ONLINE }, { 0x50300, 1, RI_E2E3_ONLINE }, - { 0x5030c, 1, RI_E2E3_ONLINE }, { 0x50318, 1, RI_E2E3_ONLINE }, - { 0x5031c, 1, RI_E2E3_ONLINE }, { 0x50320, 2, RI_E2E3_ONLINE }, - { 0x52000, 1, RI_ALL_ONLINE }, { 0x54000, 1, RI_ALL_ONLINE }, - { 0x54004, 3327, RI_ALL_OFFLINE }, { 0x58000, 1, RI_ALL_ONLINE }, - { 0x58004, 8191, RI_E1E1H_OFFLINE }, { 0x60000, 26, RI_ALL_ONLINE }, - { 0x60068, 8, RI_E1E1H_ONLINE }, { 0x60088, 12, RI_ALL_ONLINE }, - { 0x600b8, 9, RI_E1E1H_ONLINE }, { 0x600dc, 1, RI_ALL_ONLINE }, - { 0x600e0, 5, RI_E1E1H_ONLINE }, { 0x600f4, 1, RI_E1E1HE2_ONLINE }, - { 0x600f8, 1, RI_E1E1H_ONLINE }, { 0x600fc, 8, RI_ALL_ONLINE }, - { 0x6013c, 24, RI_E1H_ONLINE }, { 0x6019c, 2, RI_E2E3_ONLINE }, - { 0x601ac, 18, RI_E2E3_ONLINE }, { 0x60200, 1, RI_ALL_ONLINE }, - { 0x60204, 2, RI_ALL_OFFLINE }, { 0x60210, 13, RI_E2E3_ONLINE }, - { 0x61000, 1, RI_ALL_ONLINE }, { 0x61004, 511, RI_ALL_OFFLINE }, - { 0x61800, 512, RI_E3_OFFLINE }, { 0x70000, 8, RI_ALL_ONLINE }, - { 0x70020, 8184, RI_ALL_OFFLINE }, { 0x78000, 8192, RI_E3_OFFLINE }, - { 0x85000, 3, RI_ALL_ONLINE }, { 0x8501c, 7, RI_ALL_ONLINE }, - { 0x85048, 1, RI_ALL_ONLINE }, { 0x85200, 32, RI_ALL_ONLINE }, + { 0x2000, 341, RI_ALL_ONLINE }, + { 0x2800, 103, RI_ALL_ONLINE }, + { 0x3000, 287, RI_ALL_ONLINE }, + { 0x3800, 331, RI_ALL_ONLINE }, + { 0x8800, 6, RI_ALL_ONLINE }, + { 0x8818, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x9000, 147, RI_E2E3E3B0_ONLINE }, + { 0x924c, 1, RI_E2_ONLINE }, + { 0x9250, 16, RI_E2E3E3B0_ONLINE }, + { 0x9400, 33, RI_E2E3E3B0_ONLINE }, + { 0x9484, 5, RI_E3E3B0_ONLINE }, + { 0xa000, 27, RI_ALL_ONLINE }, + { 0xa06c, 1, RI_E1E1H_ONLINE }, + { 0xa070, 71, RI_ALL_ONLINE }, + { 0xa18c, 4, RI_E1E1H_ONLINE }, + { 0xa19c, 62, RI_ALL_ONLINE }, + { 0xa294, 2, RI_E1E1H_ONLINE }, + { 0xa29c, 2, RI_ALL_ONLINE }, + { 0xa2a4, 2, RI_E1E1HE2_ONLINE }, + { 0xa2ac, 52, RI_ALL_ONLINE }, + { 0xa39c, 7, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3b8, 2, RI_E3E3B0_ONLINE }, + { 0xa3c0, 3, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3d0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3d8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3e0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3e8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3f0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa3f8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa400, 40, RI_ALL_ONLINE }, + { 0xa4a0, 1, RI_E1E1HE2_ONLINE }, + { 0xa4a4, 2, RI_ALL_ONLINE }, + { 0xa4ac, 2, RI_E1E1H_ONLINE }, + { 0xa4b4, 1, RI_E1E1HE2_ONLINE }, + { 0xa4b8, 2, RI_E1E1H_ONLINE }, + { 0xa4c0, 3, RI_ALL_ONLINE }, + { 0xa4cc, 5, RI_E1E1H_ONLINE }, + { 0xa4e0, 3, RI_ALL_ONLINE }, + { 0xa4fc, 2, RI_ALL_ONLINE }, + { 0xa504, 1, RI_E1E1H_ONLINE }, + { 0xa508, 3, RI_ALL_ONLINE }, + { 0xa518, 1, RI_ALL_ONLINE }, + { 0xa520, 1, RI_ALL_ONLINE }, + { 0xa528, 1, RI_ALL_ONLINE }, + { 0xa530, 1, RI_ALL_ONLINE }, + { 0xa538, 1, RI_ALL_ONLINE }, + { 0xa540, 1, RI_ALL_ONLINE }, + { 0xa548, 1, RI_E1E1H_ONLINE }, + { 0xa550, 1, RI_E1E1H_ONLINE }, + { 0xa558, 1, RI_E1E1H_ONLINE }, + { 0xa560, 1, RI_E1E1H_ONLINE }, + { 0xa568, 1, RI_E1E1H_ONLINE }, + { 0xa570, 1, RI_ALL_ONLINE }, + { 0xa580, 1, RI_ALL_ONLINE }, + { 0xa590, 1, RI_ALL_ONLINE }, + { 0xa5a0, 1, RI_E1E1HE2_ONLINE }, + { 0xa5c0, 1, RI_ALL_ONLINE }, + { 0xa5e0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa5e8, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa5f0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0xa5f8, 1, RI_E1HE2_ONLINE }, + { 0xa5fc, 9, RI_E1HE2E3E3B0_ONLINE }, + { 0xa620, 6, RI_E2E3E3B0_ONLINE }, + { 0xa638, 20, RI_E2_ONLINE }, + { 0xa688, 42, RI_E2E3E3B0_ONLINE }, + { 0xa730, 1, RI_E2_ONLINE }, + { 0xa734, 2, RI_E2E3E3B0_ONLINE }, + { 0xa73c, 4, RI_E2_ONLINE }, + { 0xa74c, 5, RI_E2E3E3B0_ONLINE }, + { 0xa760, 5, RI_E2_ONLINE }, + { 0xa774, 7, RI_E2E3E3B0_ONLINE }, + { 0xa790, 15, RI_E2_ONLINE }, + { 0xa7cc, 4, RI_E2E3E3B0_ONLINE }, + { 0xa7e0, 6, RI_E3E3B0_ONLINE }, + { 0xa800, 18, RI_E2_ONLINE }, + { 0xa848, 33, RI_E2E3E3B0_ONLINE }, + { 0xa8cc, 2, RI_E3E3B0_ONLINE }, + { 0xa8d4, 4, RI_E2E3E3B0_ONLINE }, + { 0xa8e4, 1, RI_E3E3B0_ONLINE }, + { 0xa8e8, 1, RI_E2E3E3B0_ONLINE }, + { 0xa8f0, 1, RI_E2E3E3B0_ONLINE }, + { 0xa8f8, 30, RI_E3E3B0_ONLINE }, + { 0xa974, 73, RI_E3E3B0_ONLINE }, + { 0xac30, 1, RI_E3E3B0_ONLINE }, + { 0xac40, 1, RI_E3E3B0_ONLINE }, + { 0xac50, 1, RI_E3E3B0_ONLINE }, + { 0xac60, 1, RI_E3B0_ONLINE }, + { 0x10000, 9, RI_ALL_ONLINE }, + { 0x10024, 1, RI_E1E1HE2_ONLINE }, + { 0x10028, 5, RI_ALL_ONLINE }, + { 0x1003c, 6, RI_E1E1HE2_ONLINE }, + { 0x10054, 20, RI_ALL_ONLINE }, + { 0x100a4, 4, RI_E1E1HE2_ONLINE }, + { 0x100b4, 11, RI_ALL_ONLINE }, + { 0x100e0, 4, RI_E1E1HE2_ONLINE }, + { 0x100f0, 8, RI_ALL_ONLINE }, + { 0x10110, 6, RI_E1E1HE2_ONLINE }, + { 0x10128, 110, RI_ALL_ONLINE }, + { 0x102e0, 4, RI_E1E1HE2_ONLINE }, + { 0x102f0, 18, RI_ALL_ONLINE }, + { 0x10338, 20, RI_E1E1HE2_ONLINE }, + { 0x10388, 10, RI_ALL_ONLINE }, + { 0x10400, 6, RI_E1E1HE2_ONLINE }, + { 0x10418, 6, RI_ALL_ONLINE }, + { 0x10430, 10, RI_E1E1HE2_ONLINE }, + { 0x10458, 22, RI_ALL_ONLINE }, + { 0x104b0, 12, RI_E1E1HE2_ONLINE }, + { 0x104e0, 1, RI_ALL_ONLINE }, + { 0x104e8, 2, RI_ALL_ONLINE }, + { 0x104f4, 2, RI_ALL_ONLINE }, + { 0x10500, 146, RI_ALL_ONLINE }, + { 0x10750, 2, RI_E1E1HE2_ONLINE }, + { 0x10760, 2, RI_E1E1HE2_ONLINE }, + { 0x10770, 2, RI_E1E1HE2_ONLINE }, + { 0x10780, 2, RI_E1E1HE2_ONLINE }, + { 0x10790, 2, RI_ALL_ONLINE }, + { 0x107a0, 2, RI_E1E1HE2_ONLINE }, + { 0x107b0, 2, RI_E1E1HE2_ONLINE }, + { 0x107c0, 2, RI_E1E1HE2_ONLINE }, + { 0x107d0, 2, RI_E1E1HE2_ONLINE }, + { 0x107e0, 2, RI_ALL_ONLINE }, + { 0x10880, 2, RI_ALL_ONLINE }, + { 0x10900, 2, RI_ALL_ONLINE }, + { 0x16000, 1, RI_E1HE2_ONLINE }, + { 0x16004, 25, RI_E1HE2E3E3B0_ONLINE }, + { 0x16070, 8, RI_E1HE2E3E3B0_ONLINE }, + { 0x16090, 4, RI_E1HE2E3_ONLINE }, + { 0x160a0, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x160c0, 7, RI_E1HE2E3E3B0_ONLINE }, + { 0x160dc, 2, RI_E1HE2_ONLINE }, + { 0x160e4, 10, RI_E1HE2E3E3B0_ONLINE }, + { 0x1610c, 2, RI_E1HE2_ONLINE }, + { 0x16114, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x16140, 48, RI_E1HE2E3E3B0_ONLINE }, + { 0x16204, 5, RI_E1HE2E3E3B0_ONLINE }, + { 0x18000, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x18008, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x18010, 35, RI_E2E3E3B0_ONLINE }, + { 0x180a4, 2, RI_E2E3E3B0_ONLINE }, + { 0x180c0, 9, RI_E2E3E3B0_ONLINE }, + { 0x180e4, 1, RI_E2E3_ONLINE }, + { 0x180e8, 2, RI_E2E3E3B0_ONLINE }, + { 0x180f0, 1, RI_E2E3_ONLINE }, + { 0x180f4, 79, RI_E2E3E3B0_ONLINE }, + { 0x18230, 1, RI_E2E3_ONLINE }, + { 0x18234, 2, RI_E2E3E3B0_ONLINE }, + { 0x1823c, 1, RI_E2E3_ONLINE }, + { 0x18240, 13, RI_E2E3E3B0_ONLINE }, + { 0x18274, 1, RI_E2_ONLINE }, + { 0x18278, 81, RI_E2E3E3B0_ONLINE }, + { 0x18440, 63, RI_E2E3E3B0_ONLINE }, + { 0x18570, 42, RI_E3E3B0_ONLINE }, + { 0x18618, 25, RI_E3B0_ONLINE }, + { 0x18680, 44, RI_E3B0_ONLINE }, + { 0x18748, 12, RI_E3B0_ONLINE }, + { 0x18788, 1, RI_E3B0_ONLINE }, + { 0x1879c, 6, RI_E3B0_ONLINE }, + { 0x187c4, 51, RI_E3B0_ONLINE }, + { 0x18a00, 48, RI_E3B0_ONLINE }, + { 0x20000, 24, RI_ALL_ONLINE }, + { 0x20060, 8, RI_ALL_ONLINE }, + { 0x20080, 94, RI_ALL_ONLINE }, + { 0x201f8, 1, RI_E1E1H_ONLINE }, + { 0x201fc, 1, RI_ALL_ONLINE }, + { 0x20200, 1, RI_E1E1H_ONLINE }, + { 0x20204, 1, RI_ALL_ONLINE }, + { 0x20208, 1, RI_E1E1H_ONLINE }, + { 0x2020c, 39, RI_ALL_ONLINE }, + { 0x202c8, 1, RI_E2E3E3B0_ONLINE }, + { 0x202d8, 4, RI_E2E3E3B0_ONLINE }, + { 0x202f0, 1, RI_E3B0_ONLINE }, + { 0x20400, 2, RI_ALL_ONLINE }, + { 0x2040c, 8, RI_ALL_ONLINE }, + { 0x2042c, 18, RI_E1HE2E3E3B0_ONLINE }, + { 0x20480, 1, RI_ALL_ONLINE }, + { 0x20500, 1, RI_ALL_ONLINE }, + { 0x20600, 1, RI_ALL_ONLINE }, + { 0x28000, 1, RI_ALL_ONLINE }, + { 0x28004, 8191, RI_ALL_OFFLINE }, + { 0x30000, 1, RI_ALL_ONLINE }, + { 0x30004, 16383, RI_ALL_OFFLINE }, + { 0x40000, 98, RI_ALL_ONLINE }, + { 0x401a8, 8, RI_E1HE2E3E3B0_ONLINE }, + { 0x401c8, 1, RI_E1H_ONLINE }, + { 0x401cc, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x401d4, 2, RI_E2E3E3B0_ONLINE }, + { 0x40200, 4, RI_ALL_ONLINE }, + { 0x40220, 6, RI_E2E3E3B0_ONLINE }, + { 0x40238, 8, RI_E2E3_ONLINE }, + { 0x40258, 4, RI_E2E3E3B0_ONLINE }, + { 0x40268, 2, RI_E3E3B0_ONLINE }, + { 0x40270, 17, RI_E3B0_ONLINE }, + { 0x40400, 43, RI_ALL_ONLINE }, + { 0x404cc, 3, RI_E1HE2E3E3B0_ONLINE }, + { 0x404e0, 1, RI_E2E3E3B0_ONLINE }, + { 0x40500, 2, RI_ALL_ONLINE }, + { 0x40510, 2, RI_ALL_ONLINE }, + { 0x40520, 2, RI_ALL_ONLINE }, + { 0x40530, 2, RI_ALL_ONLINE }, + { 0x40540, 2, RI_ALL_ONLINE }, + { 0x40550, 10, RI_E2E3E3B0_ONLINE }, + { 0x40610, 2, RI_E2E3E3B0_ONLINE }, + { 0x42000, 164, RI_ALL_ONLINE }, + { 0x422c0, 4, RI_E2E3E3B0_ONLINE }, + { 0x422d4, 5, RI_E1HE2E3E3B0_ONLINE }, + { 0x422e8, 1, RI_E2E3E3B0_ONLINE }, + { 0x42400, 49, RI_ALL_ONLINE }, + { 0x424c8, 38, RI_ALL_ONLINE }, + { 0x42568, 2, RI_ALL_ONLINE }, + { 0x42640, 5, RI_E2E3E3B0_ONLINE }, + { 0x42800, 1, RI_ALL_ONLINE }, + { 0x50000, 1, RI_ALL_ONLINE }, + { 0x50004, 19, RI_ALL_ONLINE }, + { 0x50050, 8, RI_ALL_ONLINE }, + { 0x50070, 88, RI_ALL_ONLINE }, + { 0x501f0, 4, RI_E1HE2E3E3B0_ONLINE }, + { 0x50200, 2, RI_ALL_ONLINE }, + { 0x5020c, 7, RI_ALL_ONLINE }, + { 0x50228, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x50240, 1, RI_ALL_ONLINE }, + { 0x50280, 1, RI_ALL_ONLINE }, + { 0x50300, 1, RI_E2E3E3B0_ONLINE }, + { 0x5030c, 1, RI_E2E3E3B0_ONLINE }, + { 0x50318, 1, RI_E2E3E3B0_ONLINE }, + { 0x5031c, 1, RI_E2E3E3B0_ONLINE }, + { 0x50320, 2, RI_E2E3E3B0_ONLINE }, + { 0x50330, 1, RI_E3B0_ONLINE }, + { 0x52000, 1, RI_ALL_ONLINE }, + { 0x54000, 1, RI_ALL_ONLINE }, + { 0x54004, 3327, RI_ALL_OFFLINE }, + { 0x58000, 1, RI_ALL_ONLINE }, + { 0x58004, 8191, RI_E1E1H_OFFLINE }, + { 0x60000, 26, RI_ALL_ONLINE }, + { 0x60068, 8, RI_E1E1H_ONLINE }, + { 0x60088, 12, RI_ALL_ONLINE }, + { 0x600b8, 9, RI_E1E1H_ONLINE }, + { 0x600dc, 1, RI_ALL_ONLINE }, + { 0x600e0, 5, RI_E1E1H_ONLINE }, + { 0x600f4, 1, RI_E1E1HE2_ONLINE }, + { 0x600f8, 1, RI_E1E1H_ONLINE }, + { 0x600fc, 8, RI_ALL_ONLINE }, + { 0x6013c, 24, RI_E1H_ONLINE }, + { 0x6019c, 2, RI_E2E3E3B0_ONLINE }, + { 0x601ac, 18, RI_E2E3E3B0_ONLINE }, + { 0x60200, 1, RI_ALL_ONLINE }, + { 0x60204, 2, RI_ALL_OFFLINE }, + { 0x60210, 13, RI_E2E3E3B0_ONLINE }, + { 0x60244, 16, RI_E3B0_ONLINE }, + { 0x61000, 1, RI_ALL_ONLINE }, + { 0x61004, 511, RI_ALL_OFFLINE }, + { 0x61800, 512, RI_E3E3B0_OFFLINE }, + { 0x70000, 8, RI_ALL_ONLINE }, + { 0x70020, 8184, RI_ALL_OFFLINE }, + { 0x78000, 8192, RI_E3E3B0_OFFLINE }, + { 0x85000, 3, RI_ALL_ONLINE }, + { 0x8501c, 7, RI_ALL_ONLINE }, + { 0x85048, 1, RI_ALL_ONLINE }, + { 0x85200, 32, RI_ALL_ONLINE }, { 0xb0000, 16384, RI_E1H_ONLINE }, - { 0xc1000, 7, RI_ALL_ONLINE }, { 0xc103c, 2, RI_E2E3_ONLINE }, - { 0xc1800, 2, RI_ALL_ONLINE }, { 0xc2000, 164, RI_ALL_ONLINE }, - { 0xc22c0, 5, RI_E2E3_ONLINE }, { 0xc22d8, 4, RI_E2E3_ONLINE }, - { 0xc2400, 49, RI_ALL_ONLINE }, { 0xc24c8, 38, RI_ALL_ONLINE }, - { 0xc2568, 2, RI_ALL_ONLINE }, { 0xc2600, 1, RI_ALL_ONLINE }, - { 0xc4000, 165, RI_ALL_ONLINE }, { 0xc42d8, 2, RI_E2E3_ONLINE }, - { 0xc42e0, 7, RI_E1HE2E3_ONLINE }, { 0xc42fc, 1, RI_E2E3_ONLINE }, - { 0xc4400, 51, RI_ALL_ONLINE }, { 0xc44d0, 38, RI_ALL_ONLINE }, - { 0xc4570, 2, RI_ALL_ONLINE }, { 0xc4578, 5, RI_E2E3_ONLINE }, - { 0xc4600, 1, RI_ALL_ONLINE }, { 0xd0000, 19, RI_ALL_ONLINE }, - { 0xd004c, 8, RI_ALL_ONLINE }, { 0xd006c, 91, RI_ALL_ONLINE }, - { 0xd01fc, 1, RI_E2E3_ONLINE }, { 0xd0200, 2, RI_ALL_ONLINE }, - { 0xd020c, 7, RI_ALL_ONLINE }, { 0xd0228, 18, RI_E1HE2E3_ONLINE }, - { 0xd0280, 1, RI_ALL_ONLINE }, { 0xd0300, 1, RI_ALL_ONLINE }, - { 0xd0400, 1, RI_ALL_ONLINE }, { 0xd4000, 1, RI_ALL_ONLINE }, - { 0xd4004, 2559, RI_ALL_OFFLINE }, { 0xd8000, 1, RI_ALL_ONLINE }, - { 0xd8004, 8191, RI_ALL_OFFLINE }, { 0xe0000, 21, RI_ALL_ONLINE }, - { 0xe0054, 8, RI_ALL_ONLINE }, { 0xe0074, 49, RI_ALL_ONLINE }, - { 0xe0138, 1, RI_E1E1H_ONLINE }, { 0xe013c, 35, RI_ALL_ONLINE }, - { 0xe01f4, 1, RI_E2_ONLINE }, { 0xe01f8, 1, RI_E2E3_ONLINE }, - { 0xe0200, 2, RI_ALL_ONLINE }, { 0xe020c, 8, RI_ALL_ONLINE }, - { 0xe022c, 18, RI_E1HE2E3_ONLINE }, { 0xe0280, 1, RI_ALL_ONLINE }, - { 0xe0300, 1, RI_ALL_ONLINE }, { 0xe1000, 1, RI_ALL_ONLINE }, - { 0xe2000, 1, RI_ALL_ONLINE }, { 0xe2004, 2047, RI_ALL_OFFLINE }, - { 0xf0000, 1, RI_ALL_ONLINE }, { 0xf0004, 16383, RI_ALL_OFFLINE }, - { 0x101000, 12, RI_ALL_ONLINE }, { 0x101050, 1, RI_E1HE2E3_ONLINE }, - { 0x101054, 3, RI_E2E3_ONLINE }, { 0x101100, 1, RI_ALL_ONLINE }, - { 0x101800, 8, RI_ALL_ONLINE }, { 0x102000, 18, RI_ALL_ONLINE }, - { 0x102068, 6, RI_E2E3_ONLINE }, { 0x102080, 17, RI_ALL_ONLINE }, - { 0x1020c8, 8, RI_E1H_ONLINE }, { 0x1020e8, 9, RI_E2E3_ONLINE }, - { 0x102400, 1, RI_ALL_ONLINE }, { 0x103000, 26, RI_ALL_ONLINE }, - { 0x103098, 5, RI_E1HE2E3_ONLINE }, { 0x1030ac, 2, RI_E2E3_ONLINE }, - { 0x1030b4, 1, RI_E2_ONLINE }, { 0x1030b8, 7, RI_E2E3_ONLINE }, - { 0x1030d8, 8, RI_E2E3_ONLINE }, { 0x103400, 1, RI_E2E3_ONLINE }, - { 0x103404, 135, RI_E2E3_OFFLINE }, { 0x103800, 8, RI_ALL_ONLINE }, - { 0x104000, 63, RI_ALL_ONLINE }, { 0x10411c, 16, RI_E2E3_ONLINE }, - { 0x104200, 17, RI_ALL_ONLINE }, { 0x104400, 64, RI_ALL_ONLINE }, - { 0x104500, 192, RI_ALL_OFFLINE }, { 0x104800, 64, RI_ALL_ONLINE }, - { 0x104900, 192, RI_ALL_OFFLINE }, { 0x105000, 256, RI_ALL_ONLINE }, - { 0x105400, 768, RI_ALL_OFFLINE }, { 0x107000, 7, RI_E2E3_ONLINE }, - { 0x10701c, 1, RI_E3_ONLINE }, { 0x108000, 33, RI_E1E1H_ONLINE }, - { 0x1080ac, 5, RI_E1H_ONLINE }, { 0x108100, 5, RI_E1E1H_ONLINE }, - { 0x108120, 5, RI_E1E1H_ONLINE }, { 0x108200, 74, RI_E1E1H_ONLINE }, - { 0x108400, 74, RI_E1E1H_ONLINE }, { 0x108800, 152, RI_E1E1H_ONLINE }, - { 0x110000, 111, RI_E2E3_ONLINE }, { 0x1101dc, 1, RI_E3_ONLINE }, - { 0x110200, 4, RI_E2E3_ONLINE }, { 0x120000, 2, RI_ALL_ONLINE }, - { 0x120008, 4, RI_ALL_ONLINE }, { 0x120018, 3, RI_ALL_ONLINE }, - { 0x120024, 4, RI_ALL_ONLINE }, { 0x120034, 3, RI_ALL_ONLINE }, - { 0x120040, 4, RI_ALL_ONLINE }, { 0x120050, 3, RI_ALL_ONLINE }, - { 0x12005c, 4, RI_ALL_ONLINE }, { 0x12006c, 3, RI_ALL_ONLINE }, - { 0x120078, 4, RI_ALL_ONLINE }, { 0x120088, 3, RI_ALL_ONLINE }, - { 0x120094, 4, RI_ALL_ONLINE }, { 0x1200a4, 3, RI_ALL_ONLINE }, - { 0x1200b0, 4, RI_ALL_ONLINE }, { 0x1200c0, 3, RI_ALL_ONLINE }, - { 0x1200cc, 4, RI_ALL_ONLINE }, { 0x1200dc, 3, RI_ALL_ONLINE }, - { 0x1200e8, 4, RI_ALL_ONLINE }, { 0x1200f8, 3, RI_ALL_ONLINE }, - { 0x120104, 4, RI_ALL_ONLINE }, { 0x120114, 1, RI_ALL_ONLINE }, - { 0x120118, 22, RI_ALL_ONLINE }, { 0x120170, 2, RI_E1E1H_ONLINE }, - { 0x120178, 243, RI_ALL_ONLINE }, { 0x120544, 4, RI_E1E1H_ONLINE }, - { 0x120554, 6, RI_ALL_ONLINE }, { 0x12059c, 6, RI_E1HE2E3_ONLINE }, - { 0x1205b4, 1, RI_E1HE2E3_ONLINE }, { 0x1205b8, 15, RI_E1HE2E3_ONLINE }, - { 0x1205f4, 1, RI_E1HE2_ONLINE }, { 0x1205f8, 4, RI_E2E3_ONLINE }, - { 0x120618, 1, RI_E2E3_ONLINE }, { 0x12061c, 20, RI_E1HE2E3_ONLINE }, - { 0x12066c, 11, RI_E1HE2E3_ONLINE }, { 0x120698, 3, RI_E2E3_ONLINE }, - { 0x1206a4, 1, RI_E2_ONLINE }, { 0x1206a8, 1, RI_E2E3_ONLINE }, - { 0x1206b0, 75, RI_E2E3_ONLINE }, { 0x1207dc, 1, RI_E2_ONLINE }, - { 0x1207fc, 1, RI_E2E3_ONLINE }, { 0x12080c, 65, RI_ALL_ONLINE }, - { 0x120910, 7, RI_E2E3_ONLINE }, { 0x120930, 9, RI_E2E3_ONLINE }, - { 0x12095c, 37, RI_E3_ONLINE }, { 0x120a00, 2, RI_E1E1HE2_ONLINE }, - { 0x120b00, 1, RI_E3_ONLINE }, { 0x122000, 2, RI_ALL_ONLINE }, - { 0x122008, 2046, RI_E1_OFFLINE }, { 0x128000, 2, RI_E1HE2E3_ONLINE }, - { 0x128008, 6142, RI_E1HE2E3_OFFLINE }, - { 0x130000, 35, RI_E2E3_ONLINE }, - { 0x130100, 29, RI_E2E3_ONLINE }, { 0x130180, 1, RI_E2E3_ONLINE }, - { 0x130200, 1, RI_E2E3_ONLINE }, { 0x130280, 1, RI_E2E3_ONLINE }, - { 0x130300, 5, RI_E2E3_ONLINE }, { 0x130380, 1, RI_E2E3_ONLINE }, - { 0x130400, 1, RI_E2E3_ONLINE }, { 0x130480, 5, RI_E2E3_ONLINE }, - { 0x130800, 72, RI_E2E3_ONLINE }, { 0x131000, 136, RI_E2E3_ONLINE }, - { 0x132000, 148, RI_E2E3_ONLINE }, { 0x134000, 544, RI_E2E3_ONLINE }, - { 0x140000, 64, RI_ALL_ONLINE }, { 0x140100, 5, RI_E1E1H_ONLINE }, - { 0x140114, 45, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE }, - { 0x140220, 4, RI_E2E3_ONLINE }, { 0x140240, 4, RI_E2E3_ONLINE }, - { 0x140260, 4, RI_E2E3_ONLINE }, { 0x140280, 4, RI_E2E3_ONLINE }, - { 0x1402a0, 4, RI_E2E3_ONLINE }, { 0x1402c0, 4, RI_E2E3_ONLINE }, - { 0x1402e0, 13, RI_E2E3_ONLINE }, { 0x144000, 4, RI_E1E1H_ONLINE }, - { 0x148000, 4, RI_E1E1H_ONLINE }, { 0x14c000, 4, RI_E1E1H_ONLINE }, - { 0x150000, 4, RI_E1E1H_ONLINE }, { 0x154000, 4, RI_E1E1H_ONLINE }, - { 0x158000, 4, RI_E1E1H_ONLINE }, { 0x15c000, 2, RI_E1HE2E3_ONLINE }, - { 0x15c008, 5, RI_E1H_ONLINE }, { 0x15c020, 27, RI_E2E3_ONLINE }, - { 0x15c090, 13, RI_E2E3_ONLINE }, { 0x15c0c8, 34, RI_E2E3_ONLINE }, - { 0x15c150, 4, RI_E3_ONLINE }, { 0x160004, 6, RI_E3_ONLINE }, - { 0x160040, 6, RI_E3_ONLINE }, { 0x16005c, 6, RI_E3_ONLINE }, - { 0x160078, 2, RI_E3_ONLINE }, { 0x160300, 8, RI_E3_ONLINE }, - { 0x160330, 6, RI_E3_ONLINE }, { 0x160404, 6, RI_E3_ONLINE }, - { 0x160440, 6, RI_E3_ONLINE }, { 0x16045c, 6, RI_E3_ONLINE }, - { 0x160478, 2, RI_E3_ONLINE }, { 0x160700, 8, RI_E3_ONLINE }, - { 0x160730, 6, RI_E3_ONLINE }, { 0x161000, 7, RI_ALL_ONLINE }, - { 0x16103c, 2, RI_E2E3_ONLINE }, { 0x161800, 2, RI_ALL_ONLINE }, - { 0x162000, 54, RI_E3_ONLINE }, { 0x162200, 60, RI_E3_ONLINE }, - { 0x162400, 54, RI_E3_ONLINE }, { 0x162600, 60, RI_E3_ONLINE }, - { 0x162800, 54, RI_E3_ONLINE }, { 0x162a00, 60, RI_E3_ONLINE }, - { 0x162c00, 54, RI_E3_ONLINE }, { 0x162e00, 60, RI_E3_ONLINE }, - { 0x163000, 1, RI_E3_ONLINE }, { 0x163008, 1, RI_E3_ONLINE }, - { 0x163010, 1, RI_E3_ONLINE }, { 0x163018, 1, RI_E3_ONLINE }, - { 0x163020, 5, RI_E3_ONLINE }, { 0x163038, 3, RI_E3_ONLINE }, - { 0x163048, 3, RI_E3_ONLINE }, { 0x163058, 1, RI_E3_ONLINE }, - { 0x163060, 1, RI_E3_ONLINE }, { 0x163068, 1, RI_E3_ONLINE }, - { 0x163070, 3, RI_E3_ONLINE }, { 0x163080, 1, RI_E3_ONLINE }, - { 0x163088, 3, RI_E3_ONLINE }, { 0x163098, 1, RI_E3_ONLINE }, - { 0x1630a0, 1, RI_E3_ONLINE }, { 0x1630a8, 1, RI_E3_ONLINE }, - { 0x1630c0, 1, RI_E3_ONLINE }, { 0x1630c8, 1, RI_E3_ONLINE }, - { 0x1630d0, 1, RI_E3_ONLINE }, { 0x1630d8, 1, RI_E3_ONLINE }, - { 0x1630e0, 2, RI_E3_ONLINE }, { 0x163110, 1, RI_E3_ONLINE }, - { 0x163120, 2, RI_E3_ONLINE }, { 0x163420, 4, RI_E3_ONLINE }, - { 0x163438, 2, RI_E3_ONLINE }, { 0x163488, 2, RI_E3_ONLINE }, - { 0x163520, 2, RI_E3_ONLINE }, { 0x163800, 1, RI_E3_ONLINE }, - { 0x163808, 1, RI_E3_ONLINE }, { 0x163810, 1, RI_E3_ONLINE }, - { 0x163818, 1, RI_E3_ONLINE }, { 0x163820, 5, RI_E3_ONLINE }, - { 0x163838, 3, RI_E3_ONLINE }, { 0x163848, 3, RI_E3_ONLINE }, - { 0x163858, 1, RI_E3_ONLINE }, { 0x163860, 1, RI_E3_ONLINE }, - { 0x163868, 1, RI_E3_ONLINE }, { 0x163870, 3, RI_E3_ONLINE }, - { 0x163880, 1, RI_E3_ONLINE }, { 0x163888, 3, RI_E3_ONLINE }, - { 0x163898, 1, RI_E3_ONLINE }, { 0x1638a0, 1, RI_E3_ONLINE }, - { 0x1638a8, 1, RI_E3_ONLINE }, { 0x1638c0, 1, RI_E3_ONLINE }, - { 0x1638c8, 1, RI_E3_ONLINE }, { 0x1638d0, 1, RI_E3_ONLINE }, - { 0x1638d8, 1, RI_E3_ONLINE }, { 0x1638e0, 2, RI_E3_ONLINE }, - { 0x163910, 1, RI_E3_ONLINE }, { 0x163920, 2, RI_E3_ONLINE }, - { 0x163c20, 4, RI_E3_ONLINE }, { 0x163c38, 2, RI_E3_ONLINE }, - { 0x163c88, 2, RI_E3_ONLINE }, { 0x163d20, 2, RI_E3_ONLINE }, - { 0x164000, 60, RI_ALL_ONLINE }, { 0x164110, 2, RI_E1HE2E3_ONLINE }, - { 0x164118, 15, RI_E2E3_ONLINE }, { 0x164200, 1, RI_ALL_ONLINE }, - { 0x164208, 1, RI_ALL_ONLINE }, { 0x164210, 1, RI_ALL_ONLINE }, - { 0x164218, 1, RI_ALL_ONLINE }, { 0x164220, 1, RI_ALL_ONLINE }, - { 0x164228, 1, RI_ALL_ONLINE }, { 0x164230, 1, RI_ALL_ONLINE }, - { 0x164238, 1, RI_ALL_ONLINE }, { 0x164240, 1, RI_ALL_ONLINE }, - { 0x164248, 1, RI_ALL_ONLINE }, { 0x164250, 1, RI_ALL_ONLINE }, - { 0x164258, 1, RI_ALL_ONLINE }, { 0x164260, 1, RI_ALL_ONLINE }, - { 0x164270, 2, RI_ALL_ONLINE }, { 0x164280, 2, RI_ALL_ONLINE }, - { 0x164800, 2, RI_ALL_ONLINE }, { 0x165000, 2, RI_ALL_ONLINE }, - { 0x166000, 164, RI_ALL_ONLINE }, { 0x1662cc, 7, RI_E2E3_ONLINE }, - { 0x166400, 49, RI_ALL_ONLINE }, { 0x1664c8, 38, RI_ALL_ONLINE }, - { 0x166568, 2, RI_ALL_ONLINE }, { 0x166570, 5, RI_E2E3_ONLINE }, - { 0x166800, 1, RI_ALL_ONLINE }, { 0x168000, 137, RI_ALL_ONLINE }, - { 0x168224, 2, RI_E1E1H_ONLINE }, { 0x16822c, 29, RI_ALL_ONLINE }, - { 0x1682a0, 12, RI_E1E1H_ONLINE }, { 0x1682d0, 12, RI_ALL_ONLINE }, - { 0x168300, 2, RI_E1E1H_ONLINE }, { 0x168308, 68, RI_ALL_ONLINE }, - { 0x168418, 2, RI_E1E1H_ONLINE }, { 0x168420, 6, RI_ALL_ONLINE }, - { 0x168800, 19, RI_ALL_ONLINE }, { 0x168900, 1, RI_ALL_ONLINE }, - { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16a000, 1, RI_ALL_ONLINE }, - { 0x16a004, 1535, RI_ALL_OFFLINE }, { 0x16c000, 1, RI_ALL_ONLINE }, - { 0x16c004, 1535, RI_ALL_OFFLINE }, { 0x16e000, 16, RI_E1H_ONLINE }, - { 0x16e040, 8, RI_E2E3_ONLINE }, { 0x16e100, 1, RI_E1H_ONLINE }, - { 0x16e200, 2, RI_E1H_ONLINE }, { 0x16e400, 161, RI_E1H_ONLINE }, - { 0x16e684, 2, RI_E1HE2E3_ONLINE }, { 0x16e68c, 12, RI_E1H_ONLINE }, - { 0x16e6bc, 4, RI_E1HE2E3_ONLINE }, { 0x16e6cc, 4, RI_E1H_ONLINE }, - { 0x16e6e0, 12, RI_E2E3_ONLINE }, { 0x16e768, 17, RI_E2E3_ONLINE }, - { 0x170000, 24, RI_ALL_ONLINE }, { 0x170060, 4, RI_E1E1H_ONLINE }, - { 0x170070, 65, RI_ALL_ONLINE }, { 0x170194, 11, RI_E2E3_ONLINE }, - { 0x1701c4, 1, RI_E2E3_ONLINE }, { 0x1701cc, 7, RI_E2E3_ONLINE }, - { 0x1701e8, 1, RI_E3_ONLINE }, { 0x1701ec, 1, RI_E2E3_ONLINE }, - { 0x1701f4, 1, RI_E2E3_ONLINE }, { 0x170200, 4, RI_ALL_ONLINE }, - { 0x170214, 1, RI_ALL_ONLINE }, { 0x170218, 77, RI_E2E3_ONLINE }, - { 0x170400, 64, RI_E2E3_ONLINE }, { 0x178000, 1, RI_ALL_ONLINE }, - { 0x180000, 61, RI_ALL_ONLINE }, { 0x18013c, 2, RI_E1HE2E3_ONLINE }, - { 0x180200, 58, RI_ALL_ONLINE }, { 0x180340, 4, RI_ALL_ONLINE }, - { 0x180380, 1, RI_E2E3_ONLINE }, { 0x180388, 1, RI_E2E3_ONLINE }, - { 0x180390, 1, RI_E2E3_ONLINE }, { 0x180398, 1, RI_E2E3_ONLINE }, - { 0x1803a0, 5, RI_E2E3_ONLINE }, { 0x1803b4, 2, RI_E3_ONLINE }, - { 0x180400, 1, RI_ALL_ONLINE }, { 0x180404, 255, RI_E1E1H_OFFLINE }, - { 0x181000, 4, RI_ALL_ONLINE }, { 0x181010, 1020, RI_ALL_OFFLINE }, - { 0x182000, 4, RI_E3_ONLINE }, { 0x1a0000, 1, RI_ALL_ONLINE }, + { 0xc1000, 7, RI_ALL_ONLINE }, + { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, + { 0xc1800, 2, RI_ALL_ONLINE }, + { 0xc2000, 164, RI_ALL_ONLINE }, + { 0xc22c0, 5, RI_E2E3E3B0_ONLINE }, + { 0xc22d8, 4, RI_E2E3E3B0_ONLINE }, + { 0xc2400, 49, RI_ALL_ONLINE }, + { 0xc24c8, 38, RI_ALL_ONLINE }, + { 0xc2568, 2, RI_ALL_ONLINE }, + { 0xc2600, 1, RI_ALL_ONLINE }, + { 0xc4000, 165, RI_ALL_ONLINE }, + { 0xc42d8, 2, RI_E2E3E3B0_ONLINE }, + { 0xc42e0, 7, RI_E1HE2E3E3B0_ONLINE }, + { 0xc42fc, 1, RI_E2E3E3B0_ONLINE }, + { 0xc4400, 51, RI_ALL_ONLINE }, + { 0xc44d0, 38, RI_ALL_ONLINE }, + { 0xc4570, 2, RI_ALL_ONLINE }, + { 0xc4578, 5, RI_E2E3E3B0_ONLINE }, + { 0xc4600, 1, RI_ALL_ONLINE }, + { 0xd0000, 19, RI_ALL_ONLINE }, + { 0xd004c, 8, RI_ALL_ONLINE }, + { 0xd006c, 91, RI_ALL_ONLINE }, + { 0xd01fc, 1, RI_E2E3E3B0_ONLINE }, + { 0xd0200, 2, RI_ALL_ONLINE }, + { 0xd020c, 7, RI_ALL_ONLINE }, + { 0xd0228, 18, RI_E1HE2E3E3B0_ONLINE }, + { 0xd0280, 1, RI_ALL_ONLINE }, + { 0xd0300, 1, RI_ALL_ONLINE }, + { 0xd0400, 1, RI_ALL_ONLINE }, + { 0xd0818, 1, RI_E3B0_ONLINE }, + { 0xd4000, 1, RI_ALL_ONLINE }, + { 0xd4004, 2559, RI_ALL_OFFLINE }, + { 0xd8000, 1, RI_ALL_ONLINE }, + { 0xd8004, 8191, RI_ALL_OFFLINE }, + { 0xe0000, 21, RI_ALL_ONLINE }, + { 0xe0054, 8, RI_ALL_ONLINE }, + { 0xe0074, 49, RI_ALL_ONLINE }, + { 0xe0138, 1, RI_E1E1H_ONLINE }, + { 0xe013c, 35, RI_ALL_ONLINE }, + { 0xe01f4, 1, RI_E2_ONLINE }, + { 0xe01f8, 1, RI_E2E3E3B0_ONLINE }, + { 0xe0200, 2, RI_ALL_ONLINE }, + { 0xe020c, 8, RI_ALL_ONLINE }, + { 0xe022c, 18, RI_E1HE2E3E3B0_ONLINE }, + { 0xe0280, 1, RI_ALL_ONLINE }, + { 0xe0300, 1, RI_ALL_ONLINE }, + { 0xe0400, 1, RI_E3B0_ONLINE }, + { 0xe1000, 1, RI_ALL_ONLINE }, + { 0xe2000, 1, RI_ALL_ONLINE }, + { 0xe2004, 2047, RI_ALL_OFFLINE }, + { 0xf0000, 1, RI_ALL_ONLINE }, + { 0xf0004, 16383, RI_ALL_OFFLINE }, + { 0x101000, 12, RI_ALL_ONLINE }, + { 0x101050, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x101054, 3, RI_E2E3E3B0_ONLINE }, + { 0x101100, 1, RI_ALL_ONLINE }, + { 0x101800, 8, RI_ALL_ONLINE }, + { 0x102000, 18, RI_ALL_ONLINE }, + { 0x102068, 6, RI_E2E3E3B0_ONLINE }, + { 0x102080, 17, RI_ALL_ONLINE }, + { 0x1020c8, 8, RI_E1H_ONLINE }, + { 0x1020e8, 9, RI_E2E3E3B0_ONLINE }, + { 0x102400, 1, RI_ALL_ONLINE }, + { 0x103000, 26, RI_ALL_ONLINE }, + { 0x103098, 5, RI_E1HE2E3E3B0_ONLINE }, + { 0x1030ac, 2, RI_E2E3E3B0_ONLINE }, + { 0x1030b4, 1, RI_E2_ONLINE }, + { 0x1030b8, 7, RI_E2E3E3B0_ONLINE }, + { 0x1030d8, 8, RI_E2E3E3B0_ONLINE }, + { 0x103400, 1, RI_E2E3E3B0_ONLINE }, + { 0x103404, 135, RI_E2E3E3B0_OFFLINE }, + { 0x103800, 8, RI_ALL_ONLINE }, + { 0x104000, 63, RI_ALL_ONLINE }, + { 0x10411c, 16, RI_E2E3E3B0_ONLINE }, + { 0x104200, 17, RI_ALL_ONLINE }, + { 0x104400, 64, RI_ALL_ONLINE }, + { 0x104500, 192, RI_ALL_OFFLINE }, + { 0x104800, 64, RI_ALL_ONLINE }, + { 0x104900, 192, RI_ALL_OFFLINE }, + { 0x105000, 256, RI_ALL_ONLINE }, + { 0x105400, 768, RI_ALL_OFFLINE }, + { 0x107000, 7, RI_E2E3E3B0_ONLINE }, + { 0x10701c, 1, RI_E3E3B0_ONLINE }, + { 0x108000, 33, RI_E1E1H_ONLINE }, + { 0x1080ac, 5, RI_E1H_ONLINE }, + { 0x108100, 5, RI_E1E1H_ONLINE }, + { 0x108120, 5, RI_E1E1H_ONLINE }, + { 0x108200, 74, RI_E1E1H_ONLINE }, + { 0x108400, 74, RI_E1E1H_ONLINE }, + { 0x108800, 152, RI_E1E1H_ONLINE }, + { 0x110000, 111, RI_E2E3E3B0_ONLINE }, + { 0x1101dc, 1, RI_E3E3B0_ONLINE }, + { 0x110200, 4, RI_E2E3E3B0_ONLINE }, + { 0x120000, 2, RI_ALL_ONLINE }, + { 0x120008, 4, RI_ALL_ONLINE }, + { 0x120018, 3, RI_ALL_ONLINE }, + { 0x120024, 4, RI_ALL_ONLINE }, + { 0x120034, 3, RI_ALL_ONLINE }, + { 0x120040, 4, RI_ALL_ONLINE }, + { 0x120050, 3, RI_ALL_ONLINE }, + { 0x12005c, 4, RI_ALL_ONLINE }, + { 0x12006c, 3, RI_ALL_ONLINE }, + { 0x120078, 4, RI_ALL_ONLINE }, + { 0x120088, 3, RI_ALL_ONLINE }, + { 0x120094, 4, RI_ALL_ONLINE }, + { 0x1200a4, 3, RI_ALL_ONLINE }, + { 0x1200b0, 4, RI_ALL_ONLINE }, + { 0x1200c0, 3, RI_ALL_ONLINE }, + { 0x1200cc, 4, RI_ALL_ONLINE }, + { 0x1200dc, 3, RI_ALL_ONLINE }, + { 0x1200e8, 4, RI_ALL_ONLINE }, + { 0x1200f8, 3, RI_ALL_ONLINE }, + { 0x120104, 4, RI_ALL_ONLINE }, + { 0x120114, 1, RI_ALL_ONLINE }, + { 0x120118, 22, RI_ALL_ONLINE }, + { 0x120170, 2, RI_E1E1H_ONLINE }, + { 0x120178, 243, RI_ALL_ONLINE }, + { 0x120544, 4, RI_E1E1H_ONLINE }, + { 0x120554, 6, RI_ALL_ONLINE }, + { 0x12059c, 6, RI_E1HE2E3E3B0_ONLINE }, + { 0x1205b4, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1205b8, 15, RI_E1HE2E3E3B0_ONLINE }, + { 0x1205f4, 1, RI_E1HE2_ONLINE }, + { 0x1205f8, 4, RI_E2E3E3B0_ONLINE }, + { 0x120618, 1, RI_E2E3E3B0_ONLINE }, + { 0x12061c, 20, RI_E1HE2E3E3B0_ONLINE }, + { 0x12066c, 11, RI_E1HE2E3E3B0_ONLINE }, + { 0x120698, 3, RI_E2E3E3B0_ONLINE }, + { 0x1206a4, 1, RI_E2_ONLINE }, + { 0x1206a8, 1, RI_E2E3E3B0_ONLINE }, + { 0x1206b0, 75, RI_E2E3E3B0_ONLINE }, + { 0x1207dc, 1, RI_E2_ONLINE }, + { 0x1207fc, 1, RI_E2E3E3B0_ONLINE }, + { 0x12080c, 65, RI_ALL_ONLINE }, + { 0x120910, 7, RI_E2E3E3B0_ONLINE }, + { 0x120930, 9, RI_E2E3E3B0_ONLINE }, + { 0x12095c, 37, RI_E3E3B0_ONLINE }, + { 0x120a00, 2, RI_E1E1HE2_ONLINE }, + { 0x120b00, 1, RI_E3E3B0_ONLINE }, + { 0x122000, 2, RI_ALL_ONLINE }, + { 0x122008, 2046, RI_E1_OFFLINE }, + { 0x128000, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x128008, 6142, RI_E1HE2E3E3B0_OFFLINE }, + { 0x130000, 35, RI_E2E3E3B0_ONLINE }, + { 0x130100, 29, RI_E2E3E3B0_ONLINE }, + { 0x130180, 1, RI_E2E3E3B0_ONLINE }, + { 0x130200, 1, RI_E2E3E3B0_ONLINE }, + { 0x130280, 1, RI_E2E3E3B0_ONLINE }, + { 0x130300, 5, RI_E2E3E3B0_ONLINE }, + { 0x130380, 1, RI_E2E3E3B0_ONLINE }, + { 0x130400, 1, RI_E2E3E3B0_ONLINE }, + { 0x130480, 5, RI_E2E3E3B0_ONLINE }, + { 0x130800, 72, RI_E2E3E3B0_ONLINE }, + { 0x131000, 136, RI_E2E3E3B0_ONLINE }, + { 0x132000, 148, RI_E2E3E3B0_ONLINE }, + { 0x134000, 544, RI_E2E3E3B0_ONLINE }, + { 0x140000, 1, RI_ALL_ONLINE }, + { 0x140004, 9, RI_E1E1HE2E3_ONLINE }, + { 0x140028, 8, RI_ALL_ONLINE }, + { 0x140048, 10, RI_E1E1HE2E3_ONLINE }, + { 0x140070, 1, RI_ALL_ONLINE }, + { 0x140074, 10, RI_E1E1HE2E3_ONLINE }, + { 0x14009c, 1, RI_ALL_ONLINE }, + { 0x1400a0, 5, RI_E1E1HE2E3_ONLINE }, + { 0x1400b4, 7, RI_ALL_ONLINE }, + { 0x1400d0, 10, RI_E1E1HE2E3_ONLINE }, + { 0x1400f8, 2, RI_ALL_ONLINE }, + { 0x140100, 5, RI_E1E1H_ONLINE }, + { 0x140114, 5, RI_E1E1HE2E3_ONLINE }, + { 0x140128, 7, RI_ALL_ONLINE }, + { 0x140144, 9, RI_E1E1HE2E3_ONLINE }, + { 0x140168, 8, RI_ALL_ONLINE }, + { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, + { 0x140194, 13, RI_ALL_ONLINE }, + { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, + { 0x140220, 4, RI_E2E3_ONLINE }, + { 0x140240, 4, RI_E2E3_ONLINE }, + { 0x140260, 4, RI_E2E3_ONLINE }, + { 0x140280, 4, RI_E2E3_ONLINE }, + { 0x1402a0, 4, RI_E2E3_ONLINE }, + { 0x1402c0, 4, RI_E2E3_ONLINE }, + { 0x1402e0, 2, RI_E2E3_ONLINE }, + { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, + { 0x1402f0, 9, RI_E2E3_ONLINE }, + { 0x140314, 44, RI_E3B0_ONLINE }, + { 0x1403d0, 70, RI_E3B0_ONLINE }, + { 0x144000, 4, RI_E1E1H_ONLINE }, + { 0x148000, 4, RI_E1E1H_ONLINE }, + { 0x14c000, 4, RI_E1E1H_ONLINE }, + { 0x150000, 4, RI_E1E1H_ONLINE }, + { 0x154000, 4, RI_E1E1H_ONLINE }, + { 0x158000, 4, RI_E1E1H_ONLINE }, + { 0x15c000, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x15c008, 5, RI_E1H_ONLINE }, + { 0x15c020, 8, RI_E2E3E3B0_ONLINE }, + { 0x15c040, 1, RI_E2E3_ONLINE }, + { 0x15c044, 2, RI_E2E3E3B0_ONLINE }, + { 0x15c04c, 8, RI_E2E3_ONLINE }, + { 0x15c06c, 8, RI_E2E3E3B0_ONLINE }, + { 0x15c090, 13, RI_E2E3E3B0_ONLINE }, + { 0x15c0c8, 24, RI_E2E3E3B0_ONLINE }, + { 0x15c128, 2, RI_E2E3_ONLINE }, + { 0x15c130, 8, RI_E2E3E3B0_ONLINE }, + { 0x15c150, 2, RI_E3E3B0_ONLINE }, + { 0x15c158, 2, RI_E3_ONLINE }, + { 0x15c160, 149, RI_E3B0_ONLINE }, + { 0x161000, 7, RI_ALL_ONLINE }, + { 0x16103c, 2, RI_E2E3E3B0_ONLINE }, + { 0x161800, 2, RI_ALL_ONLINE }, + { 0x162000, 54, RI_E3E3B0_ONLINE }, + { 0x162200, 60, RI_E3E3B0_ONLINE }, + { 0x162400, 54, RI_E3E3B0_ONLINE }, + { 0x162600, 60, RI_E3E3B0_ONLINE }, + { 0x162800, 54, RI_E3E3B0_ONLINE }, + { 0x162a00, 60, RI_E3E3B0_ONLINE }, + { 0x162c00, 54, RI_E3E3B0_ONLINE }, + { 0x162e00, 60, RI_E3E3B0_ONLINE }, + { 0x164000, 60, RI_ALL_ONLINE }, + { 0x164110, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x164118, 15, RI_E2E3E3B0_ONLINE }, + { 0x164200, 1, RI_ALL_ONLINE }, + { 0x164208, 1, RI_ALL_ONLINE }, + { 0x164210, 1, RI_ALL_ONLINE }, + { 0x164218, 1, RI_ALL_ONLINE }, + { 0x164220, 1, RI_ALL_ONLINE }, + { 0x164228, 1, RI_ALL_ONLINE }, + { 0x164230, 1, RI_ALL_ONLINE }, + { 0x164238, 1, RI_ALL_ONLINE }, + { 0x164240, 1, RI_ALL_ONLINE }, + { 0x164248, 1, RI_ALL_ONLINE }, + { 0x164250, 1, RI_ALL_ONLINE }, + { 0x164258, 1, RI_ALL_ONLINE }, + { 0x164260, 1, RI_ALL_ONLINE }, + { 0x164270, 2, RI_ALL_ONLINE }, + { 0x164280, 2, RI_ALL_ONLINE }, + { 0x164800, 2, RI_ALL_ONLINE }, + { 0x165000, 2, RI_ALL_ONLINE }, + { 0x166000, 164, RI_ALL_ONLINE }, + { 0x1662cc, 7, RI_E2E3E3B0_ONLINE }, + { 0x166400, 49, RI_ALL_ONLINE }, + { 0x1664c8, 38, RI_ALL_ONLINE }, + { 0x166568, 2, RI_ALL_ONLINE }, + { 0x166570, 5, RI_E2E3E3B0_ONLINE }, + { 0x166800, 1, RI_ALL_ONLINE }, + { 0x168000, 137, RI_ALL_ONLINE }, + { 0x168224, 2, RI_E1E1H_ONLINE }, + { 0x16822c, 29, RI_ALL_ONLINE }, + { 0x1682a0, 12, RI_E1E1H_ONLINE }, + { 0x1682d0, 12, RI_ALL_ONLINE }, + { 0x168300, 2, RI_E1E1H_ONLINE }, + { 0x168308, 68, RI_ALL_ONLINE }, + { 0x168418, 2, RI_E1E1H_ONLINE }, + { 0x168420, 6, RI_ALL_ONLINE }, + { 0x168800, 19, RI_ALL_ONLINE }, + { 0x168900, 1, RI_ALL_ONLINE }, + { 0x168a00, 128, RI_ALL_ONLINE }, + { 0x16a000, 1, RI_ALL_ONLINE }, + { 0x16a004, 1535, RI_ALL_OFFLINE }, + { 0x16c000, 1, RI_ALL_ONLINE }, + { 0x16c004, 1535, RI_ALL_OFFLINE }, + { 0x16e000, 16, RI_E1H_ONLINE }, + { 0x16e040, 8, RI_E2E3E3B0_ONLINE }, + { 0x16e100, 1, RI_E1H_ONLINE }, + { 0x16e200, 2, RI_E1H_ONLINE }, + { 0x16e400, 161, RI_E1H_ONLINE }, + { 0x16e684, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x16e68c, 12, RI_E1H_ONLINE }, + { 0x16e6bc, 4, RI_E1HE2E3E3B0_ONLINE }, + { 0x16e6cc, 4, RI_E1H_ONLINE }, + { 0x16e6e0, 2, RI_E2E3E3B0_ONLINE }, + { 0x16e6e8, 5, RI_E2E3_ONLINE }, + { 0x16e6fc, 5, RI_E2E3E3B0_ONLINE }, + { 0x16e768, 17, RI_E2E3E3B0_ONLINE }, + { 0x16e7ac, 12, RI_E3B0_ONLINE }, + { 0x170000, 24, RI_ALL_ONLINE }, + { 0x170060, 4, RI_E1E1H_ONLINE }, + { 0x170070, 65, RI_ALL_ONLINE }, + { 0x170194, 11, RI_E2E3E3B0_ONLINE }, + { 0x1701c4, 1, RI_E2E3E3B0_ONLINE }, + { 0x1701cc, 7, RI_E2E3E3B0_ONLINE }, + { 0x1701e8, 1, RI_E3E3B0_ONLINE }, + { 0x1701ec, 1, RI_E2E3E3B0_ONLINE }, + { 0x1701f4, 1, RI_E2E3E3B0_ONLINE }, + { 0x170200, 4, RI_ALL_ONLINE }, + { 0x170214, 1, RI_ALL_ONLINE }, + { 0x170218, 77, RI_E2E3E3B0_ONLINE }, + { 0x170400, 64, RI_E2E3E3B0_ONLINE }, + { 0x178000, 1, RI_ALL_ONLINE }, + { 0x180000, 61, RI_ALL_ONLINE }, + { 0x18013c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x180200, 58, RI_ALL_ONLINE }, + { 0x180340, 4, RI_ALL_ONLINE }, + { 0x180380, 1, RI_E2E3E3B0_ONLINE }, + { 0x180388, 1, RI_E2E3E3B0_ONLINE }, + { 0x180390, 1, RI_E2E3E3B0_ONLINE }, + { 0x180398, 1, RI_E2E3E3B0_ONLINE }, + { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, + { 0x1803b4, 2, RI_E3E3B0_ONLINE }, + { 0x180400, 1, RI_ALL_ONLINE }, + { 0x180404, 255, RI_E1E1H_OFFLINE }, + { 0x181000, 4, RI_ALL_ONLINE }, + { 0x181010, 1020, RI_ALL_OFFLINE }, + { 0x182000, 4, RI_E3E3B0_ONLINE }, + { 0x1a0000, 1, RI_ALL_ONLINE }, { 0x1a0004, 5631, RI_ALL_OFFLINE }, - { 0x1a5800, 2560, RI_E1HE2E3_OFFLINE }, - { 0x1a8000, 1, RI_ALL_ONLINE }, { 0x1a8004, 8191, RI_E1HE2E3_OFFLINE }, - { 0x1b0000, 1, RI_ALL_ONLINE }, { 0x1b0004, 15, RI_E1H_OFFLINE }, - { 0x1b0040, 1, RI_E1HE2E3_ONLINE }, { 0x1b0044, 239, RI_E1H_OFFLINE }, - { 0x1b0400, 1, RI_ALL_ONLINE }, { 0x1b0404, 255, RI_E1H_OFFLINE }, - { 0x1b0800, 1, RI_ALL_ONLINE }, { 0x1b0840, 1, RI_E1HE2E3_ONLINE }, - { 0x1b0c00, 1, RI_ALL_ONLINE }, { 0x1b1000, 1, RI_ALL_ONLINE }, - { 0x1b1040, 1, RI_E1HE2E3_ONLINE }, { 0x1b1400, 1, RI_ALL_ONLINE }, - { 0x1b1440, 1, RI_E1HE2E3_ONLINE }, { 0x1b1480, 1, RI_E1HE2E3_ONLINE }, - { 0x1b14c0, 1, RI_E1HE2E3_ONLINE }, { 0x1b1800, 128, RI_ALL_OFFLINE }, - { 0x1b1c00, 128, RI_ALL_OFFLINE }, { 0x1b2000, 1, RI_ALL_ONLINE }, - { 0x1b2400, 1, RI_E1HE2E3_ONLINE }, { 0x1b2404, 5631, RI_E2E3_OFFLINE }, - { 0x1b8000, 1, RI_ALL_ONLINE }, { 0x1b8040, 1, RI_ALL_ONLINE }, - { 0x1b8080, 1, RI_ALL_ONLINE }, { 0x1b80c0, 1, RI_ALL_ONLINE }, - { 0x1b8100, 1, RI_ALL_ONLINE }, { 0x1b8140, 1, RI_ALL_ONLINE }, - { 0x1b8180, 1, RI_ALL_ONLINE }, { 0x1b81c0, 1, RI_ALL_ONLINE }, - { 0x1b8200, 1, RI_ALL_ONLINE }, { 0x1b8240, 1, RI_ALL_ONLINE }, - { 0x1b8280, 1, RI_ALL_ONLINE }, { 0x1b82c0, 1, RI_ALL_ONLINE }, - { 0x1b8300, 1, RI_ALL_ONLINE }, { 0x1b8340, 1, RI_ALL_ONLINE }, - { 0x1b8380, 1, RI_ALL_ONLINE }, { 0x1b83c0, 1, RI_ALL_ONLINE }, - { 0x1b8400, 1, RI_ALL_ONLINE }, { 0x1b8440, 1, RI_ALL_ONLINE }, - { 0x1b8480, 1, RI_ALL_ONLINE }, { 0x1b84c0, 1, RI_ALL_ONLINE }, - { 0x1b8500, 1, RI_ALL_ONLINE }, { 0x1b8540, 1, RI_ALL_ONLINE }, - { 0x1b8580, 1, RI_ALL_ONLINE }, { 0x1b85c0, 19, RI_E2E3_ONLINE }, - { 0x1b8800, 1, RI_ALL_ONLINE }, { 0x1b8840, 1, RI_ALL_ONLINE }, - { 0x1b8880, 1, RI_ALL_ONLINE }, { 0x1b88c0, 1, RI_ALL_ONLINE }, - { 0x1b8900, 1, RI_ALL_ONLINE }, { 0x1b8940, 1, RI_ALL_ONLINE }, - { 0x1b8980, 1, RI_ALL_ONLINE }, { 0x1b89c0, 1, RI_ALL_ONLINE }, - { 0x1b8a00, 1, RI_ALL_ONLINE }, { 0x1b8a40, 1, RI_ALL_ONLINE }, - { 0x1b8a80, 1, RI_ALL_ONLINE }, { 0x1b8ac0, 1, RI_ALL_ONLINE }, - { 0x1b8b00, 1, RI_ALL_ONLINE }, { 0x1b8b40, 1, RI_ALL_ONLINE }, - { 0x1b8b80, 1, RI_ALL_ONLINE }, { 0x1b8bc0, 1, RI_ALL_ONLINE }, - { 0x1b8c00, 1, RI_ALL_ONLINE }, { 0x1b8c40, 1, RI_ALL_ONLINE }, - { 0x1b8c80, 1, RI_ALL_ONLINE }, { 0x1b8cc0, 1, RI_ALL_ONLINE }, - { 0x1b8cc4, 1, RI_E2E3_ONLINE }, { 0x1b8d00, 1, RI_ALL_ONLINE }, - { 0x1b8d40, 1, RI_ALL_ONLINE }, { 0x1b8d80, 1, RI_ALL_ONLINE }, - { 0x1b8dc0, 1, RI_ALL_ONLINE }, { 0x1b8e00, 1, RI_ALL_ONLINE }, - { 0x1b8e40, 1, RI_ALL_ONLINE }, { 0x1b8e80, 1, RI_ALL_ONLINE }, - { 0x1b8e84, 1, RI_E2E3_ONLINE }, { 0x1b8ec0, 1, RI_E1HE2E3_ONLINE }, - { 0x1b8f00, 1, RI_E1HE2E3_ONLINE }, { 0x1b8f40, 1, RI_E1HE2E3_ONLINE }, - { 0x1b8f80, 1, RI_E1HE2E3_ONLINE }, { 0x1b8fc0, 1, RI_E1HE2E3_ONLINE }, - { 0x1b8fc4, 2, RI_E2E3_ONLINE }, { 0x1b8fd0, 6, RI_E2E3_ONLINE }, - { 0x1b8fe8, 2, RI_E3_ONLINE }, { 0x1b9000, 1, RI_E2E3_ONLINE }, - { 0x1b9040, 3, RI_E2E3_ONLINE }, { 0x1b905c, 1, RI_E3_ONLINE }, - { 0x1b9400, 14, RI_E2E3_ONLINE }, { 0x1b943c, 19, RI_E2E3_ONLINE }, - { 0x1b9490, 10, RI_E2E3_ONLINE }, { 0x1c0000, 2, RI_ALL_ONLINE }, - { 0x200000, 65, RI_ALL_ONLINE }, { 0x20014c, 2, RI_E1HE2E3_ONLINE }, - { 0x200200, 58, RI_ALL_ONLINE }, { 0x200340, 4, RI_ALL_ONLINE }, - { 0x200380, 1, RI_E2E3_ONLINE }, { 0x200388, 1, RI_E2E3_ONLINE }, - { 0x200390, 1, RI_E2E3_ONLINE }, { 0x200398, 1, RI_E2E3_ONLINE }, - { 0x2003a0, 1, RI_E2E3_ONLINE }, { 0x2003a8, 2, RI_E2E3_ONLINE }, - { 0x200400, 1, RI_ALL_ONLINE }, { 0x200404, 255, RI_E1E1H_OFFLINE }, - { 0x202000, 4, RI_ALL_ONLINE }, { 0x202010, 2044, RI_ALL_OFFLINE }, - { 0x204000, 4, RI_E3_ONLINE }, { 0x220000, 1, RI_ALL_ONLINE }, + { 0x1a5800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x1a8000, 1, RI_ALL_ONLINE }, + { 0x1a8004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x1b0000, 1, RI_ALL_ONLINE }, + { 0x1b0004, 15, RI_E1H_OFFLINE }, + { 0x1b0040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b0044, 239, RI_E1H_OFFLINE }, + { 0x1b0400, 1, RI_ALL_ONLINE }, + { 0x1b0404, 255, RI_E1H_OFFLINE }, + { 0x1b0800, 1, RI_ALL_ONLINE }, + { 0x1b0840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b0c00, 1, RI_ALL_ONLINE }, + { 0x1b1000, 1, RI_ALL_ONLINE }, + { 0x1b1040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b1400, 1, RI_ALL_ONLINE }, + { 0x1b1440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b1480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b14c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b1800, 128, RI_ALL_OFFLINE }, + { 0x1b1c00, 128, RI_ALL_OFFLINE }, + { 0x1b2000, 1, RI_ALL_ONLINE }, + { 0x1b2400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b2404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x1b8000, 1, RI_ALL_ONLINE }, + { 0x1b8040, 1, RI_ALL_ONLINE }, + { 0x1b8080, 1, RI_ALL_ONLINE }, + { 0x1b80c0, 1, RI_ALL_ONLINE }, + { 0x1b8100, 1, RI_ALL_ONLINE }, + { 0x1b8140, 1, RI_ALL_ONLINE }, + { 0x1b8180, 1, RI_ALL_ONLINE }, + { 0x1b81c0, 1, RI_ALL_ONLINE }, + { 0x1b8200, 1, RI_ALL_ONLINE }, + { 0x1b8240, 1, RI_ALL_ONLINE }, + { 0x1b8280, 1, RI_ALL_ONLINE }, + { 0x1b82c0, 1, RI_ALL_ONLINE }, + { 0x1b8300, 1, RI_ALL_ONLINE }, + { 0x1b8340, 1, RI_ALL_ONLINE }, + { 0x1b8380, 1, RI_ALL_ONLINE }, + { 0x1b83c0, 1, RI_ALL_ONLINE }, + { 0x1b8400, 1, RI_ALL_ONLINE }, + { 0x1b8440, 1, RI_ALL_ONLINE }, + { 0x1b8480, 1, RI_ALL_ONLINE }, + { 0x1b84c0, 1, RI_ALL_ONLINE }, + { 0x1b8500, 1, RI_ALL_ONLINE }, + { 0x1b8540, 1, RI_ALL_ONLINE }, + { 0x1b8580, 1, RI_ALL_ONLINE }, + { 0x1b85c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x1b8800, 1, RI_ALL_ONLINE }, + { 0x1b8840, 1, RI_ALL_ONLINE }, + { 0x1b8880, 1, RI_ALL_ONLINE }, + { 0x1b88c0, 1, RI_ALL_ONLINE }, + { 0x1b8900, 1, RI_ALL_ONLINE }, + { 0x1b8940, 1, RI_ALL_ONLINE }, + { 0x1b8980, 1, RI_ALL_ONLINE }, + { 0x1b89c0, 1, RI_ALL_ONLINE }, + { 0x1b8a00, 1, RI_ALL_ONLINE }, + { 0x1b8a40, 1, RI_ALL_ONLINE }, + { 0x1b8a80, 1, RI_ALL_ONLINE }, + { 0x1b8ac0, 1, RI_ALL_ONLINE }, + { 0x1b8b00, 1, RI_ALL_ONLINE }, + { 0x1b8b40, 1, RI_ALL_ONLINE }, + { 0x1b8b80, 1, RI_ALL_ONLINE }, + { 0x1b8bc0, 1, RI_ALL_ONLINE }, + { 0x1b8c00, 1, RI_ALL_ONLINE }, + { 0x1b8c40, 1, RI_ALL_ONLINE }, + { 0x1b8c80, 1, RI_ALL_ONLINE }, + { 0x1b8cc0, 1, RI_ALL_ONLINE }, + { 0x1b8cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x1b8d00, 1, RI_ALL_ONLINE }, + { 0x1b8d40, 1, RI_ALL_ONLINE }, + { 0x1b8d80, 1, RI_ALL_ONLINE }, + { 0x1b8dc0, 1, RI_ALL_ONLINE }, + { 0x1b8e00, 1, RI_ALL_ONLINE }, + { 0x1b8e40, 1, RI_ALL_ONLINE }, + { 0x1b8e80, 1, RI_ALL_ONLINE }, + { 0x1b8e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x1b8ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x1b8fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x1b8fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x1b8fe8, 2, RI_E3E3B0_ONLINE }, + { 0x1b9000, 1, RI_E2E3E3B0_ONLINE }, + { 0x1b9040, 3, RI_E2E3E3B0_ONLINE }, + { 0x1b905c, 1, RI_E3E3B0_ONLINE }, + { 0x1b9064, 1, RI_E3B0_ONLINE }, + { 0x1b9080, 10, RI_E3B0_ONLINE }, + { 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, + { 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, + { 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, + { 0x1c0000, 2, RI_ALL_ONLINE }, + { 0x200000, 65, RI_ALL_ONLINE }, + { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x200200, 58, RI_ALL_ONLINE }, + { 0x200340, 4, RI_ALL_ONLINE }, + { 0x200380, 1, RI_E2E3E3B0_ONLINE }, + { 0x200388, 1, RI_E2E3E3B0_ONLINE }, + { 0x200390, 1, RI_E2E3E3B0_ONLINE }, + { 0x200398, 1, RI_E2E3E3B0_ONLINE }, + { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, + { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, + { 0x200400, 1, RI_ALL_ONLINE }, + { 0x200404, 255, RI_E1E1H_OFFLINE }, + { 0x202000, 4, RI_ALL_ONLINE }, + { 0x202010, 2044, RI_ALL_OFFLINE }, + { 0x204000, 4, RI_E3E3B0_ONLINE }, + { 0x220000, 1, RI_ALL_ONLINE }, { 0x220004, 5631, RI_ALL_OFFLINE }, - { 0x225800, 2560, RI_E1HE2E3_OFFLINE }, - { 0x228000, 1, RI_ALL_ONLINE }, { 0x228004, 8191, RI_E1HE2E3_OFFLINE }, - { 0x230000, 1, RI_ALL_ONLINE }, { 0x230004, 15, RI_E1H_OFFLINE }, - { 0x230040, 1, RI_E1HE2E3_ONLINE }, { 0x230044, 239, RI_E1H_OFFLINE }, - { 0x230400, 1, RI_ALL_ONLINE }, { 0x230404, 255, RI_E1H_OFFLINE }, - { 0x230800, 1, RI_ALL_ONLINE }, { 0x230840, 1, RI_E1HE2E3_ONLINE }, - { 0x230c00, 1, RI_ALL_ONLINE }, { 0x231000, 1, RI_ALL_ONLINE }, - { 0x231040, 1, RI_E1HE2E3_ONLINE }, { 0x231400, 1, RI_ALL_ONLINE }, - { 0x231440, 1, RI_E1HE2E3_ONLINE }, { 0x231480, 1, RI_E1HE2E3_ONLINE }, - { 0x2314c0, 1, RI_E1HE2E3_ONLINE }, { 0x231800, 128, RI_ALL_OFFLINE }, - { 0x231c00, 128, RI_ALL_OFFLINE }, { 0x232000, 1, RI_ALL_ONLINE }, - { 0x232400, 1, RI_E1HE2E3_ONLINE }, { 0x232404, 5631, RI_E2E3_OFFLINE }, - { 0x238000, 1, RI_ALL_ONLINE }, { 0x238040, 1, RI_ALL_ONLINE }, - { 0x238080, 1, RI_ALL_ONLINE }, { 0x2380c0, 1, RI_ALL_ONLINE }, - { 0x238100, 1, RI_ALL_ONLINE }, { 0x238140, 1, RI_ALL_ONLINE }, - { 0x238180, 1, RI_ALL_ONLINE }, { 0x2381c0, 1, RI_ALL_ONLINE }, - { 0x238200, 1, RI_ALL_ONLINE }, { 0x238240, 1, RI_ALL_ONLINE }, - { 0x238280, 1, RI_ALL_ONLINE }, { 0x2382c0, 1, RI_ALL_ONLINE }, - { 0x238300, 1, RI_ALL_ONLINE }, { 0x238340, 1, RI_ALL_ONLINE }, - { 0x238380, 1, RI_ALL_ONLINE }, { 0x2383c0, 1, RI_ALL_ONLINE }, - { 0x238400, 1, RI_ALL_ONLINE }, { 0x238440, 1, RI_ALL_ONLINE }, - { 0x238480, 1, RI_ALL_ONLINE }, { 0x2384c0, 1, RI_ALL_ONLINE }, - { 0x238500, 1, RI_ALL_ONLINE }, { 0x238540, 1, RI_ALL_ONLINE }, - { 0x238580, 1, RI_ALL_ONLINE }, { 0x2385c0, 19, RI_E2E3_ONLINE }, - { 0x238800, 1, RI_ALL_ONLINE }, { 0x238840, 1, RI_ALL_ONLINE }, - { 0x238880, 1, RI_ALL_ONLINE }, { 0x2388c0, 1, RI_ALL_ONLINE }, - { 0x238900, 1, RI_ALL_ONLINE }, { 0x238940, 1, RI_ALL_ONLINE }, - { 0x238980, 1, RI_ALL_ONLINE }, { 0x2389c0, 1, RI_ALL_ONLINE }, - { 0x238a00, 1, RI_ALL_ONLINE }, { 0x238a40, 1, RI_ALL_ONLINE }, - { 0x238a80, 1, RI_ALL_ONLINE }, { 0x238ac0, 1, RI_ALL_ONLINE }, - { 0x238b00, 1, RI_ALL_ONLINE }, { 0x238b40, 1, RI_ALL_ONLINE }, - { 0x238b80, 1, RI_ALL_ONLINE }, { 0x238bc0, 1, RI_ALL_ONLINE }, - { 0x238c00, 1, RI_ALL_ONLINE }, { 0x238c40, 1, RI_ALL_ONLINE }, - { 0x238c80, 1, RI_ALL_ONLINE }, { 0x238cc0, 1, RI_ALL_ONLINE }, - { 0x238cc4, 1, RI_E2E3_ONLINE }, { 0x238d00, 1, RI_ALL_ONLINE }, - { 0x238d40, 1, RI_ALL_ONLINE }, { 0x238d80, 1, RI_ALL_ONLINE }, - { 0x238dc0, 1, RI_ALL_ONLINE }, { 0x238e00, 1, RI_ALL_ONLINE }, - { 0x238e40, 1, RI_ALL_ONLINE }, { 0x238e80, 1, RI_ALL_ONLINE }, - { 0x238e84, 1, RI_E2E3_ONLINE }, { 0x238ec0, 1, RI_E1HE2E3_ONLINE }, - { 0x238f00, 1, RI_E1HE2E3_ONLINE }, { 0x238f40, 1, RI_E1HE2E3_ONLINE }, - { 0x238f80, 1, RI_E1HE2E3_ONLINE }, { 0x238fc0, 1, RI_E1HE2E3_ONLINE }, - { 0x238fc4, 2, RI_E2E3_ONLINE }, { 0x238fd0, 6, RI_E2E3_ONLINE }, - { 0x238fe8, 2, RI_E3_ONLINE }, { 0x239000, 1, RI_E2E3_ONLINE }, - { 0x239040, 3, RI_E2E3_ONLINE }, { 0x23905c, 1, RI_E3_ONLINE }, - { 0x240000, 2, RI_ALL_ONLINE }, { 0x280000, 65, RI_ALL_ONLINE }, - { 0x28014c, 2, RI_E1HE2E3_ONLINE }, { 0x280200, 58, RI_ALL_ONLINE }, - { 0x280340, 4, RI_ALL_ONLINE }, { 0x280380, 1, RI_E2E3_ONLINE }, - { 0x280388, 1, RI_E2E3_ONLINE }, { 0x280390, 1, RI_E2E3_ONLINE }, - { 0x280398, 1, RI_E2E3_ONLINE }, { 0x2803a0, 1, RI_E2E3_ONLINE }, - { 0x2803a8, 2, RI_E2E3_ONLINE }, { 0x280400, 1, RI_ALL_ONLINE }, - { 0x280404, 255, RI_E1E1H_OFFLINE }, { 0x282000, 4, RI_ALL_ONLINE }, - { 0x282010, 2044, RI_ALL_OFFLINE }, { 0x284000, 4, RI_E3_ONLINE }, - { 0x2a0000, 1, RI_ALL_ONLINE }, { 0x2a0004, 5631, RI_ALL_OFFLINE }, - { 0x2a5800, 2560, RI_E1HE2E3_OFFLINE }, { 0x2a8000, 1, RI_ALL_ONLINE }, - { 0x2a8004, 8191, RI_E1HE2E3_OFFLINE }, { 0x2b0000, 1, RI_ALL_ONLINE }, - { 0x2b0004, 15, RI_E1H_OFFLINE }, { 0x2b0040, 1, RI_E1HE2E3_ONLINE }, - { 0x2b0044, 239, RI_E1H_OFFLINE }, { 0x2b0400, 1, RI_ALL_ONLINE }, - { 0x2b0404, 255, RI_E1H_OFFLINE }, { 0x2b0800, 1, RI_ALL_ONLINE }, - { 0x2b0840, 1, RI_E1HE2E3_ONLINE }, { 0x2b0c00, 1, RI_ALL_ONLINE }, - { 0x2b1000, 1, RI_ALL_ONLINE }, { 0x2b1040, 1, RI_E1HE2E3_ONLINE }, - { 0x2b1400, 1, RI_ALL_ONLINE }, { 0x2b1440, 1, RI_E1HE2E3_ONLINE }, - { 0x2b1480, 1, RI_E1HE2E3_ONLINE }, { 0x2b14c0, 1, RI_E1HE2E3_ONLINE }, - { 0x2b1800, 128, RI_ALL_OFFLINE }, { 0x2b1c00, 128, RI_ALL_OFFLINE }, - { 0x2b2000, 1, RI_ALL_ONLINE }, { 0x2b2400, 1, RI_E1HE2E3_ONLINE }, - { 0x2b2404, 5631, RI_E2E3_OFFLINE }, { 0x2b8000, 1, RI_ALL_ONLINE }, - { 0x2b8040, 1, RI_ALL_ONLINE }, { 0x2b8080, 1, RI_ALL_ONLINE }, - { 0x2b80c0, 1, RI_ALL_ONLINE }, { 0x2b8100, 1, RI_ALL_ONLINE }, - { 0x2b8140, 1, RI_ALL_ONLINE }, { 0x2b8180, 1, RI_ALL_ONLINE }, - { 0x2b81c0, 1, RI_ALL_ONLINE }, { 0x2b8200, 1, RI_ALL_ONLINE }, - { 0x2b8240, 1, RI_ALL_ONLINE }, { 0x2b8280, 1, RI_ALL_ONLINE }, - { 0x2b82c0, 1, RI_ALL_ONLINE }, { 0x2b8300, 1, RI_ALL_ONLINE }, - { 0x2b8340, 1, RI_ALL_ONLINE }, { 0x2b8380, 1, RI_ALL_ONLINE }, - { 0x2b83c0, 1, RI_ALL_ONLINE }, { 0x2b8400, 1, RI_ALL_ONLINE }, - { 0x2b8440, 1, RI_ALL_ONLINE }, { 0x2b8480, 1, RI_ALL_ONLINE }, - { 0x2b84c0, 1, RI_ALL_ONLINE }, { 0x2b8500, 1, RI_ALL_ONLINE }, - { 0x2b8540, 1, RI_ALL_ONLINE }, { 0x2b8580, 1, RI_ALL_ONLINE }, - { 0x2b85c0, 19, RI_E2E3_ONLINE }, { 0x2b8800, 1, RI_ALL_ONLINE }, - { 0x2b8840, 1, RI_ALL_ONLINE }, { 0x2b8880, 1, RI_ALL_ONLINE }, - { 0x2b88c0, 1, RI_ALL_ONLINE }, { 0x2b8900, 1, RI_ALL_ONLINE }, - { 0x2b8940, 1, RI_ALL_ONLINE }, { 0x2b8980, 1, RI_ALL_ONLINE }, - { 0x2b89c0, 1, RI_ALL_ONLINE }, { 0x2b8a00, 1, RI_ALL_ONLINE }, - { 0x2b8a40, 1, RI_ALL_ONLINE }, { 0x2b8a80, 1, RI_ALL_ONLINE }, - { 0x2b8ac0, 1, RI_ALL_ONLINE }, { 0x2b8b00, 1, RI_ALL_ONLINE }, - { 0x2b8b40, 1, RI_ALL_ONLINE }, { 0x2b8b80, 1, RI_ALL_ONLINE }, - { 0x2b8bc0, 1, RI_ALL_ONLINE }, { 0x2b8c00, 1, RI_ALL_ONLINE }, - { 0x2b8c40, 1, RI_ALL_ONLINE }, { 0x2b8c80, 1, RI_ALL_ONLINE }, - { 0x2b8cc0, 1, RI_ALL_ONLINE }, { 0x2b8cc4, 1, RI_E2E3_ONLINE }, - { 0x2b8d00, 1, RI_ALL_ONLINE }, { 0x2b8d40, 1, RI_ALL_ONLINE }, - { 0x2b8d80, 1, RI_ALL_ONLINE }, { 0x2b8dc0, 1, RI_ALL_ONLINE }, - { 0x2b8e00, 1, RI_ALL_ONLINE }, { 0x2b8e40, 1, RI_ALL_ONLINE }, - { 0x2b8e80, 1, RI_ALL_ONLINE }, { 0x2b8e84, 1, RI_E2E3_ONLINE }, - { 0x2b8ec0, 1, RI_E1HE2E3_ONLINE }, { 0x2b8f00, 1, RI_E1HE2E3_ONLINE }, - { 0x2b8f40, 1, RI_E1HE2E3_ONLINE }, { 0x2b8f80, 1, RI_E1HE2E3_ONLINE }, - { 0x2b8fc0, 1, RI_E1HE2E3_ONLINE }, { 0x2b8fc4, 2, RI_E2E3_ONLINE }, - { 0x2b8fd0, 6, RI_E2E3_ONLINE }, { 0x2b8fe8, 2, RI_E3_ONLINE }, - { 0x2b9000, 1, RI_E2E3_ONLINE }, { 0x2b9040, 3, RI_E2E3_ONLINE }, - { 0x2b905c, 1, RI_E3_ONLINE }, { 0x2b9400, 14, RI_E2E3_ONLINE }, - { 0x2b943c, 19, RI_E2E3_ONLINE }, { 0x2b9490, 10, RI_E2E3_ONLINE }, - { 0x2c0000, 2, RI_ALL_ONLINE }, { 0x300000, 65, RI_ALL_ONLINE }, - { 0x30014c, 2, RI_E1HE2E3_ONLINE }, { 0x300200, 58, RI_ALL_ONLINE }, - { 0x300340, 4, RI_ALL_ONLINE }, { 0x300380, 1, RI_E2E3_ONLINE }, - { 0x300388, 1, RI_E2E3_ONLINE }, { 0x300390, 1, RI_E2E3_ONLINE }, - { 0x300398, 1, RI_E2E3_ONLINE }, { 0x3003a0, 1, RI_E2E3_ONLINE }, - { 0x3003a8, 2, RI_E2E3_ONLINE }, { 0x300400, 1, RI_ALL_ONLINE }, - { 0x300404, 255, RI_E1E1H_OFFLINE }, { 0x302000, 4, RI_ALL_ONLINE }, - { 0x302010, 2044, RI_ALL_OFFLINE }, { 0x304000, 4, RI_E3_ONLINE }, - { 0x320000, 1, RI_ALL_ONLINE }, { 0x320004, 5631, RI_ALL_OFFLINE }, - { 0x325800, 2560, RI_E1HE2E3_OFFLINE }, { 0x328000, 1, RI_ALL_ONLINE }, - { 0x328004, 8191, RI_E1HE2E3_OFFLINE }, { 0x330000, 1, RI_ALL_ONLINE }, - { 0x330004, 15, RI_E1H_OFFLINE }, { 0x330040, 1, RI_E1HE2E3_ONLINE }, - { 0x330044, 239, RI_E1H_OFFLINE }, { 0x330400, 1, RI_ALL_ONLINE }, - { 0x330404, 255, RI_E1H_OFFLINE }, { 0x330800, 1, RI_ALL_ONLINE }, - { 0x330840, 1, RI_E1HE2E3_ONLINE }, { 0x330c00, 1, RI_ALL_ONLINE }, - { 0x331000, 1, RI_ALL_ONLINE }, { 0x331040, 1, RI_E1HE2E3_ONLINE }, - { 0x331400, 1, RI_ALL_ONLINE }, { 0x331440, 1, RI_E1HE2E3_ONLINE }, - { 0x331480, 1, RI_E1HE2E3_ONLINE }, { 0x3314c0, 1, RI_E1HE2E3_ONLINE }, - { 0x331800, 128, RI_ALL_OFFLINE }, { 0x331c00, 128, RI_ALL_OFFLINE }, - { 0x332000, 1, RI_ALL_ONLINE }, { 0x332400, 1, RI_E1HE2E3_ONLINE }, - { 0x332404, 5631, RI_E2E3_OFFLINE }, { 0x338000, 1, RI_ALL_ONLINE }, - { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, - { 0x3380c0, 1, RI_ALL_ONLINE }, { 0x338100, 1, RI_ALL_ONLINE }, - { 0x338140, 1, RI_ALL_ONLINE }, { 0x338180, 1, RI_ALL_ONLINE }, - { 0x3381c0, 1, RI_ALL_ONLINE }, { 0x338200, 1, RI_ALL_ONLINE }, - { 0x338240, 1, RI_ALL_ONLINE }, { 0x338280, 1, RI_ALL_ONLINE }, - { 0x3382c0, 1, RI_ALL_ONLINE }, { 0x338300, 1, RI_ALL_ONLINE }, - { 0x338340, 1, RI_ALL_ONLINE }, { 0x338380, 1, RI_ALL_ONLINE }, - { 0x3383c0, 1, RI_ALL_ONLINE }, { 0x338400, 1, RI_ALL_ONLINE }, - { 0x338440, 1, RI_ALL_ONLINE }, { 0x338480, 1, RI_ALL_ONLINE }, - { 0x3384c0, 1, RI_ALL_ONLINE }, { 0x338500, 1, RI_ALL_ONLINE }, - { 0x338540, 1, RI_ALL_ONLINE }, { 0x338580, 1, RI_ALL_ONLINE }, - { 0x3385c0, 19, RI_E2E3_ONLINE }, { 0x338800, 1, RI_ALL_ONLINE }, - { 0x338840, 1, RI_ALL_ONLINE }, { 0x338880, 1, RI_ALL_ONLINE }, - { 0x3388c0, 1, RI_ALL_ONLINE }, { 0x338900, 1, RI_ALL_ONLINE }, - { 0x338940, 1, RI_ALL_ONLINE }, { 0x338980, 1, RI_ALL_ONLINE }, - { 0x3389c0, 1, RI_ALL_ONLINE }, { 0x338a00, 1, RI_ALL_ONLINE }, - { 0x338a40, 1, RI_ALL_ONLINE }, { 0x338a80, 1, RI_ALL_ONLINE }, - { 0x338ac0, 1, RI_ALL_ONLINE }, { 0x338b00, 1, RI_ALL_ONLINE }, - { 0x338b40, 1, RI_ALL_ONLINE }, { 0x338b80, 1, RI_ALL_ONLINE }, - { 0x338bc0, 1, RI_ALL_ONLINE }, { 0x338c00, 1, RI_ALL_ONLINE }, - { 0x338c40, 1, RI_ALL_ONLINE }, { 0x338c80, 1, RI_ALL_ONLINE }, - { 0x338cc0, 1, RI_ALL_ONLINE }, { 0x338cc4, 1, RI_E2E3_ONLINE }, - { 0x338d00, 1, RI_ALL_ONLINE }, { 0x338d40, 1, RI_ALL_ONLINE }, - { 0x338d80, 1, RI_ALL_ONLINE }, { 0x338dc0, 1, RI_ALL_ONLINE }, - { 0x338e00, 1, RI_ALL_ONLINE }, { 0x338e40, 1, RI_ALL_ONLINE }, - { 0x338e80, 1, RI_ALL_ONLINE }, { 0x338e84, 1, RI_E2E3_ONLINE }, - { 0x338ec0, 1, RI_E1HE2E3_ONLINE }, { 0x338f00, 1, RI_E1HE2E3_ONLINE }, - { 0x338f40, 1, RI_E1HE2E3_ONLINE }, { 0x338f80, 1, RI_E1HE2E3_ONLINE }, - { 0x338fc0, 1, RI_E1HE2E3_ONLINE }, { 0x338fc4, 2, RI_E2E3_ONLINE }, - { 0x338fd0, 6, RI_E2E3_ONLINE }, { 0x338fe8, 2, RI_E3_ONLINE }, - { 0x339000, 1, RI_E2E3_ONLINE }, { 0x339040, 3, RI_E2E3_ONLINE }, - { 0x33905c, 1, RI_E3_ONLINE }, { 0x340000, 2, RI_ALL_ONLINE }, + { 0x225800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x228000, 1, RI_ALL_ONLINE }, + { 0x228004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x230000, 1, RI_ALL_ONLINE }, + { 0x230004, 15, RI_E1H_OFFLINE }, + { 0x230040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x230044, 239, RI_E1H_OFFLINE }, + { 0x230400, 1, RI_ALL_ONLINE }, + { 0x230404, 255, RI_E1H_OFFLINE }, + { 0x230800, 1, RI_ALL_ONLINE }, + { 0x230840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x230c00, 1, RI_ALL_ONLINE }, + { 0x231000, 1, RI_ALL_ONLINE }, + { 0x231040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x231400, 1, RI_ALL_ONLINE }, + { 0x231440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x231480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2314c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x231800, 128, RI_ALL_OFFLINE }, + { 0x231c00, 128, RI_ALL_OFFLINE }, + { 0x232000, 1, RI_ALL_ONLINE }, + { 0x232400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x232404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x238000, 1, RI_ALL_ONLINE }, + { 0x238040, 1, RI_ALL_ONLINE }, + { 0x238080, 1, RI_ALL_ONLINE }, + { 0x2380c0, 1, RI_ALL_ONLINE }, + { 0x238100, 1, RI_ALL_ONLINE }, + { 0x238140, 1, RI_ALL_ONLINE }, + { 0x238180, 1, RI_ALL_ONLINE }, + { 0x2381c0, 1, RI_ALL_ONLINE }, + { 0x238200, 1, RI_ALL_ONLINE }, + { 0x238240, 1, RI_ALL_ONLINE }, + { 0x238280, 1, RI_ALL_ONLINE }, + { 0x2382c0, 1, RI_ALL_ONLINE }, + { 0x238300, 1, RI_ALL_ONLINE }, + { 0x238340, 1, RI_ALL_ONLINE }, + { 0x238380, 1, RI_ALL_ONLINE }, + { 0x2383c0, 1, RI_ALL_ONLINE }, + { 0x238400, 1, RI_ALL_ONLINE }, + { 0x238440, 1, RI_ALL_ONLINE }, + { 0x238480, 1, RI_ALL_ONLINE }, + { 0x2384c0, 1, RI_ALL_ONLINE }, + { 0x238500, 1, RI_ALL_ONLINE }, + { 0x238540, 1, RI_ALL_ONLINE }, + { 0x238580, 1, RI_ALL_ONLINE }, + { 0x2385c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x238800, 1, RI_ALL_ONLINE }, + { 0x238840, 1, RI_ALL_ONLINE }, + { 0x238880, 1, RI_ALL_ONLINE }, + { 0x2388c0, 1, RI_ALL_ONLINE }, + { 0x238900, 1, RI_ALL_ONLINE }, + { 0x238940, 1, RI_ALL_ONLINE }, + { 0x238980, 1, RI_ALL_ONLINE }, + { 0x2389c0, 1, RI_ALL_ONLINE }, + { 0x238a00, 1, RI_ALL_ONLINE }, + { 0x238a40, 1, RI_ALL_ONLINE }, + { 0x238a80, 1, RI_ALL_ONLINE }, + { 0x238ac0, 1, RI_ALL_ONLINE }, + { 0x238b00, 1, RI_ALL_ONLINE }, + { 0x238b40, 1, RI_ALL_ONLINE }, + { 0x238b80, 1, RI_ALL_ONLINE }, + { 0x238bc0, 1, RI_ALL_ONLINE }, + { 0x238c00, 1, RI_ALL_ONLINE }, + { 0x238c40, 1, RI_ALL_ONLINE }, + { 0x238c80, 1, RI_ALL_ONLINE }, + { 0x238cc0, 1, RI_ALL_ONLINE }, + { 0x238cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x238d00, 1, RI_ALL_ONLINE }, + { 0x238d40, 1, RI_ALL_ONLINE }, + { 0x238d80, 1, RI_ALL_ONLINE }, + { 0x238dc0, 1, RI_ALL_ONLINE }, + { 0x238e00, 1, RI_ALL_ONLINE }, + { 0x238e40, 1, RI_ALL_ONLINE }, + { 0x238e80, 1, RI_ALL_ONLINE }, + { 0x238e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x238ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x238fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x238fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x238fe8, 2, RI_E3E3B0_ONLINE }, + { 0x239000, 1, RI_E2E3E3B0_ONLINE }, + { 0x239040, 3, RI_E2E3E3B0_ONLINE }, + { 0x23905c, 1, RI_E3E3B0_ONLINE }, + { 0x239064, 1, RI_E3B0_ONLINE }, + { 0x239080, 10, RI_E3B0_ONLINE }, + { 0x240000, 2, RI_ALL_ONLINE }, + { 0x280000, 65, RI_ALL_ONLINE }, + { 0x28014c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x280200, 58, RI_ALL_ONLINE }, + { 0x280340, 4, RI_ALL_ONLINE }, + { 0x280380, 1, RI_E2E3E3B0_ONLINE }, + { 0x280388, 1, RI_E2E3E3B0_ONLINE }, + { 0x280390, 1, RI_E2E3E3B0_ONLINE }, + { 0x280398, 1, RI_E2E3E3B0_ONLINE }, + { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, + { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, + { 0x280400, 1, RI_ALL_ONLINE }, + { 0x280404, 255, RI_E1E1H_OFFLINE }, + { 0x282000, 4, RI_ALL_ONLINE }, + { 0x282010, 2044, RI_ALL_OFFLINE }, + { 0x284000, 4, RI_E3E3B0_ONLINE }, + { 0x2a0000, 1, RI_ALL_ONLINE }, + { 0x2a0004, 5631, RI_ALL_OFFLINE }, + { 0x2a5800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x2a8000, 1, RI_ALL_ONLINE }, + { 0x2a8004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x2b0000, 1, RI_ALL_ONLINE }, + { 0x2b0004, 15, RI_E1H_OFFLINE }, + { 0x2b0040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b0044, 239, RI_E1H_OFFLINE }, + { 0x2b0400, 1, RI_ALL_ONLINE }, + { 0x2b0404, 255, RI_E1H_OFFLINE }, + { 0x2b0800, 1, RI_ALL_ONLINE }, + { 0x2b0840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b0c00, 1, RI_ALL_ONLINE }, + { 0x2b1000, 1, RI_ALL_ONLINE }, + { 0x2b1040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b1400, 1, RI_ALL_ONLINE }, + { 0x2b1440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b1480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b14c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b1800, 128, RI_ALL_OFFLINE }, + { 0x2b1c00, 128, RI_ALL_OFFLINE }, + { 0x2b2000, 1, RI_ALL_ONLINE }, + { 0x2b2400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b2404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x2b8000, 1, RI_ALL_ONLINE }, + { 0x2b8040, 1, RI_ALL_ONLINE }, + { 0x2b8080, 1, RI_ALL_ONLINE }, + { 0x2b80c0, 1, RI_ALL_ONLINE }, + { 0x2b8100, 1, RI_ALL_ONLINE }, + { 0x2b8140, 1, RI_ALL_ONLINE }, + { 0x2b8180, 1, RI_ALL_ONLINE }, + { 0x2b81c0, 1, RI_ALL_ONLINE }, + { 0x2b8200, 1, RI_ALL_ONLINE }, + { 0x2b8240, 1, RI_ALL_ONLINE }, + { 0x2b8280, 1, RI_ALL_ONLINE }, + { 0x2b82c0, 1, RI_ALL_ONLINE }, + { 0x2b8300, 1, RI_ALL_ONLINE }, + { 0x2b8340, 1, RI_ALL_ONLINE }, + { 0x2b8380, 1, RI_ALL_ONLINE }, + { 0x2b83c0, 1, RI_ALL_ONLINE }, + { 0x2b8400, 1, RI_ALL_ONLINE }, + { 0x2b8440, 1, RI_ALL_ONLINE }, + { 0x2b8480, 1, RI_ALL_ONLINE }, + { 0x2b84c0, 1, RI_ALL_ONLINE }, + { 0x2b8500, 1, RI_ALL_ONLINE }, + { 0x2b8540, 1, RI_ALL_ONLINE }, + { 0x2b8580, 1, RI_ALL_ONLINE }, + { 0x2b85c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x2b8800, 1, RI_ALL_ONLINE }, + { 0x2b8840, 1, RI_ALL_ONLINE }, + { 0x2b8880, 1, RI_ALL_ONLINE }, + { 0x2b88c0, 1, RI_ALL_ONLINE }, + { 0x2b8900, 1, RI_ALL_ONLINE }, + { 0x2b8940, 1, RI_ALL_ONLINE }, + { 0x2b8980, 1, RI_ALL_ONLINE }, + { 0x2b89c0, 1, RI_ALL_ONLINE }, + { 0x2b8a00, 1, RI_ALL_ONLINE }, + { 0x2b8a40, 1, RI_ALL_ONLINE }, + { 0x2b8a80, 1, RI_ALL_ONLINE }, + { 0x2b8ac0, 1, RI_ALL_ONLINE }, + { 0x2b8b00, 1, RI_ALL_ONLINE }, + { 0x2b8b40, 1, RI_ALL_ONLINE }, + { 0x2b8b80, 1, RI_ALL_ONLINE }, + { 0x2b8bc0, 1, RI_ALL_ONLINE }, + { 0x2b8c00, 1, RI_ALL_ONLINE }, + { 0x2b8c40, 1, RI_ALL_ONLINE }, + { 0x2b8c80, 1, RI_ALL_ONLINE }, + { 0x2b8cc0, 1, RI_ALL_ONLINE }, + { 0x2b8cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x2b8d00, 1, RI_ALL_ONLINE }, + { 0x2b8d40, 1, RI_ALL_ONLINE }, + { 0x2b8d80, 1, RI_ALL_ONLINE }, + { 0x2b8dc0, 1, RI_ALL_ONLINE }, + { 0x2b8e00, 1, RI_ALL_ONLINE }, + { 0x2b8e40, 1, RI_ALL_ONLINE }, + { 0x2b8e80, 1, RI_ALL_ONLINE }, + { 0x2b8e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x2b8ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x2b8fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x2b8fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x2b8fe8, 2, RI_E3E3B0_ONLINE }, + { 0x2b9000, 1, RI_E2E3E3B0_ONLINE }, + { 0x2b9040, 3, RI_E2E3E3B0_ONLINE }, + { 0x2b905c, 1, RI_E3E3B0_ONLINE }, + { 0x2b9064, 1, RI_E3B0_ONLINE }, + { 0x2b9080, 10, RI_E3B0_ONLINE }, + { 0x2b9400, 14, RI_E2E3E3B0_ONLINE }, + { 0x2b943c, 19, RI_E2E3E3B0_ONLINE }, + { 0x2b9490, 10, RI_E2E3E3B0_ONLINE }, + { 0x2c0000, 2, RI_ALL_ONLINE }, + { 0x300000, 65, RI_ALL_ONLINE }, + { 0x30014c, 2, RI_E1HE2E3E3B0_ONLINE }, + { 0x300200, 58, RI_ALL_ONLINE }, + { 0x300340, 4, RI_ALL_ONLINE }, + { 0x300380, 1, RI_E2E3E3B0_ONLINE }, + { 0x300388, 1, RI_E2E3E3B0_ONLINE }, + { 0x300390, 1, RI_E2E3E3B0_ONLINE }, + { 0x300398, 1, RI_E2E3E3B0_ONLINE }, + { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, + { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, + { 0x300400, 1, RI_ALL_ONLINE }, + { 0x300404, 255, RI_E1E1H_OFFLINE }, + { 0x302000, 4, RI_ALL_ONLINE }, + { 0x302010, 2044, RI_ALL_OFFLINE }, + { 0x304000, 4, RI_E3E3B0_ONLINE }, + { 0x320000, 1, RI_ALL_ONLINE }, + { 0x320004, 5631, RI_ALL_OFFLINE }, + { 0x325800, 2560, RI_E1HE2E3E3B0_OFFLINE }, + { 0x328000, 1, RI_ALL_ONLINE }, + { 0x328004, 8191, RI_E1HE2E3E3B0_OFFLINE }, + { 0x330000, 1, RI_ALL_ONLINE }, + { 0x330004, 15, RI_E1H_OFFLINE }, + { 0x330040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x330044, 239, RI_E1H_OFFLINE }, + { 0x330400, 1, RI_ALL_ONLINE }, + { 0x330404, 255, RI_E1H_OFFLINE }, + { 0x330800, 1, RI_ALL_ONLINE }, + { 0x330840, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x330c00, 1, RI_ALL_ONLINE }, + { 0x331000, 1, RI_ALL_ONLINE }, + { 0x331040, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x331400, 1, RI_ALL_ONLINE }, + { 0x331440, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x331480, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x3314c0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x331800, 128, RI_ALL_OFFLINE }, + { 0x331c00, 128, RI_ALL_OFFLINE }, + { 0x332000, 1, RI_ALL_ONLINE }, + { 0x332400, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x332404, 5631, RI_E2E3E3B0_OFFLINE }, + { 0x338000, 1, RI_ALL_ONLINE }, + { 0x338040, 1, RI_ALL_ONLINE }, + { 0x338080, 1, RI_ALL_ONLINE }, + { 0x3380c0, 1, RI_ALL_ONLINE }, + { 0x338100, 1, RI_ALL_ONLINE }, + { 0x338140, 1, RI_ALL_ONLINE }, + { 0x338180, 1, RI_ALL_ONLINE }, + { 0x3381c0, 1, RI_ALL_ONLINE }, + { 0x338200, 1, RI_ALL_ONLINE }, + { 0x338240, 1, RI_ALL_ONLINE }, + { 0x338280, 1, RI_ALL_ONLINE }, + { 0x3382c0, 1, RI_ALL_ONLINE }, + { 0x338300, 1, RI_ALL_ONLINE }, + { 0x338340, 1, RI_ALL_ONLINE }, + { 0x338380, 1, RI_ALL_ONLINE }, + { 0x3383c0, 1, RI_ALL_ONLINE }, + { 0x338400, 1, RI_ALL_ONLINE }, + { 0x338440, 1, RI_ALL_ONLINE }, + { 0x338480, 1, RI_ALL_ONLINE }, + { 0x3384c0, 1, RI_ALL_ONLINE }, + { 0x338500, 1, RI_ALL_ONLINE }, + { 0x338540, 1, RI_ALL_ONLINE }, + { 0x338580, 1, RI_ALL_ONLINE }, + { 0x3385c0, 19, RI_E2E3E3B0_ONLINE }, + { 0x338800, 1, RI_ALL_ONLINE }, + { 0x338840, 1, RI_ALL_ONLINE }, + { 0x338880, 1, RI_ALL_ONLINE }, + { 0x3388c0, 1, RI_ALL_ONLINE }, + { 0x338900, 1, RI_ALL_ONLINE }, + { 0x338940, 1, RI_ALL_ONLINE }, + { 0x338980, 1, RI_ALL_ONLINE }, + { 0x3389c0, 1, RI_ALL_ONLINE }, + { 0x338a00, 1, RI_ALL_ONLINE }, + { 0x338a40, 1, RI_ALL_ONLINE }, + { 0x338a80, 1, RI_ALL_ONLINE }, + { 0x338ac0, 1, RI_ALL_ONLINE }, + { 0x338b00, 1, RI_ALL_ONLINE }, + { 0x338b40, 1, RI_ALL_ONLINE }, + { 0x338b80, 1, RI_ALL_ONLINE }, + { 0x338bc0, 1, RI_ALL_ONLINE }, + { 0x338c00, 1, RI_ALL_ONLINE }, + { 0x338c40, 1, RI_ALL_ONLINE }, + { 0x338c80, 1, RI_ALL_ONLINE }, + { 0x338cc0, 1, RI_ALL_ONLINE }, + { 0x338cc4, 1, RI_E2E3E3B0_ONLINE }, + { 0x338d00, 1, RI_ALL_ONLINE }, + { 0x338d40, 1, RI_ALL_ONLINE }, + { 0x338d80, 1, RI_ALL_ONLINE }, + { 0x338dc0, 1, RI_ALL_ONLINE }, + { 0x338e00, 1, RI_ALL_ONLINE }, + { 0x338e40, 1, RI_ALL_ONLINE }, + { 0x338e80, 1, RI_ALL_ONLINE }, + { 0x338e84, 1, RI_E2E3E3B0_ONLINE }, + { 0x338ec0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338f00, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338f40, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338f80, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338fc0, 1, RI_E1HE2E3E3B0_ONLINE }, + { 0x338fc4, 2, RI_E2E3E3B0_ONLINE }, + { 0x338fd0, 6, RI_E2E3E3B0_ONLINE }, + { 0x338fe8, 2, RI_E3E3B0_ONLINE }, + { 0x339000, 1, RI_E2E3E3B0_ONLINE }, + { 0x339040, 3, RI_E2E3E3B0_ONLINE }, + { 0x33905c, 1, RI_E3E3B0_ONLINE }, + { 0x339064, 1, RI_E3B0_ONLINE }, + { 0x339080, 10, RI_E3B0_ONLINE }, + { 0x340000, 2, RI_ALL_ONLINE }, }; #define REGS_COUNT ARRAY_SIZE(reg_addrs) -static const struct reg_addr idle_addrs[] = { - { 0x2104, 1, RI_ALL_ONLINE }, { 0x2110, 2, RI_ALL_ONLINE }, - { 0x211c, 8, RI_ALL_ONLINE }, { 0x2814, 1, RI_ALL_ONLINE }, - { 0x281c, 2, RI_ALL_ONLINE }, { 0x2854, 1, RI_ALL_ONLINE }, - { 0x285c, 1, RI_ALL_ONLINE }, { 0x3040, 1, RI_ALL_ONLINE }, - { 0x9010, 7, RI_E2E3_ONLINE }, { 0x9030, 1, RI_E2E3_ONLINE }, - { 0x9068, 16, RI_E2E3_ONLINE }, { 0x9230, 2, RI_E2E3_ONLINE }, - { 0x9244, 1, RI_E2E3_ONLINE }, { 0x9298, 1, RI_E2E3_ONLINE }, - { 0x92a8, 1, RI_E2E3_ONLINE }, { 0xa38c, 1, RI_ALL_ONLINE }, - { 0xa3c4, 1, RI_E1HE2E3_ONLINE }, { 0xa404, 3, RI_ALL_ONLINE }, - { 0xa42c, 12, RI_ALL_ONLINE }, { 0xa600, 5, RI_E1HE2E3_ONLINE }, - { 0xa618, 1, RI_E1HE2E3_ONLINE }, { 0xa714, 1, RI_E2E3_ONLINE }, - { 0xa720, 1, RI_E2E3_ONLINE }, { 0xa750, 1, RI_E2E3_ONLINE }, - { 0xc09c, 1, RI_E1E1H_ONLINE }, { 0x103b0, 1, RI_ALL_ONLINE }, - { 0x103c0, 1, RI_ALL_ONLINE }, { 0x103d0, 1, RI_E1H_ONLINE }, - { 0x10418, 1, RI_ALL_ONLINE }, { 0x10420, 1, RI_ALL_ONLINE }, - { 0x10428, 1, RI_ALL_ONLINE }, { 0x10460, 1, RI_ALL_ONLINE }, - { 0x10474, 1, RI_ALL_ONLINE }, { 0x104e0, 1, RI_ALL_ONLINE }, - { 0x104ec, 1, RI_ALL_ONLINE }, { 0x104f8, 1, RI_ALL_ONLINE }, - { 0x10508, 1, RI_ALL_ONLINE }, { 0x10530, 1, RI_ALL_ONLINE }, - { 0x10538, 1, RI_ALL_ONLINE }, { 0x10548, 1, RI_ALL_ONLINE }, - { 0x10558, 1, RI_ALL_ONLINE }, { 0x182a8, 1, RI_E2E3_ONLINE }, - { 0x182b8, 1, RI_E2E3_ONLINE }, { 0x18308, 1, RI_E2E3_ONLINE }, - { 0x18318, 1, RI_E2E3_ONLINE }, { 0x18338, 1, RI_E2E3_ONLINE }, - { 0x18348, 1, RI_E2E3_ONLINE }, { 0x183bc, 1, RI_E2E3_ONLINE }, - { 0x183cc, 1, RI_E2E3_ONLINE }, { 0x18570, 1, RI_E3_ONLINE }, - { 0x18578, 1, RI_E3_ONLINE }, { 0x1858c, 1, RI_E3_ONLINE }, - { 0x18594, 1, RI_E3_ONLINE }, { 0x2021c, 11, RI_ALL_ONLINE }, - { 0x202a8, 1, RI_ALL_ONLINE }, { 0x202b8, 1, RI_ALL_ONLINE }, - { 0x20404, 1, RI_ALL_ONLINE }, { 0x2040c, 2, RI_ALL_ONLINE }, - { 0x2041c, 2, RI_ALL_ONLINE }, { 0x40154, 14, RI_ALL_ONLINE }, - { 0x40198, 1, RI_ALL_ONLINE }, { 0x404ac, 1, RI_ALL_ONLINE }, - { 0x404bc, 1, RI_ALL_ONLINE }, { 0x42290, 1, RI_ALL_ONLINE }, - { 0x422a0, 1, RI_ALL_ONLINE }, { 0x422b0, 1, RI_ALL_ONLINE }, - { 0x42548, 1, RI_ALL_ONLINE }, { 0x42550, 1, RI_ALL_ONLINE }, - { 0x42558, 1, RI_ALL_ONLINE }, { 0x50160, 8, RI_ALL_ONLINE }, - { 0x501d0, 1, RI_ALL_ONLINE }, { 0x501e0, 1, RI_ALL_ONLINE }, - { 0x50204, 1, RI_ALL_ONLINE }, { 0x5020c, 2, RI_ALL_ONLINE }, - { 0x5021c, 1, RI_ALL_ONLINE }, { 0x60090, 1, RI_ALL_ONLINE }, - { 0x6011c, 1, RI_ALL_ONLINE }, { 0x6012c, 1, RI_ALL_ONLINE }, - { 0xc101c, 1, RI_ALL_ONLINE }, { 0xc102c, 1, RI_ALL_ONLINE }, - { 0xc2290, 1, RI_ALL_ONLINE }, { 0xc22a0, 1, RI_ALL_ONLINE }, - { 0xc22b0, 1, RI_ALL_ONLINE }, { 0xc2548, 1, RI_ALL_ONLINE }, - { 0xc2550, 1, RI_ALL_ONLINE }, { 0xc2558, 1, RI_ALL_ONLINE }, - { 0xc4294, 1, RI_ALL_ONLINE }, { 0xc42a4, 1, RI_ALL_ONLINE }, - { 0xc42b4, 1, RI_ALL_ONLINE }, { 0xc4550, 1, RI_ALL_ONLINE }, - { 0xc4558, 1, RI_ALL_ONLINE }, { 0xc4560, 1, RI_ALL_ONLINE }, - { 0xd016c, 8, RI_ALL_ONLINE }, { 0xd01d8, 1, RI_ALL_ONLINE }, - { 0xd01e8, 1, RI_ALL_ONLINE }, { 0xd0204, 1, RI_ALL_ONLINE }, - { 0xd020c, 3, RI_ALL_ONLINE }, { 0xe0154, 8, RI_ALL_ONLINE }, - { 0xe01c8, 1, RI_ALL_ONLINE }, { 0xe01d8, 1, RI_ALL_ONLINE }, - { 0xe0204, 1, RI_ALL_ONLINE }, { 0xe020c, 2, RI_ALL_ONLINE }, - { 0xe021c, 2, RI_ALL_ONLINE }, { 0x101014, 1, RI_ALL_ONLINE }, - { 0x101030, 1, RI_ALL_ONLINE }, { 0x101040, 1, RI_ALL_ONLINE }, - { 0x102058, 1, RI_ALL_ONLINE }, { 0x102080, 16, RI_ALL_ONLINE }, - { 0x103004, 2, RI_ALL_ONLINE }, { 0x103068, 1, RI_ALL_ONLINE }, - { 0x103078, 1, RI_ALL_ONLINE }, { 0x103088, 1, RI_ALL_ONLINE }, - { 0x10309c, 2, RI_E1HE2E3_ONLINE }, { 0x1030b8, 2, RI_E2E3_ONLINE }, - { 0x1030cc, 1, RI_E2E3_ONLINE }, { 0x1030e0, 1, RI_E2E3_ONLINE }, - { 0x104004, 1, RI_ALL_ONLINE }, { 0x104018, 1, RI_ALL_ONLINE }, - { 0x104020, 1, RI_ALL_ONLINE }, { 0x10403c, 1, RI_ALL_ONLINE }, - { 0x1040fc, 1, RI_ALL_ONLINE }, { 0x10410c, 1, RI_ALL_ONLINE }, - { 0x104400, 64, RI_ALL_ONLINE }, { 0x104800, 64, RI_ALL_ONLINE }, - { 0x105000, 256, RI_ALL_ONLINE }, { 0x108094, 1, RI_E1E1H_ONLINE }, - { 0x1201b0, 2, RI_ALL_ONLINE }, { 0x12032c, 1, RI_ALL_ONLINE }, - { 0x12036c, 3, RI_ALL_ONLINE }, { 0x120408, 2, RI_ALL_ONLINE }, - { 0x120414, 15, RI_ALL_ONLINE }, { 0x120478, 2, RI_ALL_ONLINE }, - { 0x12052c, 1, RI_ALL_ONLINE }, { 0x120564, 3, RI_ALL_ONLINE }, - { 0x12057c, 1, RI_ALL_ONLINE }, { 0x12058c, 1, RI_ALL_ONLINE }, - { 0x120608, 1, RI_E1HE2E3_ONLINE }, { 0x120778, 2, RI_E2E3_ONLINE }, - { 0x120808, 3, RI_ALL_ONLINE }, { 0x120818, 1, RI_ALL_ONLINE }, - { 0x120820, 1, RI_ALL_ONLINE }, { 0x120828, 1, RI_ALL_ONLINE }, - { 0x120830, 1, RI_ALL_ONLINE }, { 0x120838, 1, RI_ALL_ONLINE }, - { 0x120840, 1, RI_ALL_ONLINE }, { 0x120848, 1, RI_ALL_ONLINE }, - { 0x120850, 1, RI_ALL_ONLINE }, { 0x120858, 1, RI_ALL_ONLINE }, - { 0x120860, 1, RI_ALL_ONLINE }, { 0x120868, 1, RI_ALL_ONLINE }, - { 0x120870, 1, RI_ALL_ONLINE }, { 0x120878, 1, RI_ALL_ONLINE }, - { 0x120880, 1, RI_ALL_ONLINE }, { 0x120888, 1, RI_ALL_ONLINE }, - { 0x120890, 1, RI_ALL_ONLINE }, { 0x120898, 1, RI_ALL_ONLINE }, - { 0x1208a0, 1, RI_ALL_ONLINE }, { 0x1208a8, 1, RI_ALL_ONLINE }, - { 0x1208b0, 1, RI_ALL_ONLINE }, { 0x1208b8, 1, RI_ALL_ONLINE }, - { 0x1208c0, 1, RI_ALL_ONLINE }, { 0x1208c8, 1, RI_ALL_ONLINE }, - { 0x1208d0, 1, RI_ALL_ONLINE }, { 0x1208d8, 1, RI_ALL_ONLINE }, - { 0x1208e0, 1, RI_ALL_ONLINE }, { 0x1208e8, 1, RI_ALL_ONLINE }, - { 0x1208f0, 1, RI_ALL_ONLINE }, { 0x1208f8, 1, RI_ALL_ONLINE }, - { 0x120900, 1, RI_ALL_ONLINE }, { 0x120908, 1, RI_ALL_ONLINE }, - { 0x130030, 1, RI_E2E3_ONLINE }, { 0x13004c, 3, RI_E2E3_ONLINE }, - { 0x130064, 2, RI_E2E3_ONLINE }, { 0x13009c, 1, RI_E2E3_ONLINE }, - { 0x130130, 1, RI_E2E3_ONLINE }, { 0x13016c, 1, RI_E2E3_ONLINE }, - { 0x130300, 1, RI_E2E3_ONLINE }, { 0x130480, 1, RI_E2E3_ONLINE }, - { 0x14005c, 2, RI_ALL_ONLINE }, { 0x1400d0, 2, RI_ALL_ONLINE }, - { 0x1400e0, 1, RI_ALL_ONLINE }, { 0x1401c8, 1, RI_ALL_ONLINE }, - { 0x140200, 6, RI_ALL_ONLINE }, { 0x16101c, 1, RI_ALL_ONLINE }, - { 0x16102c, 1, RI_ALL_ONLINE }, { 0x164014, 2, RI_ALL_ONLINE }, - { 0x1640f0, 1, RI_ALL_ONLINE }, { 0x166290, 1, RI_ALL_ONLINE }, - { 0x1662a0, 1, RI_ALL_ONLINE }, { 0x1662b0, 1, RI_ALL_ONLINE }, - { 0x166548, 1, RI_ALL_ONLINE }, { 0x166550, 1, RI_ALL_ONLINE }, - { 0x166558, 1, RI_ALL_ONLINE }, { 0x168000, 1, RI_ALL_ONLINE }, - { 0x168008, 1, RI_ALL_ONLINE }, { 0x168010, 1, RI_ALL_ONLINE }, - { 0x168018, 1, RI_ALL_ONLINE }, { 0x168028, 2, RI_ALL_ONLINE }, - { 0x168058, 4, RI_ALL_ONLINE }, { 0x168070, 1, RI_ALL_ONLINE }, - { 0x168238, 1, RI_ALL_ONLINE }, { 0x1682d0, 2, RI_ALL_ONLINE }, - { 0x1682e0, 1, RI_ALL_ONLINE }, { 0x168300, 2, RI_E1E1H_ONLINE }, - { 0x168308, 65, RI_ALL_ONLINE }, { 0x168410, 2, RI_ALL_ONLINE }, - { 0x168438, 1, RI_ALL_ONLINE }, { 0x168448, 1, RI_ALL_ONLINE }, - { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16e200, 128, RI_E1H_ONLINE }, - { 0x16e404, 2, RI_E1H_ONLINE }, { 0x16e584, 64, RI_E1H_ONLINE }, - { 0x16e684, 2, RI_E1HE2E3_ONLINE }, { 0x16e68c, 4, RI_E1H_ONLINE }, - { 0x16e6fc, 4, RI_E2E3_ONLINE }, { 0x1700a4, 1, RI_ALL_ONLINE }, - { 0x1700ac, 2, RI_ALL_ONLINE }, { 0x1700c0, 1, RI_ALL_ONLINE }, - { 0x170174, 1, RI_ALL_ONLINE }, { 0x170184, 1, RI_ALL_ONLINE }, - { 0x1800f4, 1, RI_ALL_ONLINE }, { 0x180104, 1, RI_ALL_ONLINE }, - { 0x180114, 1, RI_ALL_ONLINE }, { 0x180124, 1, RI_ALL_ONLINE }, - { 0x18026c, 1, RI_ALL_ONLINE }, { 0x1802a0, 1, RI_ALL_ONLINE }, - { 0x1b8000, 1, RI_ALL_ONLINE }, { 0x1b8040, 1, RI_ALL_ONLINE }, - { 0x1b8080, 1, RI_ALL_ONLINE }, { 0x1b80c0, 1, RI_ALL_ONLINE }, - { 0x200104, 1, RI_ALL_ONLINE }, { 0x200114, 1, RI_ALL_ONLINE }, - { 0x200124, 1, RI_ALL_ONLINE }, { 0x200134, 1, RI_ALL_ONLINE }, - { 0x20026c, 1, RI_ALL_ONLINE }, { 0x2002a0, 1, RI_ALL_ONLINE }, - { 0x238000, 1, RI_ALL_ONLINE }, { 0x238040, 1, RI_ALL_ONLINE }, - { 0x238080, 1, RI_ALL_ONLINE }, { 0x2380c0, 1, RI_ALL_ONLINE }, - { 0x280104, 1, RI_ALL_ONLINE }, { 0x280114, 1, RI_ALL_ONLINE }, - { 0x280124, 1, RI_ALL_ONLINE }, { 0x280134, 1, RI_ALL_ONLINE }, - { 0x28026c, 1, RI_ALL_ONLINE }, { 0x2802a0, 1, RI_ALL_ONLINE }, - { 0x2b8000, 1, RI_ALL_ONLINE }, { 0x2b8040, 1, RI_ALL_ONLINE }, - { 0x2b8080, 1, RI_ALL_ONLINE }, { 0x300104, 1, RI_ALL_ONLINE }, - { 0x300114, 1, RI_ALL_ONLINE }, { 0x300124, 1, RI_ALL_ONLINE }, - { 0x300134, 1, RI_ALL_ONLINE }, { 0x30026c, 1, RI_ALL_ONLINE }, - { 0x3002a0, 1, RI_ALL_ONLINE }, { 0x338000, 1, RI_ALL_ONLINE }, - { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, - { 0x3380c0, 1, RI_ALL_ONLINE } -}; -#define IDLE_REGS_COUNT ARRAY_SIZE(idle_addrs) - -static const u32 read_reg_e1_0[] = { 0x1b1000 }; -#define WREGS_COUNT_E1 ARRAY_SIZE(read_reg_e1_0) - -static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = { - { 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE } -}; - -static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 }; -#define WREGS_COUNT_E1H ARRAY_SIZE(read_reg_e1h_0) - -static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = { - { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE } -}; - -static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 }; -#define WREGS_COUNT_E2 ARRAY_SIZE(read_reg_e2_0) - -static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = { - { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE } -}; - -static const u32 read_reg_e3_0[] = { 0x1b1040, 0x1b1000 }; -#define WREGS_COUNT_E3 ARRAY_SIZE(read_reg_e3_0) - -static const struct wreg_addr wreg_addrs_e3[WREGS_COUNT_E3] = { - { 0x1b0c00, 128, 2, read_reg_e3_0, RI_E3_OFFLINE } }; - -static const struct dump_sign dump_sign_all = { 0x4dbe9fca, 0x60011, 0x3a }; - -static const u32 timer_status_regs_e1[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E1 ARRAY_SIZE(timer_status_regs_e1) - -static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] = { - 0x1640d0, 0x1640d4 }; - -static const u32 timer_status_regs_e1h[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E1H ARRAY_SIZE(timer_status_regs_e1h) - -static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = { - 0x1640d0, 0x1640d4 }; - -static const u32 timer_status_regs_e2[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E2 ARRAY_SIZE(timer_status_regs_e2) - -static const u32 timer_scan_regs_e2[TIMER_REGS_COUNT_E2] = { - 0x1640d0, 0x1640d4 }; - -static const u32 timer_status_regs_e3[] = { 0x164014, 0x164018 }; -#define TIMER_REGS_COUNT_E3 ARRAY_SIZE(timer_status_regs_e3) - -static const u32 timer_scan_regs_e3[TIMER_REGS_COUNT_E3] = { - 0x1640d0, 0x1640d4 }; - -#define PAGE_MODE_VALUES_E1 0 - -#define PAGE_READ_REGS_E1 0 - -#define PAGE_WRITE_REGS_E1 0 - -static const u32 page_vals_e1[] = { 0 }; - -static const u32 page_write_regs_e1[] = { 0 }; - -static const struct reg_addr page_read_regs_e1[] = { - { 0x0, 0, RI_E1_ONLINE } }; - -#define PAGE_MODE_VALUES_E1H 0 - -#define PAGE_READ_REGS_E1H 0 - -#define PAGE_WRITE_REGS_E1H 0 - -static const u32 page_vals_e1h[] = { 0 }; - -static const u32 page_write_regs_e1h[] = { 0 }; - -static const struct reg_addr page_read_regs_e1h[] = { - { 0x0, 0, RI_E1H_ONLINE } }; +static const struct dump_sign dump_sign_all = { 0x4e23fde1, 0x70017, 0x3a }; static const u32 page_vals_e2[] = { 0, 128 }; #define PAGE_MODE_VALUES_E2 ARRAY_SIZE(page_vals_e2) @@ -836,7 +1150,7 @@ static const u32 page_write_regs_e3[] = { 328476 }; #define PAGE_WRITE_REGS_E3 ARRAY_SIZE(page_write_regs_e3) static const struct reg_addr page_read_regs_e3[] = { - { 0x58000, 4608, RI_E3_ONLINE } }; + { 0x58000, 4608, RI_E3E3B0_ONLINE } }; #define PAGE_READ_REGS_E3 ARRAY_SIZE(page_read_regs_e3) #endif /* BNX2X_DUMP_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index eda0f7b82c5..221863059da 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -500,78 +500,179 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) #define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) #define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) #define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE) +#define IS_E3_ONLINE(info) (((info) & RI_E3_ONLINE) == RI_E3_ONLINE) +#define IS_E3B0_ONLINE(info) (((info) & RI_E3B0_ONLINE) == RI_E3B0_ONLINE) + +static inline bool bnx2x_is_reg_online(struct bnx2x *bp, + const struct reg_addr *reg_info) +{ + if (CHIP_IS_E1(bp)) + return IS_E1_ONLINE(reg_info->info); + else if (CHIP_IS_E1H(bp)) + return IS_E1H_ONLINE(reg_info->info); + else if (CHIP_IS_E2(bp)) + return IS_E2_ONLINE(reg_info->info); + else if (CHIP_IS_E3A0(bp)) + return IS_E3_ONLINE(reg_info->info); + else if (CHIP_IS_E3B0(bp)) + return IS_E3B0_ONLINE(reg_info->info); + else + return false; +} + +/******* Paged registers info selectors ********/ +static inline const u32 *__bnx2x_get_page_addr_ar(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return page_vals_e2; + else if (CHIP_IS_E3(bp)) + return page_vals_e3; + else + return NULL; +} + +static inline u32 __bnx2x_get_page_reg_num(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return PAGE_MODE_VALUES_E2; + else if (CHIP_IS_E3(bp)) + return PAGE_MODE_VALUES_E3; + else + return 0; +} + +static inline const u32 *__bnx2x_get_page_write_ar(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return page_write_regs_e2; + else if (CHIP_IS_E3(bp)) + return page_write_regs_e3; + else + return NULL; +} + +static inline u32 __bnx2x_get_page_write_num(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return PAGE_WRITE_REGS_E2; + else if (CHIP_IS_E3(bp)) + return PAGE_WRITE_REGS_E3; + else + return 0; +} + +static inline const struct reg_addr *__bnx2x_get_page_read_ar(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return page_read_regs_e2; + else if (CHIP_IS_E3(bp)) + return page_read_regs_e3; + else + return NULL; +} + +static inline u32 __bnx2x_get_page_read_num(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) + return PAGE_READ_REGS_E2; + else if (CHIP_IS_E3(bp)) + return PAGE_READ_REGS_E3; + else + return 0; +} + +static inline int __bnx2x_get_regs_len(struct bnx2x *bp) +{ + int num_pages = __bnx2x_get_page_reg_num(bp); + int page_write_num = __bnx2x_get_page_write_num(bp); + const struct reg_addr *page_read_addr = __bnx2x_get_page_read_ar(bp); + int page_read_num = __bnx2x_get_page_read_num(bp); + int regdump_len = 0; + int i, j, k; + + for (i = 0; i < REGS_COUNT; i++) + if (bnx2x_is_reg_online(bp, ®_addrs[i])) + regdump_len += reg_addrs[i].size; + + for (i = 0; i < num_pages; i++) + for (j = 0; j < page_write_num; j++) + for (k = 0; k < page_read_num; k++) + if (bnx2x_is_reg_online(bp, &page_read_addr[k])) + regdump_len += page_read_addr[k].size; + + return regdump_len; +} static int bnx2x_get_regs_len(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); int regdump_len = 0; - int i, j, k; - if (CHIP_IS_E1(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E1; i++) - if (IS_E1_ONLINE(wreg_addrs_e1[i].info)) - regdump_len += wreg_addrs_e1[i].size * - (1 + wreg_addrs_e1[i].read_regs_count); - - } else if (CHIP_IS_E1H(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1H_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E1H; i++) - if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) - regdump_len += wreg_addrs_e1h[i].size * - (1 + wreg_addrs_e1h[i].read_regs_count); - } else if (!CHIP_IS_E1x(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E2_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E2; i++) - if (IS_E2_ONLINE(wreg_addrs_e2[i].info)) - regdump_len += wreg_addrs_e2[i].size * - (1 + wreg_addrs_e2[i].read_regs_count); - - for (i = 0; i < PAGE_MODE_VALUES_E2; i++) - for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { - for (k = 0; k < PAGE_READ_REGS_E2; k++) - if (IS_E2_ONLINE(page_read_regs_e2[k]. - info)) - regdump_len += - page_read_regs_e2[k].size; - } - } + regdump_len = __bnx2x_get_regs_len(bp); regdump_len *= 4; regdump_len += sizeof(struct dump_hdr); return regdump_len; } -static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p) +/** + * bnx2x_read_pages_regs - read "paged" registers + * + * @bp device handle + * @p output buffer + * + * Reads "paged" memories: memories that may only be read by first writing to a + * specific address ("write address") and then reading from a specific address + * ("read address"). There may be more than one write address per "page" and + * more than one read address per write address. + */ +static inline void bnx2x_read_pages_regs(struct bnx2x *bp, u32 *p) { u32 i, j, k, n; - - for (i = 0; i < PAGE_MODE_VALUES_E2; i++) { - for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { - REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]); - for (k = 0; k < PAGE_READ_REGS_E2; k++) - if (IS_E2_ONLINE(page_read_regs_e2[k].info)) + /* addresses of the paged registers */ + const u32 *page_addr = __bnx2x_get_page_addr_ar(bp); + /* number of paged registers */ + int num_pages = __bnx2x_get_page_reg_num(bp); + /* write addresses */ + const u32 *write_addr = __bnx2x_get_page_write_ar(bp); + /* number of write addresses */ + int write_num = __bnx2x_get_page_write_num(bp); + /* read addresses info */ + const struct reg_addr *read_addr = __bnx2x_get_page_read_ar(bp); + /* number of read addresses */ + int read_num = __bnx2x_get_page_read_num(bp); + + for (i = 0; i < num_pages; i++) { + for (j = 0; j < write_num; j++) { + REG_WR(bp, write_addr[j], page_addr[i]); + for (k = 0; k < read_num; k++) + if (bnx2x_is_reg_online(bp, &read_addr[k])) for (n = 0; n < - page_read_regs_e2[k].size; n++) + read_addr[k].size; n++) *p++ = REG_RD(bp, - page_read_regs_e2[k].addr + n*4); + read_addr[k].addr + n*4); } } } +static inline void __bnx2x_get_regs(struct bnx2x *bp, u32 *p) +{ + u32 i, j; + + /* Read the regular registers */ + for (i = 0; i < REGS_COUNT; i++) + if (bnx2x_is_reg_online(bp, ®_addrs[i])) + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); + + /* Read "paged" registes */ + bnx2x_read_pages_regs(bp, p); +} + static void bnx2x_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) { - u32 *p = _p, i, j; + u32 *p = _p; struct bnx2x *bp = netdev_priv(dev); struct dump_hdr dump_hdr = {0}; @@ -605,33 +706,9 @@ static void bnx2x_get_regs(struct net_device *dev, memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); p += dump_hdr.hdr_size + 1; - if (CHIP_IS_E1(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - - } else if (CHIP_IS_E1H(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1H_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - - } else if (!CHIP_IS_E1x(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E2_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - - if (CHIP_IS_E2(bp)) - bnx2x_read_pages_regs_e2(bp, p); - else - /* E3 paged registers read is unimplemented yet */ - WARN_ON(1); - } + /* Actually read the registers */ + __bnx2x_get_regs(bp, p); + /* Re-enable parity attentions */ bnx2x_clear_blocks_parity(bp); bnx2x_enable_blocks_parity(bp); -- cgit v1.2.3-70-g09d2 From c03bd39c564f4b5d7683514e9249986e1404940d Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Thu, 21 Jul 2011 07:57:52 +0000 Subject: bnx2x: Read FIP mac from SHMEM in single function mode Read FIP MAC address from SHMEM's "port" section similar to what we do in a MF mode when we read it from a "func" section of SHMEM. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 121df1f676e..6ee9fc8d8e7 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -9251,6 +9251,12 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, dev_info.port_hw_config[port]. iscsi_mac_lower); bnx2x_set_mac_buf(iscsi_mac, val, val2); + + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. + fcoe_fip_mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port]. + fcoe_fip_mac_lower); + bnx2x_set_mac_buf(fip_mac, val, val2); #endif } @@ -9258,13 +9264,9 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); #ifdef BCM_CNIC - /* Set the FCoE MAC in modes other then MF_SI */ - if (!CHIP_IS_E1x(bp)) { - if (IS_MF_SD(bp)) - memcpy(fip_mac, bp->dev->dev_addr, ETH_ALEN); - else if (!IS_MF(bp)) - memcpy(fip_mac, iscsi_mac, ETH_ALEN); - } + /* Set the FCoE MAC in MF_SD mode */ + if (!CHIP_IS_E1x(bp) && IS_MF_SD(bp)) + memcpy(fip_mac, bp->dev->dev_addr, ETH_ALEN); /* Disable iSCSI if MAC configuration is * invalid. -- cgit v1.2.3-70-g09d2 From 8736c82650500222c031dd7f59f0126e59808e36 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Thu, 21 Jul 2011 07:58:36 +0000 Subject: bnx2x: Parity errors recovery for 578xx Fix the parity errors recovery flow for 578xx: - Add a separate column for the 578xx in the parity mask registers DB. - Fix the bnx2x_process_kill_chip_reset() to handle the blocks newly introduced in the 578xx. Cover ATC and PGLUE_B blocks for 57712 and 578xx. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 3 ++ drivers/net/bnx2x/bnx2x_init.h | 101 ++++++++++++++++++---------------- drivers/net/bnx2x/bnx2x_main.c | 119 ++++++++++++++++++++++++++++++++--------- drivers/net/bnx2x/bnx2x_reg.h | 16 +++++- 4 files changed, 168 insertions(+), 71 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 4b255e5f8f1..c423504a755 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1920,6 +1920,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \ AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY) +#define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR) + #define RSS_FLAGS(bp) \ (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \ diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 82795a8349f..4d748e77d1a 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -326,25 +326,25 @@ struct src_ent { /**************************************************************************** * Parity configuration ****************************************************************************/ -#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2) \ +#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \ { \ block##_REG_##block##_PRTY_MASK, \ block##_REG_##block##_PRTY_STS_CLR, \ - en_mask, {m1, m1h, m2}, #block \ + en_mask, {m1, m1h, m2, m3}, #block \ } -#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2) \ +#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \ { \ block##_REG_##block##_PRTY_MASK_0, \ block##_REG_##block##_PRTY_STS_CLR_0, \ - en_mask, {m1, m1h, m2}, #block"_0" \ + en_mask, {m1, m1h, m2, m3}, #block"_0" \ } -#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2) \ +#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \ { \ block##_REG_##block##_PRTY_MASK_1, \ block##_REG_##block##_PRTY_STS_CLR_1, \ - en_mask, {m1, m1h, m2}, #block"_1" \ + en_mask, {m1, m1h, m2, m3}, #block"_1" \ } static const struct { @@ -355,6 +355,7 @@ static const struct { u32 e1; /* 57710 */ u32 e1h; /* 57711 */ u32 e2; /* 57712 */ + u32 e3; /* 578xx */ } reg_mask; /* Register mask (all valid bits) */ char name[7]; /* Block's longest name is 6 characters long * (name + suffix) @@ -372,48 +373,56 @@ static const struct { /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't * want to handle "system kill" flow at the moment. */ - BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff), - BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), - BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), - BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0), - BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff), - BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xffff), - BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff), - BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1), - BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff), - BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3), + BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff, + 0x7ffffff), + BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(PXP2, 0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff), + BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0), + BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0), + BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff, 0xffffffff), + BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xff, 0xffff), + BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1), + BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff), + BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f), + BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3), + BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3), {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf, - {0xf, 0xf, 0xf}, "UPB"}, + {0xf, 0xf, 0xf, 0xf}, "UPB"}, {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0, - {0xf, 0xf, 0xf}, "XPB"}, - BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7), - BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f), - BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf), - BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1), - BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf), - BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf), - BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff), - BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffffff), - BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f), - BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff), - BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff), - BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff), - BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff), - BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff), - BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f), - BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f), - BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f), - BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), - BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f), + {0xf, 0xf, 0xf, 0xf}, "XPB"}, + BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7), + BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f), + BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f), + BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1), + BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf), + BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf), + BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff, 0xff), + BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff), + BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f), + BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), + BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), + BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff), + BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), + BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f), + BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f), + BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff), + BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), }; @@ -464,8 +473,10 @@ static inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx) return bnx2x_blocks_parity_data[idx].reg_mask.e1; else if (CHIP_IS_E1H(bp)) return bnx2x_blocks_parity_data[idx].reg_mask.e1h; - else + else if (CHIP_IS_E2(bp)) return bnx2x_blocks_parity_data[idx].reg_mask.e2; + else /* CHIP_IS_E3 */ + return bnx2x_blocks_parity_data[idx].reg_mask.e3; } static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 6ee9fc8d8e7..e1ec1a30247 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -3817,6 +3817,10 @@ static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num, if (print) _print_next_block(par_num++, "USDM"); break; + case AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "UCM"); + break; case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR: if (print) _print_next_block(par_num++, "USEMI"); @@ -3829,6 +3833,10 @@ static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num, if (print) _print_next_block(par_num++, "CSDM"); break; + case AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "CCM"); + break; } /* Clear the bit */ @@ -3933,32 +3941,67 @@ static inline int bnx2x_check_blocks_with_parity3(u32 sig, int par_num, return par_num; } +static inline int bnx2x_check_blocks_with_parity4(u32 sig, int par_num, + bool print) +{ + int i = 0; + u32 cur_bit = 0; + for (i = 0; sig; i++) { + cur_bit = ((u32)0x1 << i); + if (sig & cur_bit) { + switch (cur_bit) { + case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "PGLUE_B"); + break; + case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR: + if (print) + _print_next_block(par_num++, "ATC"); + break; + } + + /* Clear the bit */ + sig &= ~cur_bit; + } + } + + return par_num; +} + static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, - u32 sig0, u32 sig1, u32 sig2, u32 sig3) + u32 *sig) { - if ((sig0 & HW_PRTY_ASSERT_SET_0) || (sig1 & HW_PRTY_ASSERT_SET_1) || - (sig2 & HW_PRTY_ASSERT_SET_2) || (sig3 & HW_PRTY_ASSERT_SET_3)) { + if ((sig[0] & HW_PRTY_ASSERT_SET_0) || + (sig[1] & HW_PRTY_ASSERT_SET_1) || + (sig[2] & HW_PRTY_ASSERT_SET_2) || + (sig[3] & HW_PRTY_ASSERT_SET_3) || + (sig[4] & HW_PRTY_ASSERT_SET_4)) { int par_num = 0; DP(NETIF_MSG_HW, "Was parity error: HW block parity attention: " - "[0]:0x%08x [1]:0x%08x " - "[2]:0x%08x [3]:0x%08x\n", - sig0 & HW_PRTY_ASSERT_SET_0, - sig1 & HW_PRTY_ASSERT_SET_1, - sig2 & HW_PRTY_ASSERT_SET_2, - sig3 & HW_PRTY_ASSERT_SET_3); + "[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x " + "[4]:0x%08x\n", + sig[0] & HW_PRTY_ASSERT_SET_0, + sig[1] & HW_PRTY_ASSERT_SET_1, + sig[2] & HW_PRTY_ASSERT_SET_2, + sig[3] & HW_PRTY_ASSERT_SET_3, + sig[4] & HW_PRTY_ASSERT_SET_4); if (print) netdev_err(bp->dev, "Parity errors detected in blocks: "); par_num = bnx2x_check_blocks_with_parity0( - sig0 & HW_PRTY_ASSERT_SET_0, par_num, print); + sig[0] & HW_PRTY_ASSERT_SET_0, par_num, print); par_num = bnx2x_check_blocks_with_parity1( - sig1 & HW_PRTY_ASSERT_SET_1, par_num, global, print); + sig[1] & HW_PRTY_ASSERT_SET_1, par_num, global, print); par_num = bnx2x_check_blocks_with_parity2( - sig2 & HW_PRTY_ASSERT_SET_2, par_num, print); + sig[2] & HW_PRTY_ASSERT_SET_2, par_num, print); par_num = bnx2x_check_blocks_with_parity3( - sig3 & HW_PRTY_ASSERT_SET_3, par_num, global, print); + sig[3] & HW_PRTY_ASSERT_SET_3, par_num, global, print); + par_num = bnx2x_check_blocks_with_parity4( + sig[4] & HW_PRTY_ASSERT_SET_4, par_num, print); + if (print) pr_cont("\n"); + return true; } else return false; @@ -3973,7 +4016,7 @@ static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, */ bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) { - struct attn_route attn; + struct attn_route attn = { {0} }; int port = BP_PORT(bp); attn.sig[0] = REG_RD(bp, @@ -3989,8 +4032,12 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - return bnx2x_parity_attn(bp, global, print, attn.sig[0], attn.sig[1], - attn.sig[2], attn.sig[3]); + if (!CHIP_IS_E1x(bp)) + attn.sig[4] = REG_RD(bp, + MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 + + port*4); + + return bnx2x_parity_attn(bp, global, print, attn.sig); } @@ -7932,7 +7979,7 @@ static void bnx2x_pxp_prep(struct bnx2x *bp) static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) { u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2; - u32 global_bits2; + u32 global_bits2, stay_reset2; /* * Bits that have to be set in reset_mask2 if we want to reset 'global' @@ -7942,6 +7989,7 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU | MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE; + /* Don't reset the following blocks */ not_reset_mask1 = MISC_REGISTERS_RESET_REG_1_RST_HC | MISC_REGISTERS_RESET_REG_1_RST_PXPV | @@ -7955,19 +8003,35 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) MISC_REGISTERS_RESET_REG_2_RST_RBCN | MISC_REGISTERS_RESET_REG_2_RST_GRC | MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE | - MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B; + MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B | + MISC_REGISTERS_RESET_REG_2_RST_ATC | + MISC_REGISTERS_RESET_REG_2_PGLC; + /* + * Keep the following blocks in reset: + * - all xxMACs are handled by the bnx2x_link code. + */ + stay_reset2 = + MISC_REGISTERS_RESET_REG_2_RST_BMAC0 | + MISC_REGISTERS_RESET_REG_2_RST_BMAC1 | + MISC_REGISTERS_RESET_REG_2_RST_EMAC0 | + MISC_REGISTERS_RESET_REG_2_RST_EMAC1 | + MISC_REGISTERS_RESET_REG_2_UMAC0 | + MISC_REGISTERS_RESET_REG_2_UMAC1 | + MISC_REGISTERS_RESET_REG_2_XMAC | + MISC_REGISTERS_RESET_REG_2_XMAC_SOFT; + + /* Full reset masks according to the chip */ reset_mask1 = 0xffffffff; if (CHIP_IS_E1(bp)) reset_mask2 = 0xffff; - else + else if (CHIP_IS_E1H(bp)) reset_mask2 = 0x1ffff; - - if (CHIP_IS_E3(bp)) { - reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT0; - reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT1; - } + else if (CHIP_IS_E2(bp)) + reset_mask2 = 0xfffff; + else /* CHIP_IS_E3 */ + reset_mask2 = 0x3ffffff; /* Don't reset global blocks unless we need to */ if (!global) @@ -7996,7 +8060,12 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) barrier(); mmiowb(); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, reset_mask2); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + reset_mask2 & (~stay_reset2)); + + barrier(); + mmiowb(); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1); mmiowb(); } diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 005c05af090..1e6784b7734 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -32,7 +32,11 @@ /* [R 1] ATC initalization done */ #define ATC_REG_ATC_INIT_DONE 0x1100bc /* [RC 6] Interrupt register #0 read clear */ -#define ATC_REG_ATC_INT_STS_CLR 0x1101c0 +#define ATC_REG_ATC_INT_STS_CLR 0x1101c0 +/* [RW 5] Parity mask register #0 read/write */ +#define ATC_REG_ATC_PRTY_MASK 0x1101d8 +/* [RC 5] Parity register #0 read clear */ +#define ATC_REG_ATC_PRTY_STS_CLR 0x1101d0 /* [RW 19] Interrupt mask register #0 read/write */ #define BRB1_REG_BRB1_INT_MASK 0x60128 /* [R 19] Interrupt register #0 read */ @@ -2676,8 +2680,12 @@ #define PGLUE_B_REG_PGLUE_B_INT_STS 0x9298 /* [RC 9] Interrupt register #0 read clear */ #define PGLUE_B_REG_PGLUE_B_INT_STS_CLR 0x929c +/* [RW 2] Parity mask register #0 read/write */ +#define PGLUE_B_REG_PGLUE_B_PRTY_MASK 0x92b4 /* [R 2] Parity register #0 read */ #define PGLUE_B_REG_PGLUE_B_PRTY_STS 0x92a8 +/* [RC 2] Parity register #0 read clear */ +#define PGLUE_B_REG_PGLUE_B_PRTY_STS_CLR 0x92ac /* [R 13] Details of first request received with error. [2:0] - PFID. [3] - * VF_VALID. [9:4] - VFID. [11:10] - Error Code - 0 - Indicates Completion * Timeout of a User Tx non-posted request. 1 - unsupported request. 2 - @@ -5686,8 +5694,13 @@ #define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598 #define MISC_REGISTERS_RESET_REG_2_MSTAT0 (0x1<<24) #define MISC_REGISTERS_RESET_REG_2_MSTAT1 (0x1<<25) +#define MISC_REGISTERS_RESET_REG_2_PGLC (0x1<<19) +#define MISC_REGISTERS_RESET_REG_2_RST_ATC (0x1<<17) #define MISC_REGISTERS_RESET_REG_2_RST_BMAC0 (0x1<<0) +#define MISC_REGISTERS_RESET_REG_2_RST_BMAC1 (0x1<<1) +#define MISC_REGISTERS_RESET_REG_2_RST_EMAC0 (0x1<<2) #define MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE (0x1<<14) +#define MISC_REGISTERS_RESET_REG_2_RST_EMAC1 (0x1<<3) #define MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE (0x1<<15) #define MISC_REGISTERS_RESET_REG_2_RST_GRC (0x1<<4) #define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B (0x1<<6) @@ -5700,6 +5713,7 @@ #define MISC_REGISTERS_RESET_REG_2_RST_RBCN (0x1<<9) #define MISC_REGISTERS_RESET_REG_2_SET 0x594 #define MISC_REGISTERS_RESET_REG_2_UMAC0 (0x1<<20) +#define MISC_REGISTERS_RESET_REG_2_UMAC1 (0x1<<21) #define MISC_REGISTERS_RESET_REG_2_XMAC (0x1<<22) #define MISC_REGISTERS_RESET_REG_2_XMAC_SOFT (0x1<<23) #define MISC_REGISTERS_RESET_REG_3_CLEAR 0x5a8 -- cgit v1.2.3-70-g09d2 From 7961689586d30a34c10b18ac95ba1cd72cefe725 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Thu, 21 Jul 2011 07:58:54 +0000 Subject: bnx2x: Broken self-test in SF mode on 578xx This patch fixes both the failure in the self-test on 578xx and a hole in a parity recovery flow that this failure has discovered: - internal 'pending' state in a VLAN_MAC object wasn't been cleared when the object state change was called with DRV_ONLY flag, which in particular happens when a parity error happens during the self-test. - bp->sp_state wasn't cleared in the similar circumstances as described above. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 3 +++ drivers/net/bnx2x/bnx2x_reg.h | 6 +++--- drivers/net/bnx2x/bnx2x_sp.c | 6 ++++++ 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 3aadc306c8d..5b0dba6d4ef 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2042,6 +2042,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) */ bnx2x_squeeze_objects(bp); + /* There should be no more pending SP commands at this stage */ + bp->sp_state = 0; + bp->port.pmf = 0; /* Free SKBs, SGEs, TPA pool and driver internals */ diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 1e6784b7734..02461fef875 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -371,7 +371,7 @@ mechanism. The fields are: [5:0] - message length; [12:6] - message pointer; 18:13] - next pointer. */ #define CCM_REG_XX_DESCR_TABLE 0xd0300 -#define CCM_REG_XX_DESCR_TABLE_SIZE 36 +#define CCM_REG_XX_DESCR_TABLE_SIZE 24 /* [R 7] Used to read the value of XX protection Free counter. */ #define CCM_REG_XX_FREE 0xd0184 /* [RW 6] Initial value for the credit counter; responsible for fulfilling @@ -4226,7 +4226,7 @@ mechanism. The fields are: [5:0] - length of the message; 15:6] - message pointer; 20:16] - next pointer. */ #define TCM_REG_XX_DESCR_TABLE 0x50280 -#define TCM_REG_XX_DESCR_TABLE_SIZE 32 +#define TCM_REG_XX_DESCR_TABLE_SIZE 29 /* [R 6] Use to read the value of XX protection Free counter. */ #define TCM_REG_XX_FREE 0x50178 /* [RW 6] Initial value for the credit counter; responsible for fulfilling @@ -4754,7 +4754,7 @@ mechanism. The fields are:[5:0] - message length; 14:6] - message pointer; 19:15] - next pointer. */ #define UCM_REG_XX_DESCR_TABLE 0xe0280 -#define UCM_REG_XX_DESCR_TABLE_SIZE 32 +#define UCM_REG_XX_DESCR_TABLE_SIZE 27 /* [R 6] Use to read the XX protection Free counter. */ #define UCM_REG_XX_FREE 0xe016c /* [RW 6] Initial value for the credit counter; responsible for fulfilling diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c index cce87d5e760..df52f110c6c 100644 --- a/drivers/net/bnx2x/bnx2x_sp.c +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -1689,6 +1689,12 @@ int bnx2x_config_vlan_mac( if (!bnx2x_exe_queue_empty(&o->exe_queue)) rc = 1; + if (test_bit(RAMROD_DRV_CLR_ONLY, ramrod_flags)) { + DP(BNX2X_MSG_SP, "RAMROD_DRV_CLR_ONLY requested: " + "clearing a pending bit.\n"); + raw->clear_pending(raw); + } + /* Execute commands if required */ if (cont || test_bit(RAMROD_EXEC, ramrod_flags) || test_bit(RAMROD_COMP_WAIT, ramrod_flags)) { -- cgit v1.2.3-70-g09d2 From 9e975cc291d80d5e4562d6bed15ec171e896d69b Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:50 +0000 Subject: tg3: Fix io failures after chip reset Commit f2096f94b514d88593355995d5dd276961e88af1, entitled "tg3: Add 5720 H2BMC support", needed to add code to preserve some bits set by firmware. Unfortunately the new code causes throughput to stop after a chip reset because it enables state machines before they are ready. This patch undoes the problematic code. The bits will be restored later in the init sequence. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a5ff82d3b75..5bf7671dc2b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7412,16 +7412,11 @@ static int tg3_chip_reset(struct tg3 *tp) tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } - if (tg3_flag(tp, ENABLE_APE)) - tp->mac_mode = MAC_MODE_APE_TX_EN | - MAC_MODE_APE_RX_EN | - MAC_MODE_TDE_ENABLE; - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { - tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; + tp->mac_mode = MAC_MODE_PORT_MODE_TBI; val = tp->mac_mode; } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { - tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; + tp->mac_mode = MAC_MODE_PORT_MODE_GMII; val = tp->mac_mode; } else val = 0; @@ -8559,12 +8554,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(10); } - if (tg3_flag(tp, ENABLE_APE)) - tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; - else - tp->mac_mode = 0; tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | - MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; + MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | + MAC_MODE_FHDE_ENABLE; + if (tg3_flag(tp, ENABLE_APE)) + tp->mac_mode |= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; if (!tg3_flag(tp, 5705_PLUS) && !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) -- cgit v1.2.3-70-g09d2 From be671947b5b3efc6863ff429c1f265aa38e291db Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:51 +0000 Subject: tg3: Fix link flap at 100Mbps with EEE enabled This patch increases the scope of the EEE interoperability workaround to include more asic revisions. The workarond value is tuned to workaround a link flap issue at 100Mbps. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 9 +++++---- drivers/net/tg3.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5bf7671dc2b..2a9ab99baaf 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3131,15 +3131,16 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { case ASIC_REV_5717: case ASIC_REV_57765: - if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) - tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val | - MII_TG3_DSP_CH34TP2_HIBW01); - /* Fall through */ case ASIC_REV_5719: val = MII_TG3_DSP_TAP26_ALNOKO | MII_TG3_DSP_TAP26_RMRXSTO | MII_TG3_DSP_TAP26_OPCSINPT; tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); + /* Fall through */ + case ASIC_REV_5720: + if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) + tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val | + MII_TG3_DSP_CH34TP2_HIBW01); } val = 0; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 6a43fc51d87..691539ba17b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2180,7 +2180,7 @@ #define MII_TG3_DSP_TAP26_OPCSINPT 0x0004 #define MII_TG3_DSP_AADJ1CH0 0x001f #define MII_TG3_DSP_CH34TP2 0x4022 -#define MII_TG3_DSP_CH34TP2_HIBW01 0x017b +#define MII_TG3_DSP_CH34TP2_HIBW01 0x01ff #define MII_TG3_DSP_AADJ1CH3 0x601f #define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002 #define MII_TG3_DSP_EXP1_INT_STAT 0x0f01 -- cgit v1.2.3-70-g09d2 From b715ce947f51c6637e78b262501f0c4ff9d848cc Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:52 +0000 Subject: tg3: Fix link down notify failure when EEE disabled Occasionally, when the network cable is removed after a successful autonegotiation, the device will not send a link down interrupt to the driver. This happens because of a bad interaction of an EEE workaround. The fix is to adjust the code so that the root cause condition does not happen. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 2a9ab99baaf..e0413bcce0f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1858,6 +1858,12 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) } if (!tp->setlpicnt) { + if (current_link_up == 1 && + !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { + tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); + TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); + } + val = tr32(TG3_CPMU_EEE_MODE); tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE); } @@ -1872,7 +1878,9 @@ static void tg3_phy_eee_enable(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { - tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0003); + val = MII_TG3_DSP_TAP26_ALNOKO | + MII_TG3_DSP_TAP26_RMRXSTO; + tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); } @@ -3128,13 +3136,26 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) if (!err) { u32 err2; + val = 0; + /* Advertise 100-BaseTX EEE ability */ + if (advertise & ADVERTISED_100baseT_Full) + val |= MDIO_AN_EEE_ADV_100TX; + /* Advertise 1000-BaseT EEE ability */ + if (advertise & ADVERTISED_1000baseT_Full) + val |= MDIO_AN_EEE_ADV_1000T; + err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); + if (err) + val = 0; + switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { case ASIC_REV_5717: case ASIC_REV_57765: case ASIC_REV_5719: - val = MII_TG3_DSP_TAP26_ALNOKO | - MII_TG3_DSP_TAP26_RMRXSTO | - MII_TG3_DSP_TAP26_OPCSINPT; + /* If we advertised any eee advertisements above... */ + if (val) + val = MII_TG3_DSP_TAP26_ALNOKO | + MII_TG3_DSP_TAP26_RMRXSTO | + MII_TG3_DSP_TAP26_OPCSINPT; tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); /* Fall through */ case ASIC_REV_5720: @@ -3143,15 +3164,6 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) MII_TG3_DSP_CH34TP2_HIBW01); } - val = 0; - /* Advertise 100-BaseTX EEE ability */ - if (advertise & ADVERTISED_100baseT_Full) - val |= MDIO_AN_EEE_ADV_100TX; - /* Advertise 1000-BaseT EEE ability */ - if (advertise & ADVERTISED_1000baseT_Full) - val |= MDIO_AN_EEE_ADV_1000T; - err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); - err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); if (!err) err = err2; -- cgit v1.2.3-70-g09d2 From 5baa5e9aa28baccd2a1227095c25bb3e999f250d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:53 +0000 Subject: tg3: Add 5719 and 5720 to EEE_CAP list This patch adds the 5719 and the 5720 to the list of devices that are EEE capable. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e0413bcce0f..5110ea0be91 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -13142,7 +13142,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) } if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && - ((tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 && + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 || + (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 && tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))) -- cgit v1.2.3-70-g09d2 From 9d53fa129628d4899083b06fa66b7ca10fed8eb4 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:54 +0000 Subject: tg3: Fix RSS indirection table distribution The current RSS indirection table is populated such that more traffic will hit the first RSS ring. This patch adjusts the indirection table so that the load is more evenly distributed. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5110ea0be91..e5c1bc919b4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8723,15 +8723,24 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(100); if (tg3_flag(tp, ENABLE_RSS)) { + int i = 0; u32 reg = MAC_RSS_INDIR_TBL_0; - u8 *ent = (u8 *)&val; - /* Setup the indirection table */ - for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) { - int idx = i % sizeof(val); + if (tp->irq_cnt == 2) { + for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i += 8) { + tw32(reg, 0x0); + reg += 4; + } + } else { + u32 val; - ent[idx] = i % (tp->irq_cnt - 1); - if (idx == sizeof(val) - 1) { + while (i < TG3_RSS_INDIR_TBL_SIZE) { + val = i % (tp->irq_cnt - 1); + i++; + for (; i % 8; i++) { + val <<= 4; + val |= (i % (tp->irq_cnt - 1)); + } tw32(reg, val); reg += 4; } -- cgit v1.2.3-70-g09d2 From 3aa1cdf87c0b3f2345e75c474acc32ebbf0a4724 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:55 +0000 Subject: tg3: Fix int selftest for recent devices. This patch fixes interrupt selftest failures for recent devices (57765, 5717, 5718. 5719, 5720) by disabling MSI one-shot mode and applying the status tag workaround to the selftest code. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e5c1bc919b4..f2b0839f981 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9183,7 +9183,7 @@ static int tg3_test_interrupt(struct tg3 *tp) * Turn off MSI one shot mode. Otherwise this test has no * observable way to know whether the interrupt was delivered. */ - if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) { + if (tg3_flag(tp, 57765_PLUS)) { val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); } @@ -9211,6 +9211,10 @@ static int tg3_test_interrupt(struct tg3 *tp) break; } + if (tg3_flag(tp, 57765_PLUS) && + tnapi->hw_status->status_tag != tnapi->last_tag) + tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); + msleep(10); } @@ -9225,7 +9229,7 @@ static int tg3_test_interrupt(struct tg3 *tp) if (intr_ok) { /* Reenable MSI one shot mode. */ - if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) { + if (tg3_flag(tp, 57765_PLUS)) { val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); } -- cgit v1.2.3-70-g09d2 From 535a490eaddab484c53717fe2feeba800c9cdda2 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:56 +0000 Subject: tg3: Return size from tg3_vpd_readblock() Newer VPD datablocks can exceed the size the tg3 driver is traditionally used to. This can cause some of the routines that operate on the VPD data to fail when in-fact they could have succeeded had they known the correct size. This patch fixes the problem. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f2b0839f981..bce0f22677c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10573,7 +10573,7 @@ static void tg3_get_ethtool_stats(struct net_device *dev, memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); } -static __be32 * tg3_vpd_readblock(struct tg3 *tp) +static __be32 *tg3_vpd_readblock(struct tg3 *tp, u32 *vpdlen) { int i; __be32 *buf; @@ -10640,6 +10640,8 @@ static __be32 * tg3_vpd_readblock(struct tg3 *tp) goto error; } + *vpdlen = len; + return buf; error: @@ -10659,7 +10661,7 @@ error: static int tg3_test_nvram(struct tg3 *tp) { - u32 csum, magic; + u32 csum, magic, len; __be32 *buf; int i, j, k, err = 0, size; @@ -10800,18 +10802,17 @@ static int tg3_test_nvram(struct tg3 *tp) kfree(buf); - buf = tg3_vpd_readblock(tp); + buf = tg3_vpd_readblock(tp, &len); if (!buf) return -ENOMEM; - i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN, - PCI_VPD_LRDT_RO_DATA); + i = pci_vpd_find_tag((u8 *)buf, 0, len, PCI_VPD_LRDT_RO_DATA); if (i > 0) { j = pci_vpd_lrdt_size(&((u8 *)buf)[i]); if (j < 0) goto out; - if (i + PCI_VPD_LRDT_TAG_SIZE + j > TG3_NVM_VPD_LEN) + if (i + PCI_VPD_LRDT_TAG_SIZE + j > len) goto out; i += PCI_VPD_LRDT_TAG_SIZE; @@ -13209,14 +13210,14 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) { u8 *vpd_data; unsigned int block_end, rosize, len; + u32 vpdlen; int j, i = 0; - vpd_data = (u8 *)tg3_vpd_readblock(tp); + vpd_data = (u8 *)tg3_vpd_readblock(tp, &vpdlen); if (!vpd_data) goto out_no_vpd; - i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN, - PCI_VPD_LRDT_RO_DATA); + i = pci_vpd_find_tag(vpd_data, 0, vpdlen, PCI_VPD_LRDT_RO_DATA); if (i < 0) goto out_not_found; @@ -13224,7 +13225,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize; i += PCI_VPD_LRDT_TAG_SIZE; - if (block_end > TG3_NVM_VPD_LEN) + if (block_end > vpdlen) goto out_not_found; j = pci_vpd_find_info_keyword(vpd_data, i, rosize, @@ -13249,7 +13250,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) goto partno; memcpy(tp->fw_ver, &vpd_data[j], len); - strncat(tp->fw_ver, " bc ", TG3_NVM_VPD_LEN - len - 1); + strncat(tp->fw_ver, " bc ", vpdlen - len - 1); } partno: @@ -13262,7 +13263,7 @@ partno: i += PCI_VPD_INFO_FLD_HDR_SIZE; if (len > TG3_BPN_SIZE || - (len + i) > TG3_NVM_VPD_LEN) + (len + i) > vpdlen) goto out_not_found; memcpy(tp->board_part_number, &vpd_data[i], len); -- cgit v1.2.3-70-g09d2 From bda18faf630ae3731f4b4e8f4b94a26e326c4797 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 20 Jul 2011 10:20:57 +0000 Subject: tg3: Fix NVRAM selftest failures for 5720 devs This patch fixes NVRAM selftest failures for 5720 devices by fixing the checksum area size. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bce0f22677c..80357656815 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10655,7 +10655,7 @@ error: #define NVRAM_SELFBOOT_FORMAT1_3_SIZE 0x1c #define NVRAM_SELFBOOT_FORMAT1_4_SIZE 0x20 #define NVRAM_SELFBOOT_FORMAT1_5_SIZE 0x24 -#define NVRAM_SELFBOOT_FORMAT1_6_SIZE 0x4c +#define NVRAM_SELFBOOT_FORMAT1_6_SIZE 0x50 #define NVRAM_SELFBOOT_HW_SIZE 0x20 #define NVRAM_SELFBOOT_DATA_SIZE 0x1c -- cgit v1.2.3-70-g09d2 From b37a41e390310429d4171b0f7b6c6eab04512dc0 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 20 Jul 2011 14:55:22 +0000 Subject: cnic: Fix Context ID space calculation Include FCoE CID space only for E2_PLUS devices. Remove old CID offset adjustments that are no longer needed. Signed-off-by: Michael Chan Reviewed-by: Bhanu Prakash Gollapudi Signed-off-by: David S. Miller --- drivers/net/cnic.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index ea75f65a179..455fd0dacb3 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1172,7 +1172,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->iro_arr = ethdev->iro_arr; - cp->max_cid_space = MAX_ISCSI_TBL_SZ + BNX2X_FCOE_NUM_CONNECTIONS; + cp->max_cid_space = MAX_ISCSI_TBL_SZ; cp->iscsi_start_cid = start_cid; cp->fcoe_start_cid = start_cid + MAX_ISCSI_TBL_SZ; @@ -1183,14 +1183,6 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->fcoe_init_cid = 0x10; } - if (start_cid < BNX2X_ISCSI_START_CID) { - u32 delta = BNX2X_ISCSI_START_CID - start_cid; - - cp->iscsi_start_cid = BNX2X_ISCSI_START_CID; - cp->fcoe_start_cid += delta; - cp->max_cid_space += delta; - } - cp->iscsi_tbl = kzalloc(sizeof(struct cnic_iscsi) * MAX_ISCSI_TBL_SZ, GFP_KERNEL); if (!cp->iscsi_tbl) -- cgit v1.2.3-70-g09d2 From 74e49bbdabbac34c77b280152b1de9bef9bf9be7 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 20 Jul 2011 14:55:23 +0000 Subject: cnic: Wait for all Context IDs to be deleted before sending FCOE_DESTROY_FUNC Otherwise, the firmware will not respond and we'll have to wait for timeout. Refactor the wait loop we already have into a separate function for this purpose. Signed-off-by: Michael Chan Reviewed-by: Bhanu Prakash Gollapudi Signed-off-by: David S. Miller --- drivers/net/cnic.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 455fd0dacb3..9be0c261b8b 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2448,6 +2448,30 @@ static int cnic_bnx2x_fcoe_destroy(struct cnic_dev *dev, struct kwqe *kwqe) return ret; } +static void cnic_bnx2x_delete_wait(struct cnic_dev *dev, u32 start_cid) +{ + struct cnic_local *cp = dev->cnic_priv; + u32 i; + + for (i = start_cid; i < cp->max_cid_space; i++) { + struct cnic_context *ctx = &cp->ctx_tbl[i]; + int j; + + while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + msleep(10); + + for (j = 0; j < 5; j++) { + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + break; + msleep(20); + } + + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + netdev_warn(dev->netdev, "CID %x not deleted\n", + ctx->cid); + } +} + static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) { struct fcoe_kwqe_destroy *req; @@ -2456,6 +2480,8 @@ static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) int ret; u32 cid; + cnic_bnx2x_delete_wait(dev, MAX_ISCSI_TBL_SZ); + req = (struct fcoe_kwqe_destroy *) kwqe; cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); @@ -3930,7 +3956,6 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode) static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - int i; if (!cp->ctx_tbl) return; @@ -3938,23 +3963,7 @@ static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) if (!netif_running(dev->netdev)) return; - for (i = 0; i < cp->max_cid_space; i++) { - struct cnic_context *ctx = &cp->ctx_tbl[i]; - int j; - - while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) - msleep(10); - - for (j = 0; j < 5; j++) { - if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) - break; - msleep(20); - } - - if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) - netdev_warn(dev->netdev, "CID %x not deleted\n", - ctx->cid); - } + cnic_bnx2x_delete_wait(dev, 0); cancel_delayed_work(&cp->delete_task); flush_workqueue(cnic_wq); -- cgit v1.2.3-70-g09d2 From 415199f2bd977fa4065d4e836b4b7543f7993bc3 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 20 Jul 2011 14:55:24 +0000 Subject: cnic: Add VLAN ID as a parameter during netevent upcall The bnx2fc driver needs to handle netdev events on VLAN devices. Signed-off-by: Michael Chan Reviewed-by: Bhanu Prakash Gollapudi Signed-off-by: David S. Miller --- drivers/net/cnic.c | 50 +++++++++++++++++++++++++++------------ drivers/net/cnic_if.h | 6 ++--- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 8 ++++++- drivers/scsi/bnx2i/bnx2i_hwi.c | 8 ++++++- 4 files changed, 52 insertions(+), 20 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 9be0c261b8b..94a2e541006 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -5334,6 +5334,27 @@ static struct cnic_dev *is_cnic_dev(struct net_device *dev) return cdev; } +static void cnic_rcv_netevent(struct cnic_local *cp, unsigned long event, + u16 vlan_id) +{ + int if_type; + + rcu_read_lock(); + for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { + struct cnic_ulp_ops *ulp_ops; + void *ctx; + + ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); + if (!ulp_ops || !ulp_ops->indicate_netevent) + continue; + + ctx = cp->ulp_handle[if_type]; + + ulp_ops->indicate_netevent(ctx, event, vlan_id); + } + rcu_read_unlock(); +} + /** * netdev event handler */ @@ -5342,7 +5363,6 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, { struct net_device *netdev = ptr; struct cnic_dev *dev; - int if_type; int new_dev = 0; dev = cnic_from_netdev(netdev); @@ -5372,20 +5392,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, cnic_ulp_start(dev); } - rcu_read_lock(); - for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { - struct cnic_ulp_ops *ulp_ops; - void *ctx; - - ulp_ops = rcu_dereference(cp->ulp_ops[if_type]); - if (!ulp_ops || !ulp_ops->indicate_netevent) - continue; - - ctx = cp->ulp_handle[if_type]; - - ulp_ops->indicate_netevent(ctx, event); - } - rcu_read_unlock(); + cnic_rcv_netevent(cp, event, 0); if (event == NETDEV_GOING_DOWN) { cnic_ulp_stop(dev); @@ -5401,6 +5408,19 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event, goto done; } cnic_put(dev); + } else { + struct net_device *realdev; + u16 vid; + + vid = cnic_get_vlan(netdev, &realdev); + if (realdev) { + dev = cnic_from_netdev(realdev); + if (dev) { + vid |= VLAN_TAG_PRESENT; + cnic_rcv_netevent(dev->cnic_priv, event, vid); + cnic_put(dev); + } + } } done: return NOTIFY_DONE; diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 8a1ffbe123b..79443e0dbf9 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.5.6" -#define CNIC_MODULE_RELDATE "July 12, 2011" +#define CNIC_MODULE_VERSION "2.5.7" +#define CNIC_MODULE_RELDATE "July 20, 2011" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -318,7 +318,7 @@ struct cnic_ulp_ops { void (*cnic_stop)(void *ulp_ctx); void (*indicate_kcqes)(void *ulp_ctx, struct kcqe *cqes[], u32 num_cqes); - void (*indicate_netevent)(void *ulp_ctx, unsigned long event); + void (*indicate_netevent)(void *ulp_ctx, unsigned long event, u16 vid); void (*cm_connect_complete)(struct cnic_sock *); void (*cm_close_complete)(struct cnic_sock *); void (*cm_abort_complete)(struct cnic_sock *); diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 7a16ca1c3ec..9eebaebdaa7 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -767,17 +767,23 @@ static void bnx2fc_destroy_timer(unsigned long data) * * @context: adapter structure pointer * @event: event type + * @vlan_id: vlan id - associated vlan id with this event * * Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and * NETDEV_CHANGE_MTU events */ -static void bnx2fc_indicate_netevent(void *context, unsigned long event) +static void bnx2fc_indicate_netevent(void *context, unsigned long event, + u16 vlan_id) { struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; struct fc_lport *lport = hba->ctlr.lp; struct fc_lport *vport; u32 link_possible = 1; + /* Ignore vlans for now */ + if (vlan_id != 0) + return; + if (!test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { BNX2FC_MISC_DBG("driver not ready. event=%s %ld\n", hba->netdev->name, event); diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 5c54a2d9b83..372d30c099c 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2386,14 +2386,20 @@ static void bnx2i_indicate_kcqe(void *context, struct kcqe *kcqe[], * bnx2i_indicate_netevent - Generic netdev event handler * @context: adapter structure pointer * @event: event type + * @vlan_id: vlans id - associated vlan id with this event * * Handles four netdev events, NETDEV_UP, NETDEV_DOWN, * NETDEV_GOING_DOWN and NETDEV_CHANGE */ -static void bnx2i_indicate_netevent(void *context, unsigned long event) +static void bnx2i_indicate_netevent(void *context, unsigned long event, + u16 vlan_id) { struct bnx2i_hba *hba = context; + /* Ignore all netevent coming from vlans */ + if (vlan_id != 0) + return; + switch (event) { case NETDEV_UP: if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) -- cgit v1.2.3-70-g09d2 From 3aeb7d2243e55ddcad3c0b402e7b09619a67f5da Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 20 Jul 2011 14:55:25 +0000 Subject: bnx2: Fix endian swapping on firmware version string so that ethtool -i will display it correctly on big endian systems. Signed-off-by: Michael Chan Reviewed-by: Bhanu Prakash Gollapudi Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 3ad9b70ef1b..4b2b57018a0 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.1.10" -#define DRV_MODULE_RELDATE "July 12, 2011" +#define DRV_MODULE_VERSION "2.1.11" +#define DRV_MODULE_RELDATE "July 20, 2011" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1a.fw" @@ -8097,7 +8097,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->fw_version[j++] = ' '; for (i = 0; i < 3 && j < 28; i++) { reg = bnx2_reg_rd_ind(bp, addr + i * 4); - reg = swab32(reg); + reg = be32_to_cpu(reg); memcpy(&bp->fw_version[j], ®, 4); j += 4; } -- cgit v1.2.3-70-g09d2 From b49500957a2c90a559dd91f0dcfeb83d84458664 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:07 +0000 Subject: ehea: do vlan cleanup - unify vlan and nonvlan rx path - kill port->vgrp and ehea_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ehea/ehea.h | 1 - drivers/net/ehea/ehea_main.c | 54 ++++++-------------------------------------- 2 files changed, 7 insertions(+), 48 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 6c7257bd73f..7dd5e6a0d99 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -457,7 +457,6 @@ struct ehea_port { struct ehea_port_res port_res[EHEA_MAX_PORT_RES]; struct platform_device ofdev; /* Open Firmware Device */ struct ehea_mc_list *mc_list; /* Multicast MAC addresses */ - struct vlan_group *vgrp; struct ehea_eq *qp_eq; struct work_struct reset_task; struct mutex port_lock; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3fd5a240034..be2cb4ab8b4 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -683,24 +683,13 @@ static int get_skb_hdr(struct sk_buff *skb, void **iphdr, static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe, struct sk_buff *skb) { - int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && - pr->port->vgrp); - - if (skb->dev->features & NETIF_F_LRO) { - if (vlan_extracted) - lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, - pr->port->vgrp, - cqe->vlan_tag, - cqe); - else - lro_receive_skb(&pr->lro_mgr, skb, cqe); - } else { - if (vlan_extracted) - vlan_hwaccel_receive_skb(skb, pr->port->vgrp, - cqe->vlan_tag); - else - netif_receive_skb(skb); - } + if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) + __vlan_hwaccel_put_tag(skb, cqe->vlan_tag); + + if (skb->dev->features & NETIF_F_LRO) + lro_receive_skb(&pr->lro_mgr, skb, cqe); + else + netif_receive_skb(skb); } static int ehea_proc_rwqes(struct net_device *dev, @@ -2339,32 +2328,6 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static void ehea_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct ehea_port *port = netdev_priv(dev); - struct ehea_adapter *adapter = port->adapter; - struct hcp_ehea_port_cb1 *cb1; - u64 hret; - - port->vgrp = grp; - - cb1 = (void *)get_zeroed_page(GFP_KERNEL); - if (!cb1) { - pr_err("no mem for cb1\n"); - goto out; - } - - hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, - H_PORT_CB1, H_PORT_CB1_ALL, cb1); - if (hret != H_SUCCESS) - pr_err("modify_ehea_port failed\n"); - - free_page((unsigned long)cb1); -out: - return; -} - static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct ehea_port *port = netdev_priv(dev); @@ -2406,8 +2369,6 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) int index; u64 hret; - vlan_group_set_device(port->vgrp, vid, NULL); - cb1 = (void *)get_zeroed_page(GFP_KERNEL); if (!cb1) { pr_err("no mem for cb1\n"); @@ -3202,7 +3163,6 @@ static const struct net_device_ops ehea_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = ehea_set_multicast_list, .ndo_change_mtu = ehea_change_mtu, - .ndo_vlan_rx_register = ehea_vlan_rx_register, .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid, .ndo_tx_timeout = ehea_tx_watchdog, -- cgit v1.2.3-70-g09d2 From c8d9e6dd484a2e10875d2c277f7e8584b92779e5 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:11 +0000 Subject: amd8111e: do vlan cleanup - unify vlan and nonvlan rx path - kill lp->vlgrp and amd8111e_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/amd8111e.c | 34 ++++++---------------------------- drivers/net/amd8111e.h | 3 --- 2 files changed, 6 insertions(+), 31 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index db6d2da5a8f..78002ef9c0e 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -661,15 +661,6 @@ static void amd8111e_free_ring(struct amd8111e_priv* lp) } } -#if AMD8111E_VLAN_TAG_USED -/* -This is the receive indication function for packets with vlan tag. -*/ -static int amd8111e_vlan_rx(struct amd8111e_priv *lp, struct sk_buff *skb, u16 vlan_tag) -{ - return vlan_hwaccel_receive_skb(skb, lp->vlgrp,vlan_tag); -} -#endif /* This function will free all the transmit skbs that are actually transmitted by the device. It will check the ownership of the skb before freeing the skb. @@ -764,7 +755,7 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) #if AMD8111E_VLAN_TAG_USED vtag = status & TT_MASK; /*MAC will strip vlan tag*/ - if(lp->vlgrp != NULL && vtag !=0) + if (vtag != 0) min_pkt_len =MIN_PKT_LEN - 4; else #endif @@ -799,12 +790,12 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) skb->protocol = eth_type_trans(skb, dev); #if AMD8111E_VLAN_TAG_USED - if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){ - amd8111e_vlan_rx(lp, skb, - le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info)); - } else + if (vtag == TT_VLAN_TAGGED){ + u16 vlan_tag = le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info); + __vlan_hwaccel_put_tag(skb, vlan_tag); + } #endif - netif_receive_skb(skb); + netif_receive_skb(skb); /*COAL update rx coalescing parameters*/ lp->coal_conf.rx_packets++; lp->coal_conf.rx_bytes += pkt_len; @@ -1598,16 +1589,6 @@ static int amd8111e_change_mtu(struct net_device *dev, int new_mtu) return err; } -#if AMD8111E_VLAN_TAG_USED -static void amd8111e_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct amd8111e_priv *lp = netdev_priv(dev); - spin_lock_irq(&lp->lock); - lp->vlgrp = grp; - spin_unlock_irq(&lp->lock); -} -#endif - static int amd8111e_enable_magicpkt(struct amd8111e_priv* lp) { writel( VAL1|MPPLBA, lp->mmio + CMD3); @@ -1822,9 +1803,6 @@ static const struct net_device_ops amd8111e_netdev_ops = { .ndo_set_mac_address = amd8111e_set_mac_address, .ndo_do_ioctl = amd8111e_ioctl, .ndo_change_mtu = amd8111e_change_mtu, -#if AMD8111E_VLAN_TAG_USED - .ndo_vlan_rx_register = amd8111e_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = amd8111e_poll, #endif diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h index b5926af03a7..2ff2e7a12dd 100644 --- a/drivers/net/amd8111e.h +++ b/drivers/net/amd8111e.h @@ -783,9 +783,6 @@ struct amd8111e_priv{ struct net_device *next; int mii; struct mii_if_info mii_if; -#if AMD8111E_VLAN_TAG_USED - struct vlan_group *vlgrp; -#endif char opened; unsigned int drv_rx_errors; struct amd8111e_coalesce_conf coal_conf; -- cgit v1.2.3-70-g09d2 From 46facce9130ee5a4e4863094049af85c4a757356 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:12 +0000 Subject: atl1c: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and atl1c_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c.h | 1 - drivers/net/atl1c/atl1c_main.c | 74 ++++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 29 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 0f481b983bc..ca70e16b6e2 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h @@ -555,7 +555,6 @@ struct atl1c_smb { struct atl1c_adapter { struct net_device *netdev; struct pci_dev *pdev; - struct vlan_group *vlgrp; struct napi_struct napi; struct atl1c_hw hw; struct atl1c_hw_stats hw_stats; diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 1269ba5d6e5..97224421840 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -411,29 +411,29 @@ static void atl1c_set_multi(struct net_device *netdev) } } -static void atl1c_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atl1c_vlan_mode(u32 features, u32 *mac_ctrl_data) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atl1c_vlan_mode(struct net_device *netdev, u32 features) { struct atl1c_adapter *adapter = netdev_priv(netdev); struct pci_dev *pdev = adapter->pdev; u32 mac_ctrl_data = 0; if (netif_msg_pktdata(adapter)) - dev_dbg(&pdev->dev, "atl1c_vlan_rx_register\n"); + dev_dbg(&pdev->dev, "atl1c_vlan_mode\n"); atl1c_irq_disable(adapter); - - adapter->vlgrp = grp; AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data); - - if (grp) { - /* enable VLAN tag insert/strip */ - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; - } else { - /* disable VLAN tag insert/strip */ - mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; - } - + __atl1c_vlan_mode(features, &mac_ctrl_data); AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); atl1c_irq_enable(adapter); } @@ -443,9 +443,10 @@ static void atl1c_restore_vlan(struct atl1c_adapter *adapter) struct pci_dev *pdev = adapter->pdev; if (netif_msg_pktdata(adapter)) - dev_dbg(&pdev->dev, "atl1c_restore_vlan !"); - atl1c_vlan_rx_register(adapter->netdev, adapter->vlgrp); + dev_dbg(&pdev->dev, "atl1c_restore_vlan\n"); + atl1c_vlan_mode(adapter->netdev, adapter->netdev->features); } + /* * atl1c_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure @@ -483,12 +484,31 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, static u32 atl1c_fix_features(struct net_device *netdev, u32 features) { + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + if (netdev->mtu > MAX_TSO_FRAME_SIZE) features &= ~(NETIF_F_TSO | NETIF_F_TSO6); return features; } +static int atl1c_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atl1c_vlan_mode(netdev, features); + + return 0; +} + /* * atl1c_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -1433,8 +1453,7 @@ static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + __atl1c_vlan_mode(netdev->features, &mac_ctrl_data); mac_ctrl_data |= MAC_CTRL_BC_EN; if (netdev->flags & IFF_PROMISC) @@ -1878,14 +1897,14 @@ rrs_checked: skb_put(skb, length - ETH_FCS_LEN); skb->protocol = eth_type_trans(skb, netdev); atl1c_rx_checksum(adapter, skb, rrs); - if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) { + if (rrs->word3 & RRS_VLAN_INS) { u16 vlan; AT_TAG_TO_VLAN(rrs->vlan_tag, vlan); vlan = le16_to_cpu(vlan); - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan); - } else - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, vlan); + } + netif_receive_skb(skb); (*work_done)++; count++; @@ -2507,8 +2526,7 @@ static int atl1c_suspend(struct device *dev) /* clear phy interrupt */ atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data); /* Config MAC Ctrl register */ - if (adapter->vlgrp) - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + __atl1c_vlan_mode(netdev->features, &mac_ctrl_data); /* magic packet maybe Broadcast&multicast&Unicast frame */ if (wufc & AT_WUFC_MAG) @@ -2581,14 +2599,14 @@ static const struct net_device_ops atl1c_netdev_ops = { .ndo_stop = atl1c_close, .ndo_validate_addr = eth_validate_addr, .ndo_start_xmit = atl1c_xmit_frame, - .ndo_set_mac_address = atl1c_set_mac_addr, + .ndo_set_mac_address = atl1c_set_mac_addr, .ndo_set_multicast_list = atl1c_set_multi, .ndo_change_mtu = atl1c_change_mtu, .ndo_fix_features = atl1c_fix_features, + .ndo_set_features = atl1c_set_features, .ndo_do_ioctl = atl1c_ioctl, .ndo_tx_timeout = atl1c_tx_timeout, .ndo_get_stats = atl1c_get_stats, - .ndo_vlan_rx_register = atl1c_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl1c_netpoll, #endif @@ -2607,11 +2625,11 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) /* TODO: add when ready */ netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_TSO6; netdev->features = netdev->hw_features | - NETIF_F_HW_VLAN_RX; + NETIF_F_HW_VLAN_TX; return 0; } -- cgit v1.2.3-70-g09d2 From 2707fffc0f330662d75ff609470700100392673f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:13 +0000 Subject: atl1e: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and atl1e_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/atl1e/atl1e.h | 1 - drivers/net/atl1e/atl1e_main.c | 79 ++++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 30 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index 8c8181b5328..829b5ad71d0 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h @@ -433,7 +433,6 @@ struct atl1e_rx_ring { struct atl1e_adapter { struct net_device *netdev; struct pci_dev *pdev; - struct vlan_group *vlgrp; struct napi_struct napi; struct mii_if_info mii; /* MII interface info */ struct atl1e_hw hw; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index c3c5db13cf2..d8d411998fa 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -313,8 +313,18 @@ static void atl1e_set_multi(struct net_device *netdev) } } -static void atl1e_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atl1e_vlan_mode(u32 features, u32 *mac_ctrl_data) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atl1e_vlan_mode(struct net_device *netdev, u32 features) { struct atl1e_adapter *adapter = netdev_priv(netdev); u32 mac_ctrl_data = 0; @@ -322,18 +332,8 @@ static void atl1e_vlan_rx_register(struct net_device *netdev, netdev_dbg(adapter->netdev, "%s\n", __func__); atl1e_irq_disable(adapter); - - adapter->vlgrp = grp; mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL); - - if (grp) { - /* enable VLAN tag insert/strip */ - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; - } else { - /* disable VLAN tag insert/strip */ - mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; - } - + __atl1e_vlan_mode(features, &mac_ctrl_data); AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); atl1e_irq_enable(adapter); } @@ -341,8 +341,9 @@ static void atl1e_vlan_rx_register(struct net_device *netdev, static void atl1e_restore_vlan(struct atl1e_adapter *adapter) { netdev_dbg(adapter->netdev, "%s\n", __func__); - atl1e_vlan_rx_register(adapter->netdev, adapter->vlgrp); + atl1e_vlan_mode(adapter->netdev, adapter->netdev->features); } + /* * atl1e_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure @@ -369,6 +370,30 @@ static int atl1e_set_mac_addr(struct net_device *netdev, void *p) return 0; } +static u32 atl1e_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int atl1e_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atl1e_vlan_mode(netdev, features); + + return 0; +} + /* * atl1e_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -1039,8 +1064,7 @@ static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter) value |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; + __atl1e_vlan_mode(netdev->features, &value); value |= MAC_CTRL_BC_EN; if (netdev->flags & IFF_PROMISC) @@ -1423,19 +1447,16 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, skb->protocol = eth_type_trans(skb, netdev); atl1e_rx_checksum(adapter, skb, prrs); - if (unlikely(adapter->vlgrp && - (prrs->pkt_flag & RRS_IS_VLAN_TAG))) { + if (prrs->pkt_flag & RRS_IS_VLAN_TAG) { u16 vlan_tag = (prrs->vtag >> 4) | ((prrs->vtag & 7) << 13) | ((prrs->vtag & 8) << 9); netdev_dbg(netdev, "RXD VLAN TAG=0x%04x\n", prrs->vtag); - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - vlan_tag); - } else { - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, vlan_tag); } + netif_receive_skb(skb); skip_pkt: /* skip current packet whether it's ok or not. */ @@ -1811,7 +1832,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, tpd = atl1e_get_tpd(adapter); - if (unlikely(vlan_tx_tag_present(skb))) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); u16 atl1e_vlan_tag; @@ -2093,8 +2114,7 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state) MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + __atl1e_vlan_mode(netdev->features, &mac_ctrl_data); /* magic packet maybe Broadcast&multicast&Unicast frame */ if (wufc & AT_WUFC_MAG) @@ -2195,10 +2215,11 @@ static const struct net_device_ops atl1e_netdev_ops = { .ndo_set_multicast_list = atl1e_set_multi, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl1e_set_mac_addr, + .ndo_fix_features = atl1e_fix_features, + .ndo_set_features = atl1e_set_features, .ndo_change_mtu = atl1e_change_mtu, .ndo_do_ioctl = atl1e_ioctl, .ndo_tx_timeout = atl1e_tx_timeout, - .ndo_vlan_rx_register = atl1e_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl1e_netpoll, #endif @@ -2217,9 +2238,9 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) atl1e_set_ethtool_ops(netdev); netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO | - NETIF_F_HW_VLAN_TX; - netdev->features = netdev->hw_features | - NETIF_F_HW_VLAN_RX | NETIF_F_LLTX; + NETIF_F_HW_VLAN_RX; + netdev->features = netdev->hw_features | NETIF_F_LLTX | + NETIF_F_HW_VLAN_TX; return 0; } -- cgit v1.2.3-70-g09d2 From f859d7cb7967efaedae194dd90a23a7a72fb216d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:14 +0000 Subject: bnad: do vlan cleanup - unify vlan and nonvlan rx path - kill bnad->vlan_grp and bnad_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 55 ++++++++++++++++---------------------------------- drivers/net/bna/bnad.h | 3 ++- 2 files changed, 19 insertions(+), 39 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index fa997bfc2e5..c89c9b28cb7 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -15,6 +15,7 @@ * All rights reserved * www.brocade.com */ +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include "bnad.h" #include "bna.h" @@ -514,24 +516,16 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) rcb->rxq->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, bnad->netdev); - if (bnad->vlan_grp && (flags & BNA_CQ_EF_VLAN)) { - struct bnad_rx_ctrl *rx_ctrl = - (struct bnad_rx_ctrl *)ccb->ctrl; - if (skb->ip_summed == CHECKSUM_UNNECESSARY) - vlan_gro_receive(&rx_ctrl->napi, bnad->vlan_grp, - ntohs(cmpl->vlan_tag), skb); - else - vlan_hwaccel_receive_skb(skb, - bnad->vlan_grp, - ntohs(cmpl->vlan_tag)); - - } else { /* Not VLAN tagged/stripped */ - struct bnad_rx_ctrl *rx_ctrl = - (struct bnad_rx_ctrl *)ccb->ctrl; - if (skb->ip_summed == CHECKSUM_UNNECESSARY) - napi_gro_receive(&rx_ctrl->napi, skb); - else - netif_receive_skb(skb); + if (flags & BNA_CQ_EF_VLAN) + __vlan_hwaccel_put_tag(skb, ntohs(cmpl->vlan_tag)); + + if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + struct bnad_rx_ctrl *rx_ctrl; + + rx_ctrl = (struct bnad_rx_ctrl *) ccb->ctrl; + napi_gro_receive(&rx_ctrl->napi, skb); + } else { + netif_receive_skb(skb); } next: @@ -1981,19 +1975,14 @@ bnad_enable_default_bcast(struct bnad *bnad) static void bnad_restore_vlans(struct bnad *bnad, u32 rx_id) { - u16 vlan_id; + u16 vid; unsigned long flags; - if (!bnad->vlan_grp) - return; - BUG_ON(!(VLAN_N_VID == (BFI_MAX_VLAN + 1))); - for (vlan_id = 0; vlan_id < VLAN_N_VID; vlan_id++) { - if (!vlan_group_get_device(bnad->vlan_grp, vlan_id)) - continue; + for_each_set_bit(vid, bnad->active_vlans, VLAN_N_VID) { spin_lock_irqsave(&bnad->bna_lock, flags); - bna_rx_vlan_add(bnad->rx_info[rx_id].rx, vlan_id); + bna_rx_vlan_add(bnad->rx_info[rx_id].rx, vid); spin_unlock_irqrestore(&bnad->bna_lock, flags); } } @@ -2795,17 +2784,6 @@ bnad_change_mtu(struct net_device *netdev, int new_mtu) return err; } -static void -bnad_vlan_rx_register(struct net_device *netdev, - struct vlan_group *vlan_grp) -{ - struct bnad *bnad = netdev_priv(netdev); - - mutex_lock(&bnad->conf_mutex); - bnad->vlan_grp = vlan_grp; - mutex_unlock(&bnad->conf_mutex); -} - static void bnad_vlan_rx_add_vid(struct net_device *netdev, unsigned short vid) @@ -2820,6 +2798,7 @@ bnad_vlan_rx_add_vid(struct net_device *netdev, spin_lock_irqsave(&bnad->bna_lock, flags); bna_rx_vlan_add(bnad->rx_info[0].rx, vid); + set_bit(vid, bnad->active_vlans); spin_unlock_irqrestore(&bnad->bna_lock, flags); mutex_unlock(&bnad->conf_mutex); @@ -2838,6 +2817,7 @@ bnad_vlan_rx_kill_vid(struct net_device *netdev, mutex_lock(&bnad->conf_mutex); spin_lock_irqsave(&bnad->bna_lock, flags); + clear_bit(vid, bnad->active_vlans); bna_rx_vlan_del(bnad->rx_info[0].rx, vid); spin_unlock_irqrestore(&bnad->bna_lock, flags); @@ -2887,7 +2867,6 @@ static const struct net_device_ops bnad_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = bnad_set_mac_address, .ndo_change_mtu = bnad_change_mtu, - .ndo_vlan_rx_register = bnad_vlan_rx_register, .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index ccdabad0a40..7aa550b6182 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -24,6 +24,7 @@ #include #include #include +#include /* Fix for IA64 */ #include @@ -216,7 +217,7 @@ struct bnad { struct bnad_tx_info tx_info[BNAD_MAX_TXS]; struct bnad_rx_info rx_info[BNAD_MAX_RXS]; - struct vlan_group *vlan_grp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; /* * These q numbers are global only because * they are used to calculate MSIx vectors. -- cgit v1.2.3-70-g09d2 From 133b08513a99d44d9ed916bb83e46343f6ad2855 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:15 +0000 Subject: chelsio: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlan_grp and t1_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/chelsio/common.h | 2 -- drivers/net/chelsio/cxgb2.c | 39 +++++++++++++++++++++++++-------------- drivers/net/chelsio/sge.c | 18 ++++++++---------- drivers/net/chelsio/sge.h | 2 +- 4 files changed, 34 insertions(+), 27 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index c26d863e169..5ccbed1784d 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h @@ -240,8 +240,6 @@ struct adapter { struct work_struct ext_intr_handler_task; struct adapter_params params; - struct vlan_group *vlan_grp; - /* Terminator modules. */ struct sge *sge; struct peespi *espi; diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index b422d83f534..3edbbc4c511 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -263,6 +263,8 @@ static int cxgb_open(struct net_device *dev) if (!other_ports && adapter->params.stats_update_period) schedule_mac_stats_update(adapter, adapter->params.stats_update_period); + + t1_vlan_mode(adapter, dev->features); return 0; } @@ -849,19 +851,30 @@ static int t1_set_mac_addr(struct net_device *dev, void *p) return 0; } -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -static void t1_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) +static u32 t1_fix_features(struct net_device *dev, u32 features) { - struct adapter *adapter = dev->ml_priv; + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; - spin_lock_irq(&adapter->async_lock); - adapter->vlan_grp = grp; - t1_set_vlan_accel(adapter, grp != NULL); - spin_unlock_irq(&adapter->async_lock); + return features; } -#endif +static int t1_set_features(struct net_device *dev, u32 features) +{ + u32 changed = dev->features ^ features; + struct adapter *adapter = dev->ml_priv; + + if (changed & NETIF_F_HW_VLAN_RX) + t1_vlan_mode(adapter, features); + + return 0; +} #ifdef CONFIG_NET_POLL_CONTROLLER static void t1_netpoll(struct net_device *dev) { @@ -955,9 +968,8 @@ static const struct net_device_ops cxgb_netdev_ops = { .ndo_do_ioctl = t1_ioctl, .ndo_change_mtu = t1_change_mtu, .ndo_set_mac_address = t1_set_mac_addr, -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - .ndo_vlan_rx_register = t1_vlan_rx_register, -#endif + .ndo_fix_features = t1_fix_features, + .ndo_set_features = t1_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = t1_netpoll, #endif @@ -1080,10 +1092,9 @@ static int __devinit init_one(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; if (vlan_tso_capable(adapter)) { -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif + netdev->hw_features |= NETIF_F_HW_VLAN_RX; /* T204: disable TSO */ if (!(is_T2(adapter)) || bi->port_number != 4) { diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 58380d24061..e9a03fffef1 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -742,13 +742,14 @@ static inline void setup_ring_params(struct adapter *adapter, u64 addr, /* * Enable/disable VLAN acceleration. */ -void t1_set_vlan_accel(struct adapter *adapter, int on_off) +void t1_vlan_mode(struct adapter *adapter, u32 features) { struct sge *sge = adapter->sge; - sge->sge_control &= ~F_VLAN_XTRACT; - if (on_off) + if (features & NETIF_F_HW_VLAN_RX) sge->sge_control |= F_VLAN_XTRACT; + else + sge->sge_control &= ~F_VLAN_XTRACT; if (adapter->open_device_map) { writel(sge->sge_control, adapter->regs + A_SG_CONTROL); readl(adapter->regs + A_SG_CONTROL); /* flush */ @@ -1397,12 +1398,11 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) } else skb_checksum_none_assert(skb); - if (unlikely(adapter->vlan_grp && p->vlan_valid)) { + if (p->vlan_valid) { st->vlan_xtract++; - vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, - ntohs(p->vlan)); - } else - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, ntohs(p->vlan)); + } + netif_receive_skb(skb); } /* @@ -1875,13 +1875,11 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev) } cpl->iff = dev->if_port; -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) if (vlan_tx_tag_present(skb)) { cpl->vlan_valid = 1; cpl->vlan = htons(vlan_tx_tag_get(skb)); st->vlan_insert++; } else -#endif cpl->vlan_valid = 0; send: diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h index 00cc37fc1f6..e03980bcdd6 100644 --- a/drivers/net/chelsio/sge.h +++ b/drivers/net/chelsio/sge.h @@ -79,7 +79,7 @@ irqreturn_t t1_interrupt(int irq, void *cookie); int t1_poll(struct napi_struct *, int); netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev); -void t1_set_vlan_accel(struct adapter *adapter, int on_off); +void t1_vlan_mode(struct adapter *adapter, u32 features); void t1_sge_start(struct sge *); void t1_sge_stop(struct sge *); int t1_sge_intr_error_handler(struct sge *); -- cgit v1.2.3-70-g09d2 From 87737663d5d7668c8553c572a5a7c26e86c5842b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:16 +0000 Subject: cxgb4vf: do vlan cleanup - unify vlan and nonvlan rx path - kill pi->vlan_grp and cxgb4vf_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/adapter.h | 1 - drivers/net/cxgb4vf/cxgb4vf_main.c | 50 +++++++++++++++++++++++++------------- drivers/net/cxgb4vf/sge.c | 34 ++++++-------------------- 3 files changed, 40 insertions(+), 45 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h index 6e9a8d9ef59..594334d5c71 100644 --- a/drivers/net/cxgb4vf/adapter.h +++ b/drivers/net/cxgb4vf/adapter.h @@ -92,7 +92,6 @@ struct sge_rspq; */ struct port_info { struct adapter *adapter; /* our adapter */ - struct vlan_group *vlan_grp; /* out VLAN group */ u16 viid; /* virtual interface ID */ s16 xact_addr_filt; /* index of our MAC address filter */ u16 rss_size; /* size of VI's RSS table slice */ diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 3942a825b3d..ec799139dfe 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -209,18 +209,8 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) * ====================== */ -/* - * Record our new VLAN Group and enable/disable hardware VLAN Tag extraction - * based on whether the specified VLAN Group pointer is NULL or not. - */ -static void cxgb4vf_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct port_info *pi = netdev_priv(dev); - pi->vlan_grp = grp; - t4vf_set_rxmode(pi->adapter, pi->viid, -1, -1, -1, -1, grp != NULL, 0); -} + /* * Perform the MAC and PHY actions needed to enable a "port" (Virtual @@ -233,9 +223,9 @@ static int link_start(struct net_device *dev) /* * We do not set address filters and promiscuity here, the stack does - * that step explicitly. + * that step explicitly. Enable vlan accel. */ - ret = t4vf_set_rxmode(pi->adapter, pi->viid, dev->mtu, -1, -1, -1, -1, + ret = t4vf_set_rxmode(pi->adapter, pi->viid, dev->mtu, -1, -1, -1, 1, true); if (ret == 0) { ret = t4vf_change_mac(pi->adapter, pi->viid, @@ -1102,6 +1092,32 @@ static int cxgb4vf_change_mtu(struct net_device *dev, int new_mtu) return ret; } +static u32 cxgb4vf_fix_features(struct net_device *dev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int cxgb4vf_set_features(struct net_device *dev, u32 features) +{ + struct port_info *pi = netdev_priv(dev); + u32 changed = dev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + t4vf_set_rxmode(pi->adapter, pi->viid, -1, -1, -1, -1, + features & NETIF_F_HW_VLAN_TX, 0); + + return 0; +} + /* * Change the devices MAC address. */ @@ -2431,7 +2447,8 @@ static const struct net_device_ops cxgb4vf_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = cxgb4vf_do_ioctl, .ndo_change_mtu = cxgb4vf_change_mtu, - .ndo_vlan_rx_register = cxgb4vf_vlan_rx_register, + .ndo_fix_features = cxgb4vf_fix_features, + .ndo_set_features = cxgb4vf_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = cxgb4vf_poll_controller, #endif @@ -2600,12 +2617,11 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netdev->hw_features = NETIF_F_SG | TSO_FLAGS | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM; + NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM; netdev->vlan_features = NETIF_F_SG | TSO_FLAGS | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA; - netdev->features = netdev->hw_features | - NETIF_F_HW_VLAN_RX; + netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_TX; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index 5fd75fdaa63..cffb328c46c 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1491,20 +1491,10 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl, skb->ip_summed = CHECKSUM_UNNECESSARY; skb_record_rx_queue(skb, rxq->rspq.idx); - if (unlikely(pkt->vlan_ex)) { - struct port_info *pi = netdev_priv(rxq->rspq.netdev); - struct vlan_group *grp = pi->vlan_grp; - - rxq->stats.vlan_ex++; - if (likely(grp)) { - ret = vlan_gro_frags(&rxq->rspq.napi, grp, - be16_to_cpu(pkt->vlan)); - goto stats; - } - } + if (pkt->vlan_ex) + __vlan_hwaccel_put_tag(skb, be16_to_cpu(pkt->vlan)); ret = napi_gro_frags(&rxq->rspq.napi); -stats: if (ret == GRO_HELD) rxq->stats.lro_pkts++; else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE) @@ -1525,7 +1515,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, const struct pkt_gl *gl) { struct sk_buff *skb; - struct port_info *pi; const struct cpl_rx_pkt *pkt = (void *)&rsp[1]; bool csum_ok = pkt->csum_calc && !pkt->err_vec; struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq); @@ -1553,7 +1542,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, __skb_pull(skb, PKTSHIFT); skb->protocol = eth_type_trans(skb, rspq->netdev); skb_record_rx_queue(skb, rspq->idx); - pi = netdev_priv(skb->dev); rxq->stats.pkts++; if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) && @@ -1569,20 +1557,12 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } else skb_checksum_none_assert(skb); - /* - * Deliver the packet to the stack. - */ - if (unlikely(pkt->vlan_ex)) { - struct vlan_group *grp = pi->vlan_grp; - + if (pkt->vlan_ex) { rxq->stats.vlan_ex++; - if (likely(grp)) - vlan_hwaccel_receive_skb(skb, grp, - be16_to_cpu(pkt->vlan)); - else - dev_kfree_skb_any(skb); - } else - netif_receive_skb(skb); + __vlan_hwaccel_put_tag(skb, be16_to_cpu(pkt->vlan)); + } + + netif_receive_skb(skb); return 0; } -- cgit v1.2.3-70-g09d2 From c74ea2f75e40776607f614afde67f1241e283ed6 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:17 +0000 Subject: cxgb4: remove forgotten unused vlan_group Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index bc9982a4c1f..223a7f72343 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -276,7 +276,6 @@ enum { }; struct adapter; -struct vlan_group; struct sge_rspq; struct port_info { -- cgit v1.2.3-70-g09d2 From 6ede746b62627b6f03fe88afad1a07d38917b85d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:18 +0000 Subject: enic: do vlan cleanup - unify vlan and nonvlan rx path - kill enic->vlan_group and enic_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 1 - drivers/net/enic/enic_main.c | 32 ++++++-------------------------- 2 files changed, 6 insertions(+), 27 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f0b062b4a22..ce76d9a8ca6 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -94,7 +94,6 @@ struct enic { ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; spinlock_t wq_lock[ENIC_WQ_MAX]; unsigned int wq_count; - struct vlan_group *vlan_group; u16 loop_enable; u16 loop_tag; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index e25800fa96c..67a27cd304d 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1029,14 +1029,6 @@ static void enic_set_rx_mode(struct net_device *netdev) } } -/* rtnl lock is held */ -static void enic_vlan_rx_register(struct net_device *netdev, - struct vlan_group *vlan_group) -{ - struct enic *enic = netdev_priv(netdev); - enic->vlan_group = vlan_group; -} - /* netif_tx_lock held, BHs disabled */ static void enic_tx_timeout(struct net_device *netdev) { @@ -1264,23 +1256,13 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, skb->dev = netdev; - if (vlan_stripped) { - - if (netdev->features & NETIF_F_GRO) - vlan_gro_receive(&enic->napi[q_number], - enic->vlan_group, vlan_tci, skb); - else - vlan_hwaccel_receive_skb(skb, - enic->vlan_group, vlan_tci); + if (vlan_stripped) + __vlan_hwaccel_put_tag(skb, vlan_tci); - } else { - - if (netdev->features & NETIF_F_GRO) - napi_gro_receive(&enic->napi[q_number], skb); - else - netif_receive_skb(skb); - - } + if (netdev->features & NETIF_F_GRO) + napi_gro_receive(&enic->napi[q_number], skb); + else + netif_receive_skb(skb); } else { /* Buffer overflow @@ -2124,7 +2106,6 @@ static const struct net_device_ops enic_netdev_dynamic_ops = { .ndo_set_multicast_list = enic_set_rx_mode, .ndo_set_mac_address = enic_set_mac_address_dynamic, .ndo_change_mtu = enic_change_mtu, - .ndo_vlan_rx_register = enic_vlan_rx_register, .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid, .ndo_tx_timeout = enic_tx_timeout, @@ -2146,7 +2127,6 @@ static const struct net_device_ops enic_netdev_ops = { .ndo_set_rx_mode = enic_set_rx_mode, .ndo_set_multicast_list = enic_set_rx_mode, .ndo_change_mtu = enic_change_mtu, - .ndo_vlan_rx_register = enic_vlan_rx_register, .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid, .ndo_tx_timeout = enic_tx_timeout, -- cgit v1.2.3-70-g09d2 From 87c288c6e9aa31720b72e2bc2d665e24e1653c3e Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:19 +0000 Subject: gianfar: do vlan cleanup - unify vlan and nonvlan rx path - kill priv->vlgrp and gfar_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 55 +++++++++++++++++++++++-------------------- drivers/net/gianfar.h | 3 +-- drivers/net/gianfar_ethtool.c | 3 +++ 3 files changed, 33 insertions(+), 28 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index d265c6e1387..835cd258814 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -140,8 +140,6 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit); static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue); static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int amount_pull); -static void gfar_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp); void gfar_halt(struct net_device *dev); static void gfar_halt_nodisable(struct net_device *dev); void gfar_start(struct net_device *dev); @@ -391,10 +389,11 @@ static void gfar_init_mac(struct net_device *ndev) rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE; /* keep vlan related bits if it's enabled */ - if (priv->vlgrp) { + if (ndev->features & NETIF_F_HW_VLAN_TX) rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; + + if (ndev->features & NETIF_F_HW_VLAN_RX) tctrl |= TCTRL_VLINS; - } /* Init rctrl based on our settings */ gfar_write(®s->rctrl, rctrl); @@ -467,7 +466,6 @@ static const struct net_device_ops gfar_netdev_ops = { .ndo_tx_timeout = gfar_timeout, .ndo_do_ioctl = gfar_ioctl, .ndo_get_stats = gfar_get_stats, - .ndo_vlan_rx_register = gfar_vlan_rx_register, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -507,10 +505,17 @@ void unlock_tx_qs(struct gfar_private *priv) spin_unlock(&priv->tx_queue[i]->txlock); } +static bool gfar_is_vlan_on(struct gfar_private *priv) +{ + return (priv->ndev->features & NETIF_F_HW_VLAN_RX) || + (priv->ndev->features & NETIF_F_HW_VLAN_TX); +} + /* Returns 1 if incoming frames use an FCB */ static inline int gfar_uses_fcb(struct gfar_private *priv) { - return priv->vlgrp || (priv->ndev->features & NETIF_F_RXCSUM) || + return gfar_is_vlan_on(priv) || + (priv->ndev->features & NETIF_F_RXCSUM) || (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); } @@ -1038,10 +1043,10 @@ static int gfar_probe(struct platform_device *ofdev) NETIF_F_RXCSUM | NETIF_F_HIGHDMA; } - priv->vlgrp = NULL; - - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { + dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + } if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { priv->extended_hash = 1; @@ -2304,10 +2309,8 @@ void gfar_check_rx_parser_mode(struct gfar_private *priv) gfar_write(®s->rctrl, tempval); } - /* Enables and disables VLAN insertion/extraction */ -static void gfar_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) +void gfar_vlan_mode(struct net_device *dev, u32 features) { struct gfar_private *priv = netdev_priv(dev); struct gfar __iomem *regs = NULL; @@ -2318,25 +2321,24 @@ static void gfar_vlan_rx_register(struct net_device *dev, local_irq_save(flags); lock_rx_qs(priv); - priv->vlgrp = grp; - - if (grp) { + if (features & NETIF_F_HW_VLAN_TX) { /* Enable VLAN tag insertion */ tempval = gfar_read(®s->tctrl); tempval |= TCTRL_VLINS; - gfar_write(®s->tctrl, tempval); - - /* Enable VLAN tag extraction */ - tempval = gfar_read(®s->rctrl); - tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); - gfar_write(®s->rctrl, tempval); } else { /* Disable VLAN tag insertion */ tempval = gfar_read(®s->tctrl); tempval &= ~TCTRL_VLINS; gfar_write(®s->tctrl, tempval); + } + if (features & NETIF_F_HW_VLAN_RX) { + /* Enable VLAN tag extraction */ + tempval = gfar_read(®s->rctrl); + tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); + gfar_write(®s->rctrl, tempval); + } else { /* Disable VLAN tag extraction */ tempval = gfar_read(®s->rctrl); tempval &= ~RCTRL_VLEX; @@ -2359,7 +2361,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) int oldsize = priv->rx_buffer_size; int frame_size = new_mtu + ETH_HLEN; - if (priv->vlgrp) + if (gfar_is_vlan_on(priv)) frame_size += VLAN_HLEN; if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) { @@ -2712,11 +2714,12 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, /* Tell the skb what kind of packet this is */ skb->protocol = eth_type_trans(skb, dev); + /* Set vlan tag */ + if (fcb->flags & RXFCB_VLN) + __vlan_hwaccel_put_tag(skb, fcb->vlctl); + /* Send the packet up the stack */ - if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN))) - ret = vlan_hwaccel_receive_skb(skb, priv->vlgrp, fcb->vlctl); - else - ret = netif_receive_skb(skb); + ret = netif_receive_skb(skb); if (NET_RX_DROP == ret) priv->extra_stats.kernel_dropped++; diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 87c1d8608b7..9aa43773e8e 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -1077,8 +1077,6 @@ struct gfar_private { struct sk_buff_head rx_recycle; - struct vlan_group *vlgrp; - /* RX queue filer rule set*/ struct ethtool_rx_list rx_list; struct mutex rx_queue_access; @@ -1183,6 +1181,7 @@ extern void gfar_configure_coalescing(struct gfar_private *priv, void gfar_init_sysfs(struct net_device *dev); int gfar_set_features(struct net_device *dev, u32 features); extern void gfar_check_rx_parser_mode(struct gfar_private *priv); +extern void gfar_vlan_mode(struct net_device *dev, u32 features); extern const struct ethtool_ops gfar_ethtool_ops; diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 203369cc127..6e350692d11 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -526,6 +526,9 @@ int gfar_set_features(struct net_device *dev, u32 features) int err = 0, i = 0; u32 changed = dev->features ^ features; + if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) + gfar_vlan_mode(dev, features); + if (!(changed & NETIF_F_RXCSUM)) return 0; -- cgit v1.2.3-70-g09d2 From a0f1d603ee4186081fda0ad48ccf6163c2009f10 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 21 Jul 2011 06:30:00 +0000 Subject: igbvf: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and igbvf_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/igbvf/igbvf.h | 4 ++-- drivers/net/igbvf/netdev.c | 44 ++++++++++++++------------------------------ 2 files changed, 16 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index d5dad5d607d..fd4a7b780fd 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -34,7 +34,7 @@ #include #include #include - +#include #include "vf.h" @@ -173,7 +173,7 @@ struct igbvf_adapter { const struct igbvf_info *ei; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u32 bd_number; u32 rx_buffer_len; u32 polling_interval; diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 64b47bf01e1..1330c8e932d 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -100,12 +100,12 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, struct sk_buff *skb, u32 status, u16 vlan) { - if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(vlan) & - E1000_RXD_SPC_VLAN_MASK); - else - netif_receive_skb(skb); + if (status & E1000_RXD_STAT_VP) { + u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; + + __vlan_hwaccel_put_tag(skb, vid); + } + netif_receive_skb(skb); } static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter, @@ -1167,12 +1167,10 @@ static int igbvf_poll(struct napi_struct *napi, int budget) */ static void igbvf_set_rlpml(struct igbvf_adapter *adapter) { - int max_frame_size = adapter->max_frame_size; + int max_frame_size; struct e1000_hw *hw = &adapter->hw; - if (adapter->vlgrp) - max_frame_size += VLAN_TAG_SIZE; - + max_frame_size = adapter->max_frame_size + VLAN_TAG_SIZE; e1000_rlpml_set_vf(hw, max_frame_size); } @@ -1183,6 +1181,8 @@ static void igbvf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) if (hw->mac.ops.set_vfta(hw, vid, true)) dev_err(&adapter->pdev->dev, "Failed to add vlan id %d\n", vid); + else + set_bit(vid, adapter->active_vlans); } static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -1191,7 +1191,6 @@ static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct e1000_hw *hw = &adapter->hw; igbvf_irq_disable(adapter); - vlan_group_set_device(adapter->vlgrp, vid, NULL); if (!test_bit(__IGBVF_DOWN, &adapter->state)) igbvf_irq_enable(adapter); @@ -1199,30 +1198,16 @@ static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) if (hw->mac.ops.set_vfta(hw, vid, false)) dev_err(&adapter->pdev->dev, "Failed to remove vlan id %d\n", vid); -} - -static void igbvf_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct igbvf_adapter *adapter = netdev_priv(netdev); - - adapter->vlgrp = grp; + else + clear_bit(vid, adapter->active_vlans); } static void igbvf_restore_vlan(struct igbvf_adapter *adapter) { u16 vid; - if (!adapter->vlgrp) - return; - - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) igbvf_vlan_rx_add_vid(adapter->netdev, vid); - } - - igbvf_set_rlpml(adapter); } /** @@ -2203,7 +2188,7 @@ static netdev_tx_t igbvf_xmit_frame_ring_adv(struct sk_buff *skb, return NETDEV_TX_BUSY; } - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= IGBVF_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << IGBVF_TX_FLAGS_VLAN_SHIFT); } @@ -2556,7 +2541,6 @@ static const struct net_device_ops igbvf_netdev_ops = { .ndo_change_mtu = igbvf_change_mtu, .ndo_do_ioctl = igbvf_ioctl, .ndo_tx_timeout = igbvf_tx_timeout, - .ndo_vlan_rx_register = igbvf_vlan_rx_register, .ndo_vlan_rx_add_vid = igbvf_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = igbvf_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER -- cgit v1.2.3-70-g09d2 From 5043f5057773ba8b539eb51b9a4007e99599824f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:21 +0000 Subject: jme: do vlan cleanup - unify vlan and nonvlan rx path - kill jme->vlgrp and jme_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/jme.c | 28 +++++----------------------- drivers/net/jme.h | 4 ---- 2 files changed, 5 insertions(+), 27 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 6b2a5e74425..85a11e0fa54 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -1048,16 +1048,12 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) skb_checksum_none_assert(skb); if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { - if (jme->vlgrp) { - jme->jme_vlan_rx(skb, jme->vlgrp, - le16_to_cpu(rxdesc->descwb.vlan)); - NET_STAT(jme).rx_bytes += 4; - } else { - dev_kfree_skb(skb); - } - } else { - jme->jme_rx(skb); + u16 vid = le16_to_cpu(rxdesc->descwb.vlan); + + __vlan_hwaccel_put_tag(skb, vid); + NET_STAT(jme).rx_bytes += 4; } + jme->jme_rx(skb); if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_DEST)) == cpu_to_le16(RXWBFLAG_DEST_MUL)) @@ -2281,16 +2277,6 @@ static inline void jme_resume_rx(struct jme_adapter *jme) atomic_inc(&jme->link_changing); } -static void -jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) -{ - struct jme_adapter *jme = netdev_priv(netdev); - - jme_pause_rx(jme); - jme->vlgrp = grp; - jme_resume_rx(jme); -} - static void jme_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) @@ -2401,7 +2387,6 @@ jme_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecmd) test_bit(JME_FLAG_POLL, &jme->flags)) { clear_bit(JME_FLAG_POLL, &jme->flags); jme->jme_rx = netif_rx; - jme->jme_vlan_rx = vlan_hwaccel_rx; dpi->cur = PCC_P1; dpi->attempt = PCC_P1; dpi->cnt = 0; @@ -2411,7 +2396,6 @@ jme_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecmd) !(test_bit(JME_FLAG_POLL, &jme->flags))) { set_bit(JME_FLAG_POLL, &jme->flags); jme->jme_rx = netif_receive_skb; - jme->jme_vlan_rx = vlan_hwaccel_receive_skb; jme_interrupt_mode(jme); } @@ -2850,7 +2834,6 @@ static const struct net_device_ops jme_netdev_ops = { .ndo_set_multicast_list = jme_set_multi, .ndo_change_mtu = jme_change_mtu, .ndo_tx_timeout = jme_tx_timeout, - .ndo_vlan_rx_register = jme_vlan_rx_register, .ndo_fix_features = jme_fix_features, .ndo_set_features = jme_set_features, }; @@ -2933,7 +2916,6 @@ jme_init_one(struct pci_dev *pdev, jme->pdev = pdev; jme->dev = netdev; jme->jme_rx = netif_rx; - jme->jme_vlan_rx = vlan_hwaccel_rx; jme->old_mtu = netdev->mtu = 1500; jme->phylink = 0; jme->tx_ring_size = 1 << 10; diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 1481a62a1f3..c1f8b893e2e 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -451,7 +451,6 @@ struct jme_adapter { u32 msg_enable; struct ethtool_cmd old_ecmd; unsigned int old_mtu; - struct vlan_group *vlgrp; struct dynpcc_info dpi; atomic_t intr_sem; atomic_t link_changing; @@ -459,9 +458,6 @@ struct jme_adapter { atomic_t rx_cleaning; atomic_t rx_empty; int (*jme_rx)(struct sk_buff *skb); - int (*jme_vlan_rx)(struct sk_buff *skb, - struct vlan_group *grp, - unsigned short vlan_tag); DECLARE_NAPI_STRUCT DECLARE_NET_DEVICE_STATS }; -- cgit v1.2.3-70-g09d2 From f1b553fbe73bfad38f41269d1c7a7ce3176d9539 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:22 +0000 Subject: mlx4: do vlan cleanup - unify vlan and nonvlan path - kill priv->vlgrp and mlx4_en_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/mlx4/en_netdev.c | 49 ++++++++++---------------------------------- drivers/net/mlx4/en_port.c | 23 ++++++++------------- drivers/net/mlx4/en_rx.c | 24 ++++++++++++---------- drivers/net/mlx4/mlx4_en.h | 6 ++++-- 4 files changed, 37 insertions(+), 65 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 61850adae6f..9d3f57e76f2 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -45,25 +45,6 @@ #include "mlx4_en.h" #include "en_port.h" - -static void mlx4_en_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - int err; - - en_dbg(HW, priv, "Registering VLAN group:%p\n", grp); - priv->vlgrp = grp; - - mutex_lock(&mdev->state_lock); - if (mdev->device_up && priv->port_up) { - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, grp); - if (err) - en_err(priv, "Failed configuring VLAN filter\n"); - } - mutex_unlock(&mdev->state_lock); -} - static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct mlx4_en_priv *priv = netdev_priv(dev); @@ -71,16 +52,14 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) int err; int idx; - if (!priv->vlgrp) - return; + en_dbg(HW, priv, "adding VLAN:%d\n", vid); - en_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n", - vid, vlan_group_get_device(priv->vlgrp, vid)); + set_bit(vid, priv->active_vlans); /* Add VID to port VLAN filter */ mutex_lock(&mdev->state_lock); if (mdev->device_up && priv->port_up) { - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); if (err) en_err(priv, "Failed configuring VLAN filter\n"); } @@ -97,12 +76,9 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) int err; int idx; - if (!priv->vlgrp) - return; + en_dbg(HW, priv, "Killing VID:%d\n", vid); - en_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp entry:%p)\n", - vid, priv->vlgrp, vlan_group_get_device(priv->vlgrp, vid)); - vlan_group_set_device(priv->vlgrp, vid, NULL); + clear_bit(vid, priv->active_vlans); /* Remove VID from port VLAN filter */ mutex_lock(&mdev->state_lock); @@ -112,7 +88,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) en_err(priv, "could not find vid %d in cache\n", vid); if (mdev->device_up && priv->port_up) { - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); if (err) en_err(priv, "Failed configuring VLAN filter\n"); } @@ -265,12 +241,10 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) priv->flags |= MLX4_EN_FLAG_MC_PROMISC; } - if (priv->vlgrp) { - /* Disable port VLAN filter */ - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL); - if (err) - en_err(priv, "Failed disabling VLAN filter\n"); - } + /* Disable port VLAN filter */ + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); + if (err) + en_err(priv, "Failed disabling VLAN filter\n"); } goto out; } @@ -304,7 +278,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) } /* Enable port VLAN filter */ - err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); + err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); if (err) en_err(priv, "Failed enabling VLAN filter\n"); } @@ -1046,7 +1020,6 @@ static const struct net_device_ops mlx4_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = mlx4_en_change_mtu, .ndo_tx_timeout = mlx4_en_tx_timeout, - .ndo_vlan_rx_register = mlx4_en_vlan_rx_register, .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index f2a4f5dd313..2a74bc81b9f 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c @@ -48,7 +48,7 @@ int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B); } -int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp) +int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv) { struct mlx4_cmd_mailbox *mailbox; struct mlx4_set_vlan_fltr_mbox *filter; @@ -63,20 +63,15 @@ int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp) return PTR_ERR(mailbox); filter = mailbox->buf; - if (grp) { - memset(filter, 0, sizeof *filter); - for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) { - entry = 0; - for (j = 0; j < 32; j++) - if (vlan_group_get_device(grp, index++)) - entry |= 1 << j; - filter->entry[i] = cpu_to_be32(entry); - } - } else { - /* When no vlans are configured we block all vlans */ - memset(filter, 0, sizeof(*filter)); + memset(filter, 0, sizeof(*filter)); + for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) { + entry = 0; + for (j = 0; j < 32; j++) + if (test_bit(index++, priv->active_vlans)) + entry |= 1 << j; + filter->entry[i] = cpu_to_be32(entry); } - err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_VLAN_FLTR, + err = mlx4_cmd(dev, mailbox->dma, priv->port, 0, MLX4_CMD_SET_VLAN_FLTR, MLX4_CMD_TIME_CLASS_B); mlx4_free_cmd_mailbox(dev, mailbox); return err; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 5197b50b2d8..37cc9e5c56b 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -611,11 +611,14 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud gro_skb->truesize += length; gro_skb->ip_summed = CHECKSUM_UNNECESSARY; - if (priv->vlgrp && (cqe->vlan_my_qpn & - cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) - vlan_gro_frags(&cq->napi, priv->vlgrp, be16_to_cpu(cqe->sl_vid)); - else - napi_gro_frags(&cq->napi); + if (cqe->vlan_my_qpn & + cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK)) { + u16 vid = be16_to_cpu(cqe->sl_vid); + + __vlan_hwaccel_put_tag(gro_skb, vid); + } + + napi_gro_frags(&cq->napi); goto next; } @@ -647,13 +650,12 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud skb->protocol = eth_type_trans(skb, dev); skb_record_rx_queue(skb, cq->ring); + if (be32_to_cpu(cqe->vlan_my_qpn) & + MLX4_CQE_VLAN_PRESENT_MASK) + __vlan_hwaccel_put_tag(skb, be16_to_cpu(cqe->sl_vid)); + /* Push it up the stack */ - if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) & - MLX4_CQE_VLAN_PRESENT_MASK)) { - vlan_hwaccel_receive_skb(skb, priv->vlgrp, - be16_to_cpu(cqe->sl_vid)); - } else - netif_receive_skb(skb); + netif_receive_skb(skb); next: ++cq->mcq.cons_index; diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 0b5150df058..ed84811766e 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -34,10 +34,12 @@ #ifndef _MLX4_EN_H_ #define _MLX4_EN_H_ +#include #include #include #include #include +#include #include #include @@ -418,7 +420,7 @@ struct mlx4_en_priv { struct mlx4_en_dev *mdev; struct mlx4_en_port_profile *prof; struct net_device *dev; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct net_device_stats stats; struct net_device_stats ret_stats; struct mlx4_en_port_state port_state; @@ -553,7 +555,7 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring); void mlx4_en_rx_irq(struct mlx4_cq *mcq); int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, u64 mac, u64 clear, u8 mode); -int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp); +int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, struct mlx4_en_priv *priv); int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu, u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx); int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, -- cgit v1.2.3-70-g09d2 From 18c49b91777c66265d640f8fb221039bdf46b2d3 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 21 Jul 2011 03:24:11 +0000 Subject: qlge: do vlan cleanup - unify vlan and nonvlan path - kill qdev->vlgrp and qlge_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 3 +- drivers/net/qlge/qlge_main.c | 161 ++++++++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 71 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 794252c0aed..8731f79c9ef 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -11,6 +11,7 @@ #include #include #include +#include /* * General definitions... @@ -2052,7 +2053,7 @@ struct ql_adapter { struct nic_stats nic_stats; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; /* PCI Configuration information for this device */ struct pci_dev *pdev; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 68fbfac7a3b..743e3ec729c 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -7,6 +7,7 @@ */ #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -415,7 +417,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, (qdev-> func << CAM_OUT_FUNC_SHIFT) | (0 << CAM_OUT_CQ_ID_SHIFT)); - if (qdev->vlgrp) + if (qdev->ndev->features & NETIF_F_HW_VLAN_RX) cam_output |= CAM_OUT_RV; /* route to NIC core */ ql_write32(qdev, MAC_ADDR_DATA, cam_output); @@ -1507,10 +1509,9 @@ static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev, rx_ring->rx_bytes += length; skb->ip_summed = CHECKSUM_UNNECESSARY; skb_record_rx_queue(skb, rx_ring->cq_id); - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_gro_frags(&rx_ring->napi, qdev->vlgrp, vlan_id); - else - napi_gro_frags(napi); + if (vlan_id != 0xffff) + __vlan_hwaccel_put_tag(skb, vlan_id); + napi_gro_frags(napi); } /* Process an inbound completion from an rx ring. */ @@ -1594,17 +1595,12 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, } skb_record_rx_queue(skb, rx_ring->cq_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_gro_receive(napi, qdev->vlgrp, vlan_id, skb); - else - napi_gro_receive(napi, skb); - } else { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id); - else - netif_receive_skb(skb); - } + if (vlan_id != 0xffff) + __vlan_hwaccel_put_tag(skb, vlan_id); + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(napi, skb); + else + netif_receive_skb(skb); return; err_out: dev_kfree_skb_any(skb); @@ -1707,18 +1703,12 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, } skb_record_rx_queue(skb, rx_ring->cq_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_gro_receive(&rx_ring->napi, qdev->vlgrp, - vlan_id, skb); - else - napi_gro_receive(&rx_ring->napi, skb); - } else { - if (qdev->vlgrp && (vlan_id != 0xffff)) - vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id); - else - netif_receive_skb(skb); - } + if (vlan_id != 0xffff) + __vlan_hwaccel_put_tag(skb, vlan_id); + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(&rx_ring->napi, skb); + else + netif_receive_skb(skb); } static void ql_realign_skb(struct sk_buff *skb, int len) @@ -2028,22 +2018,12 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb_record_rx_queue(skb, rx_ring->cq_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (qdev->vlgrp && - (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && - (vlan_id != 0)) - vlan_gro_receive(&rx_ring->napi, qdev->vlgrp, - vlan_id, skb); - else - napi_gro_receive(&rx_ring->napi, skb); - } else { - if (qdev->vlgrp && - (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && - (vlan_id != 0)) - vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id); - else - netif_receive_skb(skb); - } + if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && (vlan_id != 0)) + __vlan_hwaccel_put_tag(skb, vlan_id); + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(&rx_ring->napi, skb); + else + netif_receive_skb(skb); } /* Process an inbound completion from an rx ring. */ @@ -2334,71 +2314,111 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget) return work_done; } -static void qlge_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp) +static void qlge_vlan_mode(struct net_device *ndev, u32 features) { struct ql_adapter *qdev = netdev_priv(ndev); - qdev->vlgrp = grp; - if (grp) { - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, + if (features & NETIF_F_HW_VLAN_RX) { + netif_printk(qdev, ifup, KERN_DEBUG, ndev, "Turning on VLAN in NIC_RCV_CFG.\n"); ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK | - NIC_RCV_CFG_VLAN_MATCH_AND_NON); + NIC_RCV_CFG_VLAN_MATCH_AND_NON); } else { - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, + netif_printk(qdev, ifup, KERN_DEBUG, ndev, "Turning off VLAN in NIC_RCV_CFG.\n"); ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK); } } -static void qlge_vlan_rx_add_vid(struct net_device *ndev, u16 vid) +static u32 qlge_fix_features(struct net_device *ndev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int qlge_set_features(struct net_device *ndev, u32 features) +{ + u32 changed = ndev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + qlge_vlan_mode(ndev, features); + + return 0; +} + +static void __qlge_vlan_rx_add_vid(struct ql_adapter *qdev, u16 vid) { - struct ql_adapter *qdev = netdev_priv(ndev); u32 enable_bit = MAC_ADDR_E; - int status; - status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return; if (ql_set_mac_addr_reg (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { netif_err(qdev, ifup, qdev->ndev, "Failed to init vlan address.\n"); } - ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } -static void qlge_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) +static void qlge_vlan_rx_add_vid(struct net_device *ndev, u16 vid) { struct ql_adapter *qdev = netdev_priv(ndev); - u32 enable_bit = 0; int status; status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); if (status) return; + __qlge_vlan_rx_add_vid(qdev, vid); + set_bit(vid, qdev->active_vlans); + + ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); +} + +static void __qlge_vlan_rx_kill_vid(struct ql_adapter *qdev, u16 vid) +{ + u32 enable_bit = 0; + if (ql_set_mac_addr_reg (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { netif_err(qdev, ifup, qdev->ndev, "Failed to clear vlan address.\n"); } - ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); +} + +static void qlge_vlan_rx_kill_vid(struct net_device *ndev, u16 vid) +{ + struct ql_adapter *qdev = netdev_priv(ndev); + int status; + + status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); + if (status) + return; + + __qlge_vlan_rx_kill_vid(qdev, vid); + clear_bit(vid, qdev->active_vlans); + ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } static void qlge_restore_vlan(struct ql_adapter *qdev) { - qlge_vlan_rx_register(qdev->ndev, qdev->vlgrp); + int status; + u16 vid; - if (qdev->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(qdev->vlgrp, vid)) - continue; - qlge_vlan_rx_add_vid(qdev->ndev, vid); - } - } + status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); + if (status) + return; + + for_each_set_bit(vid, qdev->active_vlans, VLAN_N_VID) + __qlge_vlan_rx_add_vid(qdev, vid); + + ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } /* MSI-X Multiple Vector Interrupt Handler for inbound completions. */ @@ -4661,7 +4681,8 @@ static const struct net_device_ops qlge_netdev_ops = { .ndo_set_mac_address = qlge_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = qlge_tx_timeout, - .ndo_vlan_rx_register = qlge_vlan_rx_register, + .ndo_fix_features = qlge_fix_features, + .ndo_set_features = qlge_set_features, .ndo_vlan_rx_add_vid = qlge_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qlge_vlan_rx_kill_vid, }; -- cgit v1.2.3-70-g09d2 From b85da2c00453d9b97e66b5be7d035d6e0736eca0 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:24 +0000 Subject: s2io: do vlan cleanup - unify vlan and nonvlan rx path - kill sp->vlgrp and s2io_vlan_rx_register and s2io_vlan_rx_kill_vid (which does nothing and is never called :)) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/s2io.c | 70 +++++------------------------------------------------- drivers/net/s2io.h | 1 - 2 files changed, 6 insertions(+), 65 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 043850b8c30..277d48b0800 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -356,56 +356,6 @@ static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr) sp->def_mac_addr[offset].mac_addr[0] = (u8) (mac_addr >> 40); } -/* Add the vlan */ -static void s2io_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - int i; - struct s2io_nic *nic = netdev_priv(dev); - unsigned long flags[MAX_TX_FIFOS]; - struct config_param *config = &nic->config; - struct mac_info *mac_control = &nic->mac_control; - - for (i = 0; i < config->tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_lock_irqsave(&fifo->tx_lock, flags[i]); - } - - nic->vlgrp = grp; - - for (i = config->tx_fifo_num - 1; i >= 0; i--) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_unlock_irqrestore(&fifo->tx_lock, flags[i]); - } -} - -/* Unregister the vlan */ -static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - int i; - struct s2io_nic *nic = netdev_priv(dev); - unsigned long flags[MAX_TX_FIFOS]; - struct config_param *config = &nic->config; - struct mac_info *mac_control = &nic->mac_control; - - for (i = 0; i < config->tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_lock_irqsave(&fifo->tx_lock, flags[i]); - } - - if (nic->vlgrp) - vlan_group_set_device(nic->vlgrp, vid, NULL); - - for (i = config->tx_fifo_num - 1; i >= 0; i--) { - struct fifo_info *fifo = &mac_control->fifos[i]; - - spin_unlock_irqrestore(&fifo->tx_lock, flags[i]); - } -} - /* * Constants to be programmed into the Xena's registers, to configure * the XAUI. @@ -7737,8 +7687,6 @@ static const struct net_device_ops s2io_netdev_ops = { .ndo_set_mac_address = s2io_set_mac_addr, .ndo_change_mtu = s2io_change_mtu, .ndo_set_features = s2io_set_features, - .ndo_vlan_rx_register = s2io_vlan_rx_register, - .ndo_vlan_rx_kill_vid = s2io_vlan_rx_kill_vid, .ndo_tx_timeout = s2io_tx_watchdog, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = s2io_netpoll, @@ -8617,18 +8565,12 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag) struct s2io_nic *sp = netdev_priv(dev); skb->protocol = eth_type_trans(skb, dev); - if (sp->vlgrp && vlan_tag && (sp->vlan_strip_flag)) { - /* Queueing the vlan frame to the upper layer */ - if (sp->config.napi) - vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag); - else - vlan_hwaccel_rx(skb, sp->vlgrp, vlan_tag); - } else { - if (sp->config.napi) - netif_receive_skb(skb); - else - netif_rx(skb); - } + if (vlan_tag && sp->vlan_strip_flag) + __vlan_hwaccel_put_tag(skb, vlan_tag); + if (sp->config.napi) + netif_receive_skb(skb); + else + netif_rx(skb); } static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 800b3a44e65..ae3c8e79b32 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -939,7 +939,6 @@ struct s2io_nic { int task_flag; unsigned long long start_time; - struct vlan_group *vlgrp; int vlan_strip_flag; #define MSIX_FLG 0xA5 int num_entries; -- cgit v1.2.3-70-g09d2 From 9c5d061429b0abc74bcd95d1896a848d1ab663b1 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:25 +0000 Subject: spider_net: do not mention dying vlan_hwaccel_receive_skb Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/spider_net.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 9bc6c20e8b9..1ff3491c824 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1004,9 +1004,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, } if (data_status & SPIDER_NET_VLAN_PACKET) { - /* further enhancements: HW-accel VLAN - * vlan_hwaccel_receive_skb - */ + /* further enhancements: HW-accel VLAN */ } /* update netdevice statistics */ -- cgit v1.2.3-70-g09d2 From 312cd51353a4f5940eea963570b8b14b7d9290c4 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:26 +0000 Subject: tehuti: do vlan cleanup - unify vlan and nonvlan rx path - kill priv->vlgrp and bdx_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/tehuti.c | 37 +++++++------------------------------ drivers/net/tehuti.h | 1 - 2 files changed, 7 insertions(+), 31 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 80fbee0d40a..749bbf18dc6 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -742,22 +742,6 @@ static void bdx_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid) __bdx_vlan_rx_vid(ndev, vid, 0); } -/* - * bdx_vlan_rx_register - kernel hook for adding VLAN group - * @ndev network device - * @grp VLAN group - */ -static void -bdx_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp) -{ - struct bdx_priv *priv = netdev_priv(ndev); - - ENTER; - DBG("device='%s', group='%p'\n", ndev->name, grp); - priv->vlgrp = grp; - RET(); -} - /** * bdx_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -1146,21 +1130,15 @@ NETIF_RX_MUX(struct bdx_priv *priv, u32 rxd_val1, u16 rxd_vlan, struct sk_buff *skb) { ENTER; - DBG("rxdd->flags.bits.vtag=%d vlgrp=%p\n", GET_RXD_VTAG(rxd_val1), - priv->vlgrp); - if (priv->vlgrp && GET_RXD_VTAG(rxd_val1)) { - DBG("%s: vlan rcv vlan '%x' vtag '%x', device name '%s'\n", + DBG("rxdd->flags.bits.vtag=%d\n", GET_RXD_VTAG(rxd_val1)); + if (GET_RXD_VTAG(rxd_val1)) { + DBG("%s: vlan rcv vlan '%x' vtag '%x'\n", priv->ndev->name, GET_RXD_VLAN_ID(rxd_vlan), - GET_RXD_VTAG(rxd_val1), - vlan_group_get_device(priv->vlgrp, - GET_RXD_VLAN_ID(rxd_vlan))->name); - /* NAPI variant of receive functions */ - vlan_hwaccel_receive_skb(skb, priv->vlgrp, - GET_RXD_VLAN_TCI(rxd_vlan)); - } else { - netif_receive_skb(skb); + GET_RXD_VTAG(rxd_val1)); + __vlan_hwaccel_put_tag(skb, GET_RXD_VLAN_TCI(rxd_vlan)); } + netif_receive_skb(skb); } static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd) @@ -1877,7 +1855,7 @@ static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size) } static const struct net_device_ops bdx_netdev_ops = { - .ndo_open = bdx_open, + .ndo_open = bdx_open, .ndo_stop = bdx_close, .ndo_start_xmit = bdx_tx_transmit, .ndo_validate_addr = eth_validate_addr, @@ -1885,7 +1863,6 @@ static const struct net_device_ops bdx_netdev_ops = { .ndo_set_multicast_list = bdx_setmulti, .ndo_change_mtu = bdx_change_mtu, .ndo_set_mac_address = bdx_set_mac, - .ndo_vlan_rx_register = bdx_vlan_rx_register, .ndo_vlan_rx_add_vid = bdx_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bdx_vlan_rx_kill_vid, }; diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index c5642fefc9e..709ebd6e28b 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -250,7 +250,6 @@ struct bdx_priv { struct rxf_fifo rxf_fifo0; struct rxdb *rxdb; /* rx dbs to store skb pointers */ int napi_stop; - struct vlan_group *vlgrp; /* Tx FIFOs: 1 for data desc, 1 for empty (acks) desc */ struct txd_fifo txd_fifo0; -- cgit v1.2.3-70-g09d2 From dadcd65f52921456112183fde543fc214bb0a227 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 21 Jul 2011 03:25:09 +0000 Subject: ixgbevf: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and ixgbevf_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ixgbevf/ixgbevf.h | 6 ++-- drivers/net/ixgbevf/ixgbevf_main.c | 64 +++++++++----------------------------- 2 files changed, 18 insertions(+), 52 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index a2bbbb35816..8857df4dd3b 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -29,9 +29,11 @@ #define _IXGBEVF_H_ #include +#include #include #include #include +#include #include "vf.h" @@ -185,9 +187,7 @@ struct ixgbevf_q_vector { /* board specific private data structure */ struct ixgbevf_adapter { struct timer_list watchdog_timer; -#ifdef NETIF_F_HW_VLAN_TX - struct vlan_group *vlgrp; -#endif + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 bd_number; struct work_struct reset_task; struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index fec36bde199..3b880a27f8d 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -30,6 +30,7 @@ Copyright (c)2006 - 2007 Myricom, Inc. for some LRO specific code ******************************************************************************/ #include +#include #include #include #include @@ -288,21 +289,17 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, { struct ixgbevf_adapter *adapter = q_vector->adapter; bool is_vlan = (status & IXGBE_RXD_STAT_VP); - u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { - if (adapter->vlgrp && is_vlan) - vlan_gro_receive(&q_vector->napi, - adapter->vlgrp, - tag, skb); - else + if (is_vlan) { + u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); + + __vlan_hwaccel_put_tag(skb, tag); + } + + if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) napi_gro_receive(&q_vector->napi, skb); - } else { - if (adapter->vlgrp && is_vlan) - vlan_hwaccel_rx(skb, adapter->vlgrp, tag); - else + else netif_rx(skb); - } } /** @@ -1401,24 +1398,6 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) } } -static void ixgbevf_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct ixgbevf_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; - int i, j; - u32 ctrl; - - adapter->vlgrp = grp; - - for (i = 0; i < adapter->num_rx_queues; i++) { - j = adapter->rx_ring[i].reg_idx; - ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)); - ctrl |= IXGBE_RXDCTL_VME; - IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), ctrl); - } -} - static void ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); @@ -1427,6 +1406,7 @@ static void ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) /* add VID to filter table */ if (hw->mac.ops.set_vfta) hw->mac.ops.set_vfta(hw, vid, 0, true); + set_bit(vid, adapter->active_vlans); } static void ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -1434,31 +1414,18 @@ static void ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; - if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) - ixgbevf_irq_disable(adapter); - - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) - ixgbevf_irq_enable(adapter, true, true); - /* remove VID from filter table */ if (hw->mac.ops.set_vfta) hw->mac.ops.set_vfta(hw, vid, 0, false); + clear_bit(vid, adapter->active_vlans); } static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) { - ixgbevf_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - ixgbevf_vlan_rx_add_vid(adapter->netdev, vid); - } - } + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + ixgbevf_vlan_rx_add_vid(adapter->netdev, vid); } static int ixgbevf_write_uc_addr_list(struct net_device *netdev) @@ -1648,7 +1615,7 @@ static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) for (i = 0; i < num_rx_rings; i++) { j = adapter->rx_ring[i].reg_idx; rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)); - rxdctl |= IXGBE_RXDCTL_ENABLE; + rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; if (hw->mac.type == ixgbe_mac_X540_vf) { rxdctl &= ~IXGBE_RXDCTL_RLPMLMASK; rxdctl |= ((netdev->mtu + ETH_HLEN + ETH_FCS_LEN) | @@ -3258,7 +3225,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_mac_address = ixgbevf_set_mac, .ndo_change_mtu = ixgbevf_change_mtu, .ndo_tx_timeout = ixgbevf_tx_timeout, - .ndo_vlan_rx_register = ixgbevf_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgbevf_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbevf_vlan_rx_kill_vid, }; -- cgit v1.2.3-70-g09d2 From 08dddfc3f6e39fc81238ef4804815c559f314066 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:29 +0000 Subject: acenic: do vlan cleanup - unify vlan and nonvlan rx path - kill ap->vlgrp and ace_vlan_rx_register - enable vlan hw accel always (kill vlan ifdefs) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/acenic.c | 60 ++++++---------------------------------------------- drivers/net/acenic.h | 7 ------ 2 files changed, 7 insertions(+), 60 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index d7c1bfe4b6e..02fcb5c997e 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -69,10 +69,7 @@ #include #include #include - -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include -#endif #ifdef SIOCETHTOOL #include @@ -171,15 +168,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); #define BOARD_IDX_STATIC 0 #define BOARD_IDX_OVERFLOW -1 -#if (defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)) && \ - defined(NETIF_F_HW_VLAN_RX) -#define ACENIC_DO_VLAN 1 -#define ACE_RCB_VLAN_FLAG RCB_FLG_VLAN_ASSIST -#else -#define ACENIC_DO_VLAN 0 -#define ACE_RCB_VLAN_FLAG 0 -#endif - #include "acenic.h" /* @@ -465,9 +453,6 @@ static const struct net_device_ops ace_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ace_set_mac_addr, .ndo_change_mtu = ace_change_mtu, -#if ACENIC_DO_VLAN - .ndo_vlan_rx_register = ace_vlan_rx_register, -#endif }; static int __devinit acenic_probe_one(struct pci_dev *pdev, @@ -491,9 +476,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, ap->name = pci_name(pdev); dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; -#if ACENIC_DO_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif dev->watchdog_timeo = 5*HZ; @@ -1248,7 +1231,7 @@ static int __devinit ace_init(struct net_device *dev) set_aceaddr(&info->rx_std_ctrl.rngptr, ap->rx_ring_base_dma); info->rx_std_ctrl.max_len = ACE_STD_BUFSIZE; info->rx_std_ctrl.flags = - RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; + RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST; memset(ap->rx_std_ring, 0, RX_STD_RING_ENTRIES * sizeof(struct rx_desc)); @@ -1264,7 +1247,7 @@ static int __devinit ace_init(struct net_device *dev) (sizeof(struct rx_desc) * RX_STD_RING_ENTRIES))); info->rx_jumbo_ctrl.max_len = 0; info->rx_jumbo_ctrl.flags = - RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; + RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST; memset(ap->rx_jumbo_ring, 0, RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc)); @@ -1286,7 +1269,7 @@ static int __devinit ace_init(struct net_device *dev) RX_JUMBO_RING_ENTRIES)))); info->rx_mini_ctrl.max_len = ACE_MINI_SIZE; info->rx_mini_ctrl.flags = - RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|ACE_RCB_VLAN_FLAG; + RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|RCB_FLG_VLAN_ASSIST; for (i = 0; i < RX_MINI_RING_ENTRIES; i++) ap->rx_mini_ring[i].flags = @@ -1332,7 +1315,7 @@ static int __devinit ace_init(struct net_device *dev) } info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap); - tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; + tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST; /* * The Tigon I does not like having the TX ring in host memory ;-( @@ -2038,12 +2021,9 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) } /* send it up */ -#if ACENIC_DO_VLAN - if (ap->vlgrp && (bd_flags & BD_FLG_VLAN_TAG)) { - vlan_hwaccel_rx(skb, ap->vlgrp, retdesc->vlan); - } else -#endif - netif_rx(skb); + if ((bd_flags & BD_FLG_VLAN_TAG)) + __vlan_hwaccel_put_tag(skb, retdesc->vlan); + netif_rx(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += retdesc->size; @@ -2262,24 +2242,6 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } - -#if ACENIC_DO_VLAN -static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct ace_private *ap = netdev_priv(dev); - unsigned long flags; - - local_irq_save(flags); - ace_mask_irq(dev); - - ap->vlgrp = grp; - - ace_unmask_irq(dev); - local_irq_restore(flags); -} -#endif /* ACENIC_DO_VLAN */ - - static int ace_open(struct net_device *dev) { struct ace_private *ap = netdev_priv(dev); @@ -2449,16 +2411,12 @@ ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr, writel(addr >> 32, &io->addr.addrhi); writel(addr & 0xffffffff, &io->addr.addrlo); writel(flagsize, &io->flagsize); -#if ACENIC_DO_VLAN writel(vlan_tag, &io->vlanres); -#endif } else { desc->addr.addrhi = addr >> 32; desc->addr.addrlo = addr; desc->flagsize = flagsize; -#if ACENIC_DO_VLAN desc->vlanres = vlan_tag; -#endif } } @@ -2486,12 +2444,10 @@ restart: flagsize = (skb->len << 16) | (BD_FLG_END); if (skb->ip_summed == CHECKSUM_PARTIAL) flagsize |= BD_FLG_TCP_UDP_SUM; -#if ACENIC_DO_VLAN if (vlan_tx_tag_present(skb)) { flagsize |= BD_FLG_VLAN_TAG; vlan_tag = vlan_tx_tag_get(skb); } -#endif desc = ap->tx_ring + idx; idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap); @@ -2509,12 +2465,10 @@ restart: flagsize = (skb_headlen(skb) << 16); if (skb->ip_summed == CHECKSUM_PARTIAL) flagsize |= BD_FLG_TCP_UDP_SUM; -#if ACENIC_DO_VLAN if (vlan_tx_tag_present(skb)) { flagsize |= BD_FLG_VLAN_TAG; vlan_tag = vlan_tx_tag_get(skb); } -#endif ace_load_tx_bd(ap, ap->tx_ring + idx, mapping, flagsize, vlan_tag); diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h index fd25a3b47fe..f67dc9b0eb8 100644 --- a/drivers/net/acenic.h +++ b/drivers/net/acenic.h @@ -665,10 +665,6 @@ struct ace_private struct rx_desc *rx_mini_ring; struct rx_desc *rx_return_ring; -#if ACENIC_DO_VLAN - struct vlan_group *vlgrp; -#endif - int tasklet_pending, jumbo; struct tasklet_struct ace_tasklet; @@ -790,8 +786,5 @@ static void ace_free_descriptors(struct net_device *dev); static void ace_init_cleanup(struct net_device *dev); static struct net_device_stats *ace_get_stats(struct net_device *dev); static int read_eeprom_byte(struct net_device *dev, unsigned long offset); -#if ACENIC_DO_VLAN -static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp); -#endif #endif /* _ACENIC_H_ */ -- cgit v1.2.3-70-g09d2 From 73b54688815f76bdccb8b94b5d1fd2dd0af3ea70 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:30 +0000 Subject: via-velocity: do vlan cleanup - unify vlan and nonvlan rx path - kill vptr->vlgrp and velocity_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 49 +++++++++++++++++++--------------------------- drivers/net/via-velocity.h | 2 +- 2 files changed, 21 insertions(+), 30 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f92924283d3..a9aa4a3fbfb 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -45,6 +45,7 @@ #include #include +#include #include #include #include @@ -76,6 +77,7 @@ #include #include #include +#include #include "via-velocity.h" @@ -501,6 +503,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, static void velocity_init_cam_filter(struct velocity_info *vptr) { struct mac_regs __iomem *regs = vptr->mac_regs; + unsigned int vid, i = 0; /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG); @@ -513,30 +516,17 @@ static void velocity_init_cam_filter(struct velocity_info *vptr) mac_set_cam_mask(regs, vptr->mCAMmask); /* Enable VCAMs */ - if (vptr->vlgrp) { - unsigned int vid, i = 0; - - if (!vlan_group_get_device(vptr->vlgrp, 0)) - WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); - - for (vid = 1; (vid < VLAN_VID_MASK); vid++) { - if (vlan_group_get_device(vptr->vlgrp, vid)) { - mac_set_vlan_cam(regs, i, (u8 *) &vid); - vptr->vCAMmask[i / 8] |= 0x1 << (i % 8); - if (++i >= VCAM_SIZE) - break; - } - } - mac_set_vlan_cam_mask(regs, vptr->vCAMmask); - } -} -static void velocity_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct velocity_info *vptr = netdev_priv(dev); + if (test_bit(0, vptr->active_vlans)) + WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); - vptr->vlgrp = grp; + for_each_set_bit(vid, vptr->active_vlans, VLAN_N_VID) { + mac_set_vlan_cam(regs, i, (u8 *) &vid); + vptr->vCAMmask[i / 8] |= 0x1 << (i % 8); + if (++i >= VCAM_SIZE) + break; + } + mac_set_vlan_cam_mask(regs, vptr->vCAMmask); } static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) @@ -544,6 +534,7 @@ static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) struct velocity_info *vptr = netdev_priv(dev); spin_lock_irq(&vptr->lock); + set_bit(vid, vptr->active_vlans); velocity_init_cam_filter(vptr); spin_unlock_irq(&vptr->lock); } @@ -553,7 +544,7 @@ static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid struct velocity_info *vptr = netdev_priv(dev); spin_lock_irq(&vptr->lock); - vlan_group_set_device(vptr->vlgrp, vid, NULL); + clear_bit(vid, vptr->active_vlans); velocity_init_cam_filter(vptr); spin_unlock_irq(&vptr->lock); } @@ -2094,11 +2085,12 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx) skb_put(skb, pkt_len - 4); skb->protocol = eth_type_trans(skb, vptr->dev); - if (vptr->vlgrp && (rd->rdesc0.RSR & RSR_DETAG)) { - vlan_hwaccel_rx(skb, vptr->vlgrp, - swab16(le16_to_cpu(rd->rdesc1.PQTAG))); - } else - netif_rx(skb); + if (rd->rdesc0.RSR & RSR_DETAG) { + u16 vid = swab16(le16_to_cpu(rd->rdesc1.PQTAG)); + + __vlan_hwaccel_put_tag(skb, vid); + } + netif_rx(skb); stats->rx_bytes += pkt_len; @@ -2641,7 +2633,6 @@ static const struct net_device_ops velocity_netdev_ops = { .ndo_do_ioctl = velocity_ioctl, .ndo_vlan_rx_add_vid = velocity_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = velocity_vlan_rx_kill_vid, - .ndo_vlan_rx_register = velocity_vlan_rx_register, }; /** diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index 0f1f05f6c4f..4cb9f13485e 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -1437,7 +1437,7 @@ struct velocity_info { struct pci_dev *pdev; struct net_device *dev; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u8 ip_addr[4]; enum chip_type chip_id; -- cgit v1.2.3-70-g09d2 From 5da96be53a16a62488316810d0c7c5d58ce3ee4f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:31 +0000 Subject: starfire: do vlan cleanup - unify vlan and nonvlan rx path - kill np->vlgrp and netdev_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/starfire.c | 89 ++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 50 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 860a50815f8..7ae1f990a98 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -561,7 +561,7 @@ struct netdev_private { struct net_device *dev; struct pci_dev *pci_dev; #ifdef VLAN_SUPPORT - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; #endif void *queue_mem; dma_addr_t queue_mem_dma; @@ -607,18 +607,6 @@ static const struct ethtool_ops ethtool_ops; #ifdef VLAN_SUPPORT -static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct netdev_private *np = netdev_priv(dev); - - spin_lock(&np->lock); - if (debug > 2) - printk("%s: Setting vlgrp to %p\n", dev->name, grp); - np->vlgrp = grp; - set_rx_mode(dev); - spin_unlock(&np->lock); -} - static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct netdev_private *np = netdev_priv(dev); @@ -626,6 +614,7 @@ static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) spin_lock(&np->lock); if (debug > 1) printk("%s: Adding vlanid %d to vlan filter\n", dev->name, vid); + set_bit(vid, np->active_vlans); set_rx_mode(dev); spin_unlock(&np->lock); } @@ -637,7 +626,7 @@ static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) spin_lock(&np->lock); if (debug > 1) printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid); - vlan_group_set_device(np->vlgrp, vid, NULL); + clear_bit(vid, np->active_vlans); set_rx_mode(dev); spin_unlock(&np->lock); } @@ -648,15 +637,14 @@ static const struct net_device_ops netdev_ops = { .ndo_open = netdev_open, .ndo_stop = netdev_close, .ndo_start_xmit = start_tx, - .ndo_tx_timeout = tx_timeout, - .ndo_get_stats = get_stats, + .ndo_tx_timeout = tx_timeout, + .ndo_get_stats = get_stats, .ndo_set_multicast_list = &set_rx_mode, - .ndo_do_ioctl = netdev_ioctl, + .ndo_do_ioctl = netdev_ioctl, .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef VLAN_SUPPORT - .ndo_vlan_rx_register = netdev_vlan_rx_register, .ndo_vlan_rx_add_vid = netdev_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = netdev_vlan_rx_kill_vid, #endif @@ -1528,21 +1516,17 @@ static int __netdev_rx(struct net_device *dev, int *quota) printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2)); } #ifdef VLAN_SUPPORT - if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) { + if (le16_to_cpu(desc->status2) & 0x0200) { u16 vlid = le16_to_cpu(desc->vlanid); if (debug > 4) { printk(KERN_DEBUG " netdev_rx() vlanid = %d\n", vlid); } - /* - * vlan_hwaccel_rx expects a packet with the VLAN tag - * stripped out. - */ - vlan_hwaccel_rx(skb, np->vlgrp, vlid); - } else + __vlan_hwaccel_put_tag(skb, vlid); + } #endif /* VLAN_SUPPORT */ - netif_receive_skb(skb); + netif_receive_skb(skb); dev->stats.rx_packets++; next_rx: @@ -1752,6 +1736,32 @@ static struct net_device_stats *get_stats(struct net_device *dev) return &dev->stats; } +#ifdef VLAN_SUPPORT +static u32 set_vlan_mode(struct netdev_private *np) +{ + u32 ret = VlanMode; + u16 vid; + void __iomem *filter_addr = np->base + HashTable + 8; + int vlan_count = 0; + + for_each_set_bit(vid, np->active_vlans, VLAN_N_VID) { + if (vlan_count == 32) + break; + writew(vid, filter_addr); + filter_addr += 16; + vlan_count++; + } + if (vlan_count == 32) { + ret |= PerfectFilterVlan; + while (vlan_count < 32) { + writew(0, filter_addr); + filter_addr += 16; + vlan_count++; + } + } + return ret; +} +#endif /* VLAN_SUPPORT */ static void set_rx_mode(struct net_device *dev) { @@ -1760,30 +1770,9 @@ static void set_rx_mode(struct net_device *dev) u32 rx_mode = MinVLANPrio; struct netdev_hw_addr *ha; int i; -#ifdef VLAN_SUPPORT - rx_mode |= VlanMode; - if (np->vlgrp) { - int vlan_count = 0; - void __iomem *filter_addr = ioaddr + HashTable + 8; - for (i = 0; i < VLAN_VID_MASK; i++) { - if (vlan_group_get_device(np->vlgrp, i)) { - if (vlan_count >= 32) - break; - writew(i, filter_addr); - filter_addr += 16; - vlan_count++; - } - } - if (i == VLAN_VID_MASK) { - rx_mode |= PerfectFilterVlan; - while (vlan_count < 32) { - writew(0, filter_addr); - filter_addr += 16; - vlan_count++; - } - } - } +#ifdef VLAN_SUPPORT + rx_mode |= set_vlan_mode(np); #endif /* VLAN_SUPPORT */ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ -- cgit v1.2.3-70-g09d2 From a4f676b80f9ca2a76cb27b8378343a5f4f972d3f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:32 +0000 Subject: ns83820: do vlan cleanup - unify vlan and nonvlan rx path - kill dev->vlgrp and ns83820_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ns83820.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index d3afb458987..e736aec588f 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -430,10 +430,6 @@ struct ns83820 { struct pci_dev *pci_dev; struct net_device *ndev; -#ifdef NS83820_VLAN_ACCEL_SUPPORT - struct vlan_group *vlgrp; -#endif - struct rx_info rx_info; struct tasklet_struct rx_tasklet; @@ -494,22 +490,6 @@ static inline void kick_rx(struct net_device *ndev) #define start_tx_okay(dev) \ (((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE) - -#ifdef NS83820_VLAN_ACCEL_SUPPORT -static void ns83820_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp) -{ - struct ns83820 *dev = PRIV(ndev); - - spin_lock_irq(&dev->misc_lock); - spin_lock(&dev->tx_lock); - - dev->vlgrp = grp; - - spin_unlock(&dev->tx_lock); - spin_unlock_irq(&dev->misc_lock); -} -#endif - /* Packet Receiver * * The hardware supports linked lists of receive descriptors for @@ -930,14 +910,12 @@ static void rx_irq(struct net_device *ndev) #ifdef NS83820_VLAN_ACCEL_SUPPORT if(extsts & EXTSTS_VPKT) { unsigned short tag; + tag = ntohs(extsts & EXTSTS_VTG_MASK); - rx_rc = vlan_hwaccel_rx(skb,dev->vlgrp,tag); - } else { - rx_rc = netif_rx(skb); + __vlan_hwaccel_put_tag(skb, tag); } -#else - rx_rc = netif_rx(skb); #endif + rx_rc = netif_rx(skb); if (NET_RX_DROP == rx_rc) { netdev_mangle_me_harder_failed: ndev->stats.rx_dropped++; @@ -1961,11 +1939,8 @@ static const struct net_device_ops netdev_ops = { .ndo_change_mtu = ns83820_change_mtu, .ndo_set_multicast_list = ns83820_set_multicast, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_tx_timeout = ns83820_tx_timeout, -#ifdef NS83820_VLAN_ACCEL_SUPPORT - .ndo_vlan_rx_register = ns83820_vlan_rx_register, -#endif }; static int __devinit ns83820_init_one(struct pci_dev *pci_dev, -- cgit v1.2.3-70-g09d2 From 924917098e4bc3561a372a6eb36993e7c3bb02f2 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:33 +0000 Subject: atl1: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and atlx_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/atlx/atl1.c | 21 +++++++++--------- drivers/net/atlx/atl1.h | 1 - drivers/net/atlx/atlx.c | 57 ++++++++++++++++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 28 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index cd5789ff372..6f0e9403004 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -1285,8 +1285,7 @@ static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) value |= (((u32) adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); /* vlan */ - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; + __atlx_vlan_mode(netdev->features, &value); /* rx checksum if (adapter->rx_csum) value |= MAC_CTRL_RX_CHKSUM_EN; @@ -2023,13 +2022,14 @@ rrd_ok: atl1_rx_checksum(adapter, rrd, skb); skb->protocol = eth_type_trans(skb, adapter->netdev); - if (adapter->vlgrp && (rrd->pkt_flg & PACKET_FLAG_VLAN_INS)) { + if (rrd->pkt_flg & PACKET_FLAG_VLAN_INS) { u16 vlan_tag = (rrd->vlan_tag >> 4) | ((rrd->vlan_tag & 7) << 13) | ((rrd->vlan_tag & 8) << 9); - vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); - } else - netif_rx(skb); + + __vlan_hwaccel_put_tag(skb, vlan_tag); + } + netif_rx(skb); /* let protocol layer free skb */ buffer_info->skb = NULL; @@ -2783,8 +2783,7 @@ static int atl1_suspend(struct device *dev) ctrl |= MAC_CTRL_DUPLX; ctrl |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - if (adapter->vlgrp) - ctrl |= MAC_CTRL_RMV_VLAN; + __atlx_vlan_mode(netdev->features, &ctrl); if (wufc & ATLX_WUFC_MAG) ctrl |= MAC_CTRL_BC_EN; iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); @@ -2874,9 +2873,10 @@ static const struct net_device_ops atl1_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl1_set_mac, .ndo_change_mtu = atl1_change_mtu, + .ndo_fix_features = atlx_fix_features, + .ndo_set_features = atlx_set_features, .ndo_do_ioctl = atlx_ioctl, .ndo_tx_timeout = atlx_tx_timeout, - .ndo_vlan_rx_register = atlx_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl1_poll_controller, #endif @@ -2984,7 +2984,8 @@ static int __devinit atl1_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_SG; netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO; + netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO | + NETIF_F_HW_VLAN_RX; /* is this valid? see atl1_setup_mac_ctrl() */ netdev->features |= NETIF_F_RXCSUM; diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h index 68de8cbfb3e..109d6da8be9 100644 --- a/drivers/net/atlx/atl1.h +++ b/drivers/net/atlx/atl1.h @@ -753,7 +753,6 @@ struct atl1_adapter { struct pci_dev *pdev; struct atl1_sft_stats soft_stats; - struct vlan_group *vlgrp; u32 rx_buffer_len; u32 wol; u16 link_speed; diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index afb7f7dd1bb..aabcf4b5745 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c @@ -211,8 +211,18 @@ static void atlx_link_chg_task(struct work_struct *work) spin_unlock_irqrestore(&adapter->lock, flags); } -static void atlx_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atlx_vlan_mode(u32 features, u32 *ctrl) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *ctrl |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *ctrl &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atlx_vlan_mode(struct net_device *netdev, u32 features) { struct atlx_adapter *adapter = netdev_priv(netdev); unsigned long flags; @@ -220,27 +230,40 @@ static void atlx_vlan_rx_register(struct net_device *netdev, spin_lock_irqsave(&adapter->lock, flags); /* atlx_irq_disable(adapter); FIXME: confirm/remove */ - adapter->vlgrp = grp; - - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl |= MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } else { - /* disable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } - + ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); + __atlx_vlan_mode(features, &ctrl); + iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); /* atlx_irq_enable(adapter); FIXME */ spin_unlock_irqrestore(&adapter->lock, flags); } static void atlx_restore_vlan(struct atlx_adapter *adapter) { - atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp); + atlx_vlan_mode(adapter->netdev, adapter->netdev->features); +} + +static u32 atlx_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int atlx_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atlx_vlan_mode(netdev, features); + + return 0; } #endif /* ATLX_C */ -- cgit v1.2.3-70-g09d2 From dc437974af52e78f2736543dfee94cc385dae6e9 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:34 +0000 Subject: atl2: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and atl2_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/atlx/atl2.c | 78 ++++++++++++++++++++++++++++++------------------- drivers/net/atlx/atl2.h | 3 -- 2 files changed, 48 insertions(+), 33 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 24e15926cee..e0f87cf1e2b 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -361,36 +361,59 @@ static inline void atl2_irq_disable(struct atl2_adapter *adapter) synchronize_irq(adapter->pdev->irq); } -#ifdef NETIF_F_HW_VLAN_TX -static void atl2_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void __atl2_vlan_mode(u32 features, u32 *ctrl) +{ + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + *ctrl |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + *ctrl &= ~MAC_CTRL_RMV_VLAN; + } +} + +static void atl2_vlan_mode(struct net_device *netdev, u32 features) { struct atl2_adapter *adapter = netdev_priv(netdev); u32 ctrl; atl2_irq_disable(adapter); - adapter->vlgrp = grp; - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); - ctrl |= MAC_CTRL_RMV_VLAN; - ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); - } else { - /* disable VLAN tag insert/strip */ - ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_RMV_VLAN; - ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); - } + ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); + __atl2_vlan_mode(features, &ctrl); + ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); atl2_irq_enable(adapter); } static void atl2_restore_vlan(struct atl2_adapter *adapter) { - atl2_vlan_rx_register(adapter->netdev, adapter->vlgrp); + atl2_vlan_mode(adapter->netdev, adapter->netdev->features); +} + +static u32 atl2_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int atl2_set_features(struct net_device *netdev, u32 features) +{ + u32 changed = netdev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + atl2_vlan_mode(netdev, features); + + return 0; } -#endif static void atl2_intr_rx(struct atl2_adapter *adapter) { @@ -424,14 +447,13 @@ static void atl2_intr_rx(struct atl2_adapter *adapter) memcpy(skb->data, rxd->packet, rx_size); skb_put(skb, rx_size); skb->protocol = eth_type_trans(skb, netdev); -#ifdef NETIF_F_HW_VLAN_TX - if (adapter->vlgrp && (rxd->status.vlan)) { + if (rxd->status.vlan) { u16 vlan_tag = (rxd->status.vtag>>4) | ((rxd->status.vtag&7) << 13) | ((rxd->status.vtag&8) << 9); - vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); - } else -#endif + + __vlan_hwaccel_put_tag(skb, vlan_tag); + } netif_rx(skb); netdev->stats.rx_bytes += rx_size; netdev->stats.rx_packets++; @@ -704,9 +726,7 @@ static int atl2_open(struct net_device *netdev) atl2_set_multi(netdev); init_ring_ptrs(adapter); -#ifdef NETIF_F_HW_VLAN_TX atl2_restore_vlan(adapter); -#endif if (atl2_configure(adapter)) { err = -EIO; @@ -1082,9 +1102,7 @@ static int atl2_up(struct atl2_adapter *adapter) atl2_set_multi(netdev); init_ring_ptrs(adapter); -#ifdef NETIF_F_HW_VLAN_TX atl2_restore_vlan(adapter); -#endif if (atl2_configure(adapter)) { err = -EIO; @@ -1145,8 +1163,7 @@ static void atl2_setup_mac_ctrl(struct atl2_adapter *adapter) MAC_CTRL_PRMLEN_SHIFT); /* vlan */ - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; + __atl2_vlan_mode(netdev->features, &value); /* filter mode */ value |= MAC_CTRL_BC_EN; @@ -1312,9 +1329,10 @@ static const struct net_device_ops atl2_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl2_set_mac, .ndo_change_mtu = atl2_change_mtu, + .ndo_fix_features = atl2_fix_features, + .ndo_set_features = atl2_set_features, .ndo_do_ioctl = atl2_ioctl, .ndo_tx_timeout = atl2_tx_timeout, - .ndo_vlan_rx_register = atl2_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = atl2_poll_controller, #endif @@ -1410,7 +1428,7 @@ static int __devinit atl2_probe(struct pci_dev *pdev, err = -EIO; - netdev->hw_features = NETIF_F_SG; + netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_RX; netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); /* Init PHY as early as possible due to power saving issue */ diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h index 927e4de6474..78344ddf4bf 100644 --- a/drivers/net/atlx/atl2.h +++ b/drivers/net/atlx/atl2.h @@ -453,9 +453,6 @@ struct atl2_adapter { /* OS defined structs */ struct net_device *netdev; struct pci_dev *pdev; -#ifdef NETIF_F_HW_VLAN_TX - struct vlan_group *vlgrp; -#endif u32 wol; u16 link_speed; u16 link_duplex; -- cgit v1.2.3-70-g09d2 From 892ef5d85259e193505d553c10237fd5dc9a3d0d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:35 +0000 Subject: cxgb3: do vlan cleanup - unify vlan and nonvlan rx path - kill pi->vlan_grp and vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/cxgb3/adapter.h | 2 -- drivers/net/cxgb3/cxgb3_main.c | 51 ++++++++++++++++++++++++++++++--------- drivers/net/cxgb3/cxgb3_offload.c | 9 +++---- drivers/net/cxgb3/sge.c | 35 +++++---------------------- 4 files changed, 49 insertions(+), 48 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 7300de5a142..8b395b53733 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -45,7 +45,6 @@ #include "t3cdev.h" #include -struct vlan_group; struct adapter; struct sge_qset; struct port_info; @@ -66,7 +65,6 @@ struct iscsi_config { struct port_info { struct adapter *adapter; - struct vlan_group *vlan_grp; struct sge_qset *qs; u8 port_id; u8 nqsets; diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 9081ce03714..93b41a7ac17 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -2532,25 +2532,51 @@ static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) } } -static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) +static void cxgb_vlan_mode(struct net_device *dev, u32 features) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - pi->vlan_grp = grp; - if (adapter->params.rev > 0) - t3_set_vlan_accel(adapter, 1 << pi->port_id, grp != NULL); - else { + if (adapter->params.rev > 0) { + t3_set_vlan_accel(adapter, 1 << pi->port_id, + features & NETIF_F_HW_VLAN_RX); + } else { /* single control for all ports */ - unsigned int i, have_vlans = 0; + unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; + for_each_port(adapter, i) - have_vlans |= adap2pinfo(adapter, i)->vlan_grp != NULL; + have_vlans |= + adapter->port[i]->features & NETIF_F_HW_VLAN_RX; t3_set_vlan_accel(adapter, 1, have_vlans); } t3_synchronize_rx(adapter, pi); } +static u32 cxgb_fix_features(struct net_device *dev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + +static int cxgb_set_features(struct net_device *dev, u32 features) +{ + u32 changed = dev->features ^ features; + + if (changed & NETIF_F_HW_VLAN_RX) + cxgb_vlan_mode(dev, features); + + return 0; +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void cxgb_netpoll(struct net_device *dev) { @@ -3131,7 +3157,8 @@ static const struct net_device_ops cxgb_netdev_ops = { .ndo_do_ioctl = cxgb_ioctl, .ndo_change_mtu = cxgb_change_mtu, .ndo_set_mac_address = cxgb_set_mac_addr, - .ndo_vlan_rx_register = vlan_rx_register, + .ndo_fix_features = cxgb_fix_features, + .ndo_set_features = cxgb_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = cxgb_netpoll, #endif @@ -3263,9 +3290,8 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_RXCSUM; - netdev->features |= netdev->hw_features | - NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX; + netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_TX; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -3329,6 +3355,9 @@ static int __devinit init_one(struct pci_dev *pdev, err = sysfs_create_group(&adapter->port[0]->dev.kobj, &cxgb3_attr_group); + for_each_port(adapter, i) + cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); + print_port_info(adapter, ai); return 0; diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index fa1b450af82..32636a1d62a 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -176,16 +176,13 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter, int i; for_each_port(adapter, i) { - struct vlan_group *grp; struct net_device *dev = adapter->port[i]; - const struct port_info *p = netdev_priv(dev); if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) { if (vlan && vlan != VLAN_VID_MASK) { - grp = p->vlan_grp; - dev = NULL; - if (grp) - dev = vlan_group_get_device(grp, vlan); + rcu_read_lock(); + dev = __vlan_find_dev_deep(dev, vlan); + rcu_read_unlock(); } else if (netif_is_bond_slave(dev)) { while (dev->master) dev = dev->master; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 76bf5892b96..d6fa1777a34 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2028,28 +2028,11 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, skb_checksum_none_assert(skb); skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); - if (unlikely(p->vlan_valid)) { - struct vlan_group *grp = pi->vlan_grp; - + if (p->vlan_valid) { qs->port_stats[SGE_PSTAT_VLANEX]++; - if (likely(grp)) - if (lro) - vlan_gro_receive(&qs->napi, grp, - ntohs(p->vlan), skb); - else { - if (unlikely(pi->iscsic.flags)) { - unsigned short vtag = ntohs(p->vlan) & - VLAN_VID_MASK; - skb->dev = vlan_group_get_device(grp, - vtag); - cxgb3_process_iscsi_prov_pack(pi, skb); - } - __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan), - rq->polling); - } - else - dev_kfree_skb_any(skb); - } else if (rq->polling) { + __vlan_hwaccel_put_tag(skb, ntohs(p->vlan)); + } + if (rq->polling) { if (lro) napi_gro_receive(&qs->napi, skb); else { @@ -2147,14 +2130,8 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); - if (unlikely(cpl->vlan_valid)) { - struct vlan_group *grp = pi->vlan_grp; - - if (likely(grp != NULL)) { - vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan)); - return; - } - } + if (cpl->vlan_valid) + __vlan_hwaccel_put_tag(skb, ntohs(cpl->vlan)); napi_gro_frags(&qs->napi); } -- cgit v1.2.3-70-g09d2 From 5622e4044a916de1af84bfcc4d437ce0c799d531 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 21 Jul 2011 03:26:31 +0000 Subject: e1000: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and e1000_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/e1000/e1000.h | 2 +- drivers/net/e1000/e1000_main.c | 168 ++++++++++++++++++++++++++--------------- 2 files changed, 108 insertions(+), 62 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 8676899120c..24f41da8c4b 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -215,7 +215,7 @@ struct e1000_adapter { struct timer_list tx_fifo_stall_timer; struct timer_list watchdog_timer; struct timer_list phy_info_timer; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 mng_vlan_id; u32 bd_number; u32 rx_buffer_len; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 188d99ae908..acaebecf0ca 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include /* Intel Media SOC GbE MDIO physical base address */ static unsigned long ce4100_gbe_mdio_base_phy; @@ -166,7 +168,8 @@ static void e1000_smartspeed(struct e1000_adapter *adapter); static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb); -static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); +static bool e1000_vlan_used(struct e1000_adapter *adapter); +static void e1000_vlan_mode(struct net_device *netdev, u32 features); static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); @@ -330,21 +333,24 @@ static void e1000_update_mng_vlan(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; u16 vid = hw->mng_cookie.vlan_id; u16 old_vid = adapter->mng_vlan_id; - if (adapter->vlgrp) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) { - if (hw->mng_cookie.status & - E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) { - e1000_vlan_rx_add_vid(netdev, vid); - adapter->mng_vlan_id = vid; - } else - adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; - if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && - (vid != old_vid) && - !vlan_group_get_device(adapter->vlgrp, old_vid)) - e1000_vlan_rx_kill_vid(netdev, old_vid); - } else + if (!e1000_vlan_used(adapter)) + return; + + if (!test_bit(vid, adapter->active_vlans)) { + if (hw->mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) { + e1000_vlan_rx_add_vid(netdev, vid); adapter->mng_vlan_id = vid; + } else { + adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; + } + if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && + (vid != old_vid) && + !test_bit(old_vid, adapter->active_vlans)) + e1000_vlan_rx_kill_vid(netdev, old_vid); + } else { + adapter->mng_vlan_id = vid; } } @@ -797,11 +803,28 @@ static int e1000_is_need_ioport(struct pci_dev *pdev) } } +static u32 e1000_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + static int e1000_set_features(struct net_device *netdev, u32 features) { struct e1000_adapter *adapter = netdev_priv(netdev); u32 changed = features ^ netdev->features; + if (changed & NETIF_F_HW_VLAN_RX) + e1000_vlan_mode(netdev, features); + if (!(changed & NETIF_F_RXCSUM)) return 0; @@ -822,18 +845,17 @@ static const struct net_device_ops e1000_netdev_ops = { .ndo_get_stats = e1000_get_stats, .ndo_set_rx_mode = e1000_set_rx_mode, .ndo_set_mac_address = e1000_set_mac, - .ndo_tx_timeout = e1000_tx_timeout, + .ndo_tx_timeout = e1000_tx_timeout, .ndo_change_mtu = e1000_change_mtu, .ndo_do_ioctl = e1000_ioctl, .ndo_validate_addr = eth_validate_addr, - - .ndo_vlan_rx_register = e1000_vlan_rx_register, .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = e1000_netpoll, #endif - .ndo_set_features = e1000_set_features, + .ndo_fix_features = e1000_fix_features, + .ndo_set_features = e1000_set_features, }; /** @@ -1036,9 +1058,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (hw->mac_type >= e1000_82543) { netdev->hw_features = NETIF_F_SG | - NETIF_F_HW_CSUM; + NETIF_F_HW_CSUM | + NETIF_F_HW_VLAN_RX; netdev->features = NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; } @@ -1197,6 +1219,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) goto err_register; + e1000_vlan_mode(netdev, netdev->features); + /* print bus type/speed/width info */ e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), @@ -1441,8 +1465,7 @@ static int e1000_close(struct net_device *netdev) * the same ID is registered on the host OS (let 8021q kill it) */ if ((hw->mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && - !(adapter->vlgrp && - vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) { + !test_bit(adapter->mng_vlan_id, adapter->active_vlans)) { e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); } @@ -2233,7 +2256,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) else rctl &= ~E1000_RCTL_MPE; /* Enable VLAN filter if there is a VLAN */ - if (adapter->vlgrp) + if (e1000_vlan_used(adapter)) rctl |= E1000_RCTL_VFE; } @@ -3180,7 +3203,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, } } - if (unlikely(vlan_tx_tag_present(skb))) { + if (vlan_tx_tag_present(skb)) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } @@ -3735,12 +3758,12 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status, { skb->protocol = eth_type_trans(skb, adapter->netdev); - if ((unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP)))) - vlan_gro_receive(&adapter->napi, adapter->vlgrp, - le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK, - skb); - else - napi_gro_receive(&adapter->napi, skb); + if (status & E1000_RXD_STAT_VP) { + u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; + + __vlan_hwaccel_put_tag(skb, vid); + } + napi_gro_receive(&adapter->napi, skb); } /** @@ -4523,46 +4546,61 @@ void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value) outl(value, port); } -static void e1000_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static bool e1000_vlan_used(struct e1000_adapter *adapter) +{ + u16 vid; + + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + return true; + return false; +} + +static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, + bool filter_on) { - struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - u32 ctrl, rctl; + u32 rctl; if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_disable(adapter); - adapter->vlgrp = grp; - - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_VME; - ew32(CTRL, ctrl); + if (filter_on) { /* enable VLAN receive filtering */ rctl = er32(RCTL); rctl &= ~E1000_RCTL_CFIEN; - if (!(netdev->flags & IFF_PROMISC)) + if (!(adapter->netdev->flags & IFF_PROMISC)) rctl |= E1000_RCTL_VFE; ew32(RCTL, rctl); e1000_update_mng_vlan(adapter); } else { - /* disable VLAN tag insert/strip */ - ctrl = er32(CTRL); - ctrl &= ~E1000_CTRL_VME; - ew32(CTRL, ctrl); - /* disable VLAN receive filtering */ rctl = er32(RCTL); rctl &= ~E1000_RCTL_VFE; ew32(RCTL, rctl); + } - if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) { - e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); - adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; - } + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_enable(adapter); +} + +static void e1000_vlan_mode(struct net_device *netdev, u32 features) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 ctrl; + + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_disable(adapter); + + ctrl = er32(CTRL); + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + ctrl |= E1000_CTRL_VME; + } else { + /* disable VLAN tag insert/strip */ + ctrl &= ~E1000_CTRL_VME; } + ew32(CTRL, ctrl); if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_enable(adapter); @@ -4578,11 +4616,17 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid) E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && (vid == adapter->mng_vlan_id)) return; + + if (!e1000_vlan_used(adapter)) + e1000_vlan_filter_on_off(adapter, true); + /* add VID to filter table */ index = (vid >> 5) & 0x7F; vfta = E1000_READ_REG_ARRAY(hw, VFTA, index); vfta |= (1 << (vid & 0x1F)); e1000_write_vfta(hw, index, vfta); + + set_bit(vid, adapter->active_vlans); } static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -4593,7 +4637,6 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_disable(adapter); - vlan_group_set_device(adapter->vlgrp, vid, NULL); if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_enable(adapter); @@ -4602,20 +4645,23 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) vfta = E1000_READ_REG_ARRAY(hw, VFTA, index); vfta &= ~(1 << (vid & 0x1F)); e1000_write_vfta(hw, index, vfta); + + clear_bit(vid, adapter->active_vlans); + + if (!e1000_vlan_used(adapter)) + e1000_vlan_filter_on_off(adapter, false); } static void e1000_restore_vlan(struct e1000_adapter *adapter) { - e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - e1000_vlan_rx_add_vid(adapter->netdev, vid); - } - } + if (!e1000_vlan_used(adapter)) + return; + + e1000_vlan_filter_on_off(adapter, true); + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + e1000_vlan_rx_add_vid(adapter->netdev, vid); } int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx) -- cgit v1.2.3-70-g09d2 From 3326c784c9f492e988617d93f647ae0cfd4c8d09 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:38 +0000 Subject: forcedeth: do vlan cleanup - unify vlan and nonvlan rx path - kill np->vlangrp and nv_vlan_rx_register - allow to turn on/off rx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 68 ++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 38 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 537b6957bb7..e64cd9ceac3 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -820,9 +820,6 @@ struct fe_priv { struct nv_skb_map *tx_end_flip; int tx_stop; - /* vlan fields */ - struct vlan_group *vlangrp; - /* msi/msi-x fields */ u32 msi_flags; struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS]; @@ -2766,17 +2763,13 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); prefetch(skb->data); - if (likely(!np->vlangrp)) { - napi_gro_receive(&np->napi, skb); - } else { - vlanflags = le32_to_cpu(np->get_rx.ex->buflow); - if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) { - vlan_gro_receive(&np->napi, np->vlangrp, - vlanflags & NV_RX3_VLAN_TAG_MASK, skb); - } else { - napi_gro_receive(&np->napi, skb); - } + vlanflags = le32_to_cpu(np->get_rx.ex->buflow); + if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) { + u16 vid = vlanflags & NV_RX3_VLAN_TAG_MASK; + + __vlan_hwaccel_put_tag(skb, vid); } + napi_gro_receive(&np->napi, skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; @@ -4484,6 +4477,27 @@ static u32 nv_fix_features(struct net_device *dev, u32 features) return features; } +static void nv_vlan_mode(struct net_device *dev, u32 features) +{ + struct fe_priv *np = get_nvpriv(dev); + + spin_lock_irq(&np->lock); + + if (features & NETIF_F_HW_VLAN_RX) + np->txrxctl_bits |= NVREG_TXRXCTL_VLANSTRIP; + else + np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANSTRIP; + + if (features & NETIF_F_HW_VLAN_TX) + np->txrxctl_bits |= NVREG_TXRXCTL_VLANINS; + else + np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANINS; + + writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + + spin_unlock_irq(&np->lock); +} + static int nv_set_features(struct net_device *dev, u32 features) { struct fe_priv *np = netdev_priv(dev); @@ -4504,6 +4518,9 @@ static int nv_set_features(struct net_device *dev, u32 features) spin_unlock_irq(&np->lock); } + if (changed & (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX)) + nv_vlan_mode(dev, features); + return 0; } @@ -4879,29 +4896,6 @@ static const struct ethtool_ops ops = { .self_test = nv_self_test, }; -static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct fe_priv *np = get_nvpriv(dev); - - spin_lock_irq(&np->lock); - - /* save vlan group */ - np->vlangrp = grp; - - if (grp) { - /* enable vlan on MAC */ - np->txrxctl_bits |= NVREG_TXRXCTL_VLANSTRIP | NVREG_TXRXCTL_VLANINS; - } else { - /* disable vlan on MAC */ - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANSTRIP; - np->txrxctl_bits &= ~NVREG_TXRXCTL_VLANINS; - } - - writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); - - spin_unlock_irq(&np->lock); -} - /* The mgmt unit and driver use a semaphore to access the phy during init */ static int nv_mgmt_acquire_sema(struct net_device *dev) { @@ -5208,7 +5202,6 @@ static const struct net_device_ops nv_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, - .ndo_vlan_rx_register = nv_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = nv_poll_controller, #endif @@ -5226,7 +5219,6 @@ static const struct net_device_ops nv_netdev_ops_optimized = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, - .ndo_vlan_rx_register = nv_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = nv_poll_controller, #endif -- cgit v1.2.3-70-g09d2 From b2cb09b1a7725408a3464b2f593ceb222eff1042 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 21 Jul 2011 03:27:27 +0000 Subject: igb: do vlan cleanup - unify vlan and nonvlan rx path - kill adapter->vlgrp and igb_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool (set_features) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/igb/igb.h | 4 ++- drivers/net/igb/igb_main.c | 90 +++++++++++++++++++++++----------------------- 2 files changed, 47 insertions(+), 47 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 0389ff6ea69..265e151b66c 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -37,6 +37,8 @@ #include #include #include +#include +#include struct igb_adapter; @@ -252,7 +254,7 @@ static inline int igb_desc_unused(struct igb_ring *ring) struct igb_adapter { struct timer_list watchdog_timer; struct timer_list phy_info_timer; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 mng_vlan_id; u32 bd_number; u32 wol; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index f4d82b2859d..cb8c6bbbf0d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ #include #include #include +#include #ifdef CONFIG_IGB_DCA #include #endif @@ -140,7 +142,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *, int *, int); static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); static void igb_tx_timeout(struct net_device *); static void igb_reset_task(struct work_struct *); -static void igb_vlan_rx_register(struct net_device *, struct vlan_group *); +static void igb_vlan_mode(struct net_device *netdev, u32 features); static void igb_vlan_rx_add_vid(struct net_device *, u16); static void igb_vlan_rx_kill_vid(struct net_device *, u16); static void igb_restore_vlan(struct igb_adapter *); @@ -1362,7 +1364,7 @@ static void igb_update_mng_vlan(struct igb_adapter *adapter) if ((old_vid != (u16)IGB_MNG_VLAN_NONE) && (vid != old_vid) && - !vlan_group_get_device(adapter->vlgrp, old_vid)) { + !test_bit(old_vid, adapter->active_vlans)) { /* remove VID from filter table */ igb_vfta_set(hw, old_vid, false); } @@ -1748,10 +1750,25 @@ void igb_reset(struct igb_adapter *adapter) igb_get_phy_info(hw); } +static u32 igb_fix_features(struct net_device *netdev, u32 features) +{ + /* + * Since there is no support for separate rx/tx vlan accel + * enable/disable make sure tx flag is always in same state as rx. + */ + if (features & NETIF_F_HW_VLAN_RX) + features |= NETIF_F_HW_VLAN_TX; + else + features &= ~NETIF_F_HW_VLAN_TX; + + return features; +} + static int igb_set_features(struct net_device *netdev, u32 features) { struct igb_adapter *adapter = netdev_priv(netdev); int i; + u32 changed = netdev->features ^ features; for (i = 0; i < adapter->num_rx_queues; i++) { if (features & NETIF_F_RXCSUM) @@ -1760,6 +1777,9 @@ static int igb_set_features(struct net_device *netdev, u32 features) adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM; } + if (changed & NETIF_F_HW_VLAN_RX) + igb_vlan_mode(netdev, features); + return 0; } @@ -1775,7 +1795,6 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_do_ioctl = igb_ioctl, .ndo_tx_timeout = igb_tx_timeout, .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = igb_vlan_rx_register, .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid, .ndo_set_vf_mac = igb_ndo_set_vf_mac, @@ -1785,7 +1804,8 @@ static const struct net_device_ops igb_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = igb_netpoll, #endif - .ndo_set_features = igb_set_features, + .ndo_fix_features = igb_fix_features, + .ndo_set_features = igb_set_features, }; /** @@ -1930,11 +1950,11 @@ static int __devinit igb_probe(struct pci_dev *pdev, NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_RXCSUM; + NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_RX; netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; netdev->vlan_features |= NETIF_F_TSO; @@ -2057,6 +2077,8 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (err) goto err_register; + igb_vlan_mode(netdev, netdev->features); + /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); @@ -2939,12 +2961,11 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size, **/ static void igb_rlpml_set(struct igb_adapter *adapter) { - u32 max_frame_size = adapter->max_frame_size; + u32 max_frame_size; struct e1000_hw *hw = &adapter->hw; u16 pf_id = adapter->vfs_allocated_count; - if (adapter->vlgrp) - max_frame_size += VLAN_TAG_SIZE; + max_frame_size = adapter->max_frame_size + VLAN_TAG_SIZE; /* if vfs are enabled we set RLPML to the largest possible request * size and set the VMOLR RLPML to the size we need */ @@ -5693,25 +5714,6 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) return count < tx_ring->count; } -/** - * igb_receive_skb - helper function to handle rx indications - * @q_vector: structure containing interrupt and ring information - * @skb: packet to send up - * @vlan_tag: vlan tag for packet - **/ -static void igb_receive_skb(struct igb_q_vector *q_vector, - struct sk_buff *skb, - u16 vlan_tag) -{ - struct igb_adapter *adapter = q_vector->adapter; - - if (vlan_tag && adapter->vlgrp) - vlan_gro_receive(&q_vector->napi, adapter->vlgrp, - vlan_tag, skb); - else - napi_gro_receive(&q_vector->napi, skb); -} - static inline void igb_rx_checksum_adv(struct igb_ring *ring, u32 status_err, struct sk_buff *skb) { @@ -5809,7 +5811,6 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, unsigned int i; u32 staterr; u16 length; - u16 vlan_tag; i = rx_ring->next_to_clean; buffer_info = &rx_ring->buffer_info[i]; @@ -5894,10 +5895,12 @@ send_up: skb->protocol = eth_type_trans(skb, netdev); skb_record_rx_queue(skb, rx_ring->queue_index); - vlan_tag = ((staterr & E1000_RXD_STAT_VP) ? - le16_to_cpu(rx_desc->wb.upper.vlan) : 0); + if (staterr & E1000_RXD_STAT_VP) { + u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); - igb_receive_skb(q_vector, skb, vlan_tag); + __vlan_hwaccel_put_tag(skb, vid); + } + napi_gro_receive(&q_vector->napi, skb); next_desc: rx_desc->wb.upper.status_error = 0; @@ -6290,17 +6293,15 @@ s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) return 0; } -static void igb_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +static void igb_vlan_mode(struct net_device *netdev, u32 features) { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u32 ctrl, rctl; igb_irq_disable(adapter); - adapter->vlgrp = grp; - if (grp) { + if (features & NETIF_F_HW_VLAN_RX) { /* enable VLAN tag insert/strip */ ctrl = rd32(E1000_CTRL); ctrl |= E1000_CTRL_VME; @@ -6334,6 +6335,8 @@ static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid) /* add the filter since PF can receive vlans w/o entry in vlvf */ igb_vfta_set(hw, vid, true); + + set_bit(vid, adapter->active_vlans); } static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -6344,7 +6347,6 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) s32 err; igb_irq_disable(adapter); - vlan_group_set_device(adapter->vlgrp, vid, NULL); if (!test_bit(__IGB_DOWN, &adapter->state)) igb_irq_enable(adapter); @@ -6355,20 +6357,16 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) /* if vid was not present in VLVF just remove it from table */ if (err) igb_vfta_set(hw, vid, false); + + clear_bit(vid, adapter->active_vlans); } static void igb_restore_vlan(struct igb_adapter *adapter) { - igb_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - igb_vlan_rx_add_vid(adapter->netdev, vid); - } - } + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + igb_vlan_rx_add_vid(adapter->netdev, vid); } int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx) -- cgit v1.2.3-70-g09d2 From 53515734888e018af7bcec6b4464bd9e28f1d655 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:40 +0000 Subject: vxge: do vlan cleanup - unify vlan and nonvlan rx path - kill vdev->vlgrp and vxge_vlan_rx_register Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 91 +++++++------------------------------------- drivers/net/vxge/vxge-main.h | 5 ++- 2 files changed, 16 insertions(+), 80 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 15d878b4547..178348a258d 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -43,6 +43,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -308,13 +309,10 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan, "%s: %s:%d skb protocol = %d", ring->ndev->name, __func__, __LINE__, skb->protocol); - if (ring->vlgrp && ext_info->vlan && - (ring->vlan_tag_strip == - VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE)) - vlan_gro_receive(ring->napi_p, ring->vlgrp, - ext_info->vlan, skb); - else - napi_gro_receive(ring->napi_p, skb); + if (ext_info->vlan && + ring->vlan_tag_strip == VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) + __vlan_hwaccel_put_tag(skb, ext_info->vlan); + napi_gro_receive(ring->napi_p, skb); vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__); @@ -1489,15 +1487,11 @@ vxge_restore_vpath_vid_table(struct vxge_vpath *vpath) struct vxgedev *vdev = vpath->vdev; u16 vid; - if (vdev->vlgrp && vpath->is_open) { + if (!vpath->is_open) + return status; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(vdev->vlgrp, vid)) - continue; - /* Add these vlan to the vid table */ - status = vxge_hw_vpath_vid_add(vpath->handle, vid); - } - } + for_each_set_bit(vid, vdev->active_vlans, VLAN_N_VID) + status = vxge_hw_vpath_vid_add(vpath->handle, vid); return status; } @@ -3302,60 +3296,6 @@ static void vxge_tx_watchdog(struct net_device *dev) "%s:%d Exiting...", __func__, __LINE__); } -/** - * vxge_vlan_rx_register - * @dev: net device pointer. - * @grp: vlan group - * - * Vlan group registration - */ -static void -vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct vxgedev *vdev; - struct vxge_vpath *vpath; - int vp; - u64 vid; - enum vxge_hw_status status; - int i; - - vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - - vdev = netdev_priv(dev); - - vpath = &vdev->vpaths[0]; - if ((NULL == grp) && (vpath->is_open)) { - /* Get the first vlan */ - status = vxge_hw_vpath_vid_get(vpath->handle, &vid); - - while (status == VXGE_HW_OK) { - - /* Delete this vlan from the vid table */ - for (vp = 0; vp < vdev->no_of_vpath; vp++) { - vpath = &vdev->vpaths[vp]; - if (!vpath->is_open) - continue; - - vxge_hw_vpath_vid_delete(vpath->handle, vid); - } - - /* Get the next vlan to be deleted */ - vpath = &vdev->vpaths[0]; - status = vxge_hw_vpath_vid_get(vpath->handle, &vid); - } - } - - vdev->vlgrp = grp; - - for (i = 0; i < vdev->no_of_vpath; i++) { - if (vdev->vpaths[i].is_configured) - vdev->vpaths[i].ring.vlgrp = grp; - } - - vxge_debug_entryexit(VXGE_TRACE, - "%s:%d Exiting...", __func__, __LINE__); -} - /** * vxge_vlan_rx_add_vid * @dev: net device pointer. @@ -3366,12 +3306,10 @@ vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) static void vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { - struct vxgedev *vdev; + struct vxgedev *vdev = netdev_priv(dev); struct vxge_vpath *vpath; int vp_id; - vdev = netdev_priv(dev); - /* Add these vlan to the vid table */ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { vpath = &vdev->vpaths[vp_id]; @@ -3379,6 +3317,7 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) continue; vxge_hw_vpath_vid_add(vpath->handle, vid); } + set_bit(vid, vdev->active_vlans); } /** @@ -3391,16 +3330,12 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) static void vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { - struct vxgedev *vdev; + struct vxgedev *vdev = netdev_priv(dev); struct vxge_vpath *vpath; int vp_id; vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = netdev_priv(dev); - - vlan_group_set_device(vdev->vlgrp, vid, NULL); - /* Delete this vlan from the vid table */ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { vpath = &vdev->vpaths[vp_id]; @@ -3410,6 +3345,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) } vxge_debug_entryexit(VXGE_TRACE, "%s:%d Exiting...", __func__, __LINE__); + clear_bit(vid, vdev->active_vlans); } static const struct net_device_ops vxge_netdev_ops = { @@ -3424,7 +3360,6 @@ static const struct net_device_ops vxge_netdev_ops = { .ndo_change_mtu = vxge_change_mtu, .ndo_fix_features = vxge_fix_features, .ndo_set_features = vxge_set_features, - .ndo_vlan_rx_register = vxge_vlan_rx_register, .ndo_vlan_rx_kill_vid = vxge_vlan_rx_kill_vid, .ndo_vlan_rx_add_vid = vxge_vlan_rx_add_vid, .ndo_tx_timeout = vxge_tx_watchdog, diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 66e6de86ff0..f52a42d1dbb 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -18,6 +18,8 @@ #include "vxge-config.h" #include "vxge-version.h" #include +#include +#include #define VXGE_DRIVER_NAME "vxge" #define VXGE_DRIVER_VENDOR "Neterion, Inc" @@ -287,7 +289,6 @@ struct vxge_ring { #define VXGE_MAX_MAC_ADDR_COUNT 30 int vlan_tag_strip; - struct vlan_group *vlgrp; u32 rx_vector_no; enum vxge_hw_status last_status; @@ -332,7 +333,7 @@ struct vxgedev { struct net_device *ndev; struct pci_dev *pdev; struct __vxge_hw_device *devh; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; int vlan_tag_strip; struct vxge_config config; unsigned long state; -- cgit v1.2.3-70-g09d2 From 5526c0313777d4e5a6551de6b34705ac1fce92a7 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:43 +0000 Subject: stmmac: do vlan cleanup - kill priv->vlgrp and stmmac_vlan_rx_register (used for nothing :)) Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 3 --- drivers/net/stmmac/stmmac_main.c | 17 ----------------- 2 files changed, 20 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 2b076b31362..4d8995df2f2 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -78,9 +78,6 @@ struct stmmac_priv { int wolenabled; #ifdef CONFIG_STMMAC_TIMER struct stmmac_timer *tm; -#endif -#ifdef STMMAC_VLAN_TAG_USED - struct vlan_group *vlgrp; #endif struct plat_stmmacenet_data *plat; }; diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index d37ebc80623..1002b551772 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1421,20 +1421,6 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return ret; } -#ifdef STMMAC_VLAN_TAG_USED -static void stmmac_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct stmmac_priv *priv = netdev_priv(dev); - - DBG(probe, INFO, "%s: Setting vlgrp to %p\n", dev->name, grp); - - spin_lock(&priv->lock); - priv->vlgrp = grp; - spin_unlock(&priv->lock); -} -#endif - static const struct net_device_ops stmmac_netdev_ops = { .ndo_open = stmmac_open, .ndo_start_xmit = stmmac_xmit, @@ -1445,9 +1431,6 @@ static const struct net_device_ops stmmac_netdev_ops = { .ndo_tx_timeout = stmmac_tx_timeout, .ndo_do_ioctl = stmmac_ioctl, .ndo_set_config = stmmac_config, -#ifdef STMMAC_VLAN_TAG_USED - .ndo_vlan_rx_register = stmmac_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = stmmac_poll_controller, #endif -- cgit v1.2.3-70-g09d2 From 223bb15e4a78115bb1bbc3e58e246d26f2c16462 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:44 +0000 Subject: qlcnic: remove usage of vlan_group_get_device Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 3579229db4a..5ca1b562443 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -4198,18 +4198,13 @@ static void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) { struct qlcnic_adapter *adapter = netdev_priv(netdev); - struct vlan_group *grp; struct net_device *dev; u16 vid; qlcnic_config_indev_addr(adapter, netdev, event); - grp = rcu_dereference_rtnl(netdev->vlgrp); - if (!grp) - return; - for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { - dev = vlan_group_get_device(grp, vid); + dev = __vlan_find_dev_deep(netdev, vid); if (!dev) continue; qlcnic_config_indev_addr(adapter, dev, event); -- cgit v1.2.3-70-g09d2 From cc0e40700656b09d93b062ef6c818aa45429d09a Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:46 +0000 Subject: bonding: do vlan cleanup Now when all devices are cleaned up, bond can be cleaned up as well - remove bond->vlgrp - remove bond_vlan_rx_register - substitute necessary occurences of vlan_group_get_device Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 4 +- drivers/net/bonding/bond_ipv6.c | 8 ++-- drivers/net/bonding/bond_main.c | 98 +++++++++-------------------------------- drivers/net/bonding/bonding.h | 6 ++- 4 files changed, 33 insertions(+), 83 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 2df9276720a..7f8b20a34ee 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -635,7 +635,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon client_info->ntt = 0; } - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { if (!vlan_get_tag(skb, &client_info->vlan_id)) client_info->tag = 1; } @@ -847,7 +847,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) skb->priority = TC_PRIO_CONTROL; skb->dev = slave->dev; - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { struct vlan_entry *vlan; vlan = bond_next_vlan(bond, diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c index 84fbd4ebd77..027a0ee7d85 100644 --- a/drivers/net/bonding/bond_ipv6.c +++ b/drivers/net/bonding/bond_ipv6.c @@ -183,10 +183,10 @@ static int bond_inet6addr_event(struct notifier_block *this, } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - if (!bond->vlgrp) - continue; - vlan_dev = vlan_group_get_device(bond->vlgrp, - vlan->vlan_id); + rcu_read_lock(); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); + rcu_read_unlock(); if (vlan_dev == event_dev) { switch (event) { case NETDEV_UP: diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b9eaf5c0dc7..02842d05c11 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -408,9 +408,8 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, } /* - * In the following 3 functions, bond_vlan_rx_register(), bond_vlan_rx_add_vid - * and bond_vlan_rx_kill_vid, We don't protect the slave list iteration with a - * lock because: + * In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid, + * We don't protect the slave list iteration with a lock because: * a. This operation is performed in IOCTL context, * b. The operation is protected by the RTNL semaphore in the 8021q code, * c. Holding a lock with BH disabled while directly calling a base driver @@ -425,33 +424,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, * worse, and if it works for regular VLAN usage it will work here too. */ -/** - * bond_vlan_rx_register - Propagates registration to slaves - * @bond_dev: bonding net device that got called - * @grp: vlan group being registered - */ -static void bond_vlan_rx_register(struct net_device *bond_dev, - struct vlan_group *grp) -{ - struct bonding *bond = netdev_priv(bond_dev); - struct slave *slave; - int i; - - write_lock_bh(&bond->lock); - bond->vlgrp = grp; - write_unlock_bh(&bond->lock); - - bond_for_each_slave(bond, slave, i) { - struct net_device *slave_dev = slave->dev; - const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - - if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && - slave_ops->ndo_vlan_rx_register) { - slave_ops->ndo_vlan_rx_register(slave_dev, grp); - } - } -} - /** * bond_vlan_rx_add_vid - Propagates adding an id to slaves * @bond_dev: bonding net device that got called @@ -489,7 +461,6 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid) { struct bonding *bond = netdev_priv(bond_dev); struct slave *slave; - struct net_device *vlan_dev; int i, res; bond_for_each_slave(bond, slave, i) { @@ -498,12 +469,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid) if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) && slave_ops->ndo_vlan_rx_kill_vid) { - /* Save and then restore vlan_dev in the grp array, - * since the slave's driver might clear it. - */ - vlan_dev = vlan_group_get_device(bond->vlgrp, vid); slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vid); - vlan_group_set_device(bond->vlgrp, vid, vlan_dev); } } @@ -519,13 +485,6 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla struct vlan_entry *vlan; const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - if (!bond->vlgrp) - return; - - if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && - slave_ops->ndo_vlan_rx_register) - slave_ops->ndo_vlan_rx_register(slave_dev, bond->vlgrp); - if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || !(slave_ops->ndo_vlan_rx_add_vid)) return; @@ -539,30 +498,16 @@ static void bond_del_vlans_from_slave(struct bonding *bond, { const struct net_device_ops *slave_ops = slave_dev->netdev_ops; struct vlan_entry *vlan; - struct net_device *vlan_dev; - - if (!bond->vlgrp) - return; if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || !(slave_ops->ndo_vlan_rx_kill_vid)) - goto unreg; + return; list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { if (!vlan->vlan_id) continue; - /* Save and then restore vlan_dev in the grp array, - * since the slave's driver might clear it. - */ - vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vlan->vlan_id); - vlan_group_set_device(bond->vlgrp, vlan->vlan_id, vlan_dev); } - -unreg: - if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && - slave_ops->ndo_vlan_rx_register) - slave_ops->ndo_vlan_rx_register(slave_dev, NULL); } /*------------------------------- Link status -------------------------------*/ @@ -836,13 +781,13 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) __bond_resend_igmp_join_requests(bond->dev); /* rejoin all groups on vlan devices */ - if (bond->vlgrp) { - list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - vlan_dev = vlan_group_get_device(bond->vlgrp, - vlan->vlan_id); - if (vlan_dev) - __bond_resend_igmp_join_requests(vlan_dev); - } + list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { + rcu_read_lock(); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); + rcu_read_unlock(); + if (vlan_dev) + __bond_resend_igmp_join_requests(vlan_dev); } if (--bond->igmp_retrans > 0) @@ -1557,7 +1502,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* no need to lock since we're protected by rtnl_lock */ if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", bond_dev->name, slave_dev->name, bond_dev->name); return -EPERM; @@ -2065,7 +2010,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) */ memset(bond_dev->dev_addr, 0, bond_dev->addr_len); - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", bond_dev->name, bond_dev->name); pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", @@ -2247,7 +2192,7 @@ static int bond_release_all(struct net_device *bond_dev) */ memset(bond_dev->dev_addr, 0, bond_dev->addr_len); - if (bond->vlgrp) { + if (bond_vlan_used(bond)) { pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", bond_dev->name, bond_dev->name); pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", @@ -2685,7 +2630,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) if (!targets[i]) break; pr_debug("basa: target %x\n", targets[i]); - if (!bond->vlgrp) { + if (!bond_vlan_used(bond)) { pr_debug("basa: empty vlan: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); @@ -2720,7 +2665,10 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) vlan_id = 0; list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); + rcu_read_lock(); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); + rcu_read_unlock(); if (vlan_dev == rt->dst.dev) { vlan_id = vlan->vlan_id; pr_debug("basa: vlan match on %s %d\n", @@ -3381,9 +3329,8 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - if (!bond->vlgrp) - continue; - vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); + vlan_dev = __vlan_find_dev_deep(bond->dev, + vlan->vlan_id); if (vlan_dev == event_dev) { switch (event) { case NETDEV_UP: @@ -4335,10 +4282,9 @@ static const struct net_device_ops bond_netdev_ops = { .ndo_do_ioctl = bond_do_ioctl, .ndo_set_multicast_list = bond_set_multicast_list, .ndo_change_mtu = bond_change_mtu, - .ndo_set_mac_address = bond_set_mac_address, + .ndo_set_mac_address = bond_set_mac_address, .ndo_neigh_setup = bond_neigh_setup, - .ndo_vlan_rx_register = bond_vlan_rx_register, - .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, + .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_netpoll_setup = bond_netpoll_setup, diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 2936171f533..43526a2d275 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -240,7 +240,6 @@ struct bonding { struct alb_bond_info alb_info; struct bond_params params; struct list_head vlan_list; - struct vlan_group *vlgrp; struct workqueue_struct *wq; struct delayed_work mii_work; struct delayed_work arp_work; @@ -253,6 +252,11 @@ struct bonding { #endif /* CONFIG_DEBUG_FS */ }; +static inline bool bond_vlan_used(struct bonding *bond) +{ + return !list_empty(&bond->vlan_list); +} + #define bond_slave_get_rcu(dev) \ ((struct slave *) rcu_dereference(dev->rx_handler_data)) -- cgit v1.2.3-70-g09d2 From 4f7a4505f8356a739b13e55e964a7f4dc43a1633 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 20 Jul 2011 04:54:47 +0000 Subject: macvlan: do vlan cleanup ndo_vlan_rx_register is no longer in use in any driver so remove it. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index cc67cbe670c..ba631fcece3 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -510,17 +510,6 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, return stats; } -static void macvlan_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct macvlan_dev *vlan = netdev_priv(dev); - struct net_device *lowerdev = vlan->lowerdev; - const struct net_device_ops *ops = lowerdev->netdev_ops; - - if (ops->ndo_vlan_rx_register) - ops->ndo_vlan_rx_register(lowerdev, grp); -} - static void macvlan_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { @@ -575,7 +564,6 @@ static const struct net_device_ops macvlan_netdev_ops = { .ndo_set_multicast_list = macvlan_set_multicast_list, .ndo_get_stats64 = macvlan_dev_get_stats64, .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = macvlan_vlan_rx_register, .ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid, }; -- cgit v1.2.3-70-g09d2 From 94c5b41b327e08de0ddf563237855f55080652a1 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Wed, 20 Jul 2011 16:57:36 +0000 Subject: jme: Fix unmap error (Causing system freeze) This patch add the missing dma_unmap(). Which solved the critical issue of system freeze on heavy load. Michal Miroslaw's rejected patch: [PATCH v2 10/46] net: jme: convert to generic DMA API Pointed out the issue also, thank you Michal. But the fix was incorrect. It would unmap needed address when low memory. Got lots of feedback from End user and Gentoo Bugzilla. https://bugs.gentoo.org/show_bug.cgi?id=373109 Thank you all. :) Cc: stable@kernel.org Signed-off-by: Guo-Fu Tseng Acked-by: Chris Wright Signed-off-by: David S. Miller --- drivers/net/jme.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index b5b174a8c14..19738143aa9 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -753,20 +753,28 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i) struct jme_ring *rxring = &(jme->rxring[0]); struct jme_buffer_info *rxbi = rxring->bufinf + i; struct sk_buff *skb; + dma_addr_t mapping; skb = netdev_alloc_skb(jme->dev, jme->dev->mtu + RX_EXTRA_LEN); if (unlikely(!skb)) return -ENOMEM; + mapping = pci_map_page(jme->pdev, virt_to_page(skb->data), + offset_in_page(skb->data), skb_tailroom(skb), + PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) { + dev_kfree_skb(skb); + return -ENOMEM; + } + + if (likely(rxbi->mapping)) + pci_unmap_page(jme->pdev, rxbi->mapping, + rxbi->len, PCI_DMA_FROMDEVICE); + rxbi->skb = skb; rxbi->len = skb_tailroom(skb); - rxbi->mapping = pci_map_page(jme->pdev, - virt_to_page(skb->data), - offset_in_page(skb->data), - rxbi->len, - PCI_DMA_FROMDEVICE); - + rxbi->mapping = mapping; return 0; } -- cgit v1.2.3-70-g09d2 From 3bec5dcc649bf6b9c8f9ea996c3333381665f263 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 20 Jul 2011 00:05:21 +0000 Subject: stmmac: update the version (V2) Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 4d8995df2f2..63979b75f08 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -20,7 +20,7 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#define DRV_MODULE_VERSION "Nov_2010" +#define DRV_MODULE_VERSION "July_2011" #include #include "common.h" -- cgit v1.2.3-70-g09d2 From f3240e2811f05f11126b0947ff9bb411b692b2aa Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 20 Jul 2011 00:05:22 +0000 Subject: stmmac: remove warning when compile as built-in (V2) The patch removes the following serie of warnings when the driver is compiled as built-in: drivers/net/stmmac/stmmac_main.c: In function stmmac_cmdline_opt: drivers/net/stmmac/stmmac_main.c:1855:12: warning: ignoring return value of kstrtoul, declared with attribute warn_unused_result [snip] Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 65 ++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 23 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 1002b551772..40a6ae58280 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1917,33 +1917,52 @@ static int __init stmmac_cmdline_opt(char *str) if (!str || !*str) return -EINVAL; while ((opt = strsep(&str, ",")) != NULL) { - if (!strncmp(opt, "debug:", 6)) - strict_strtoul(opt + 6, 0, (unsigned long *)&debug); - else if (!strncmp(opt, "phyaddr:", 8)) - strict_strtoul(opt + 8, 0, (unsigned long *)&phyaddr); - else if (!strncmp(opt, "dma_txsize:", 11)) - strict_strtoul(opt + 11, 0, - (unsigned long *)&dma_txsize); - else if (!strncmp(opt, "dma_rxsize:", 11)) - strict_strtoul(opt + 11, 0, - (unsigned long *)&dma_rxsize); - else if (!strncmp(opt, "buf_sz:", 7)) - strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz); - else if (!strncmp(opt, "tc:", 3)) - strict_strtoul(opt + 3, 0, (unsigned long *)&tc); - else if (!strncmp(opt, "watchdog:", 9)) - strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog); - else if (!strncmp(opt, "flow_ctrl:", 10)) - strict_strtoul(opt + 10, 0, - (unsigned long *)&flow_ctrl); - else if (!strncmp(opt, "pause:", 6)) - strict_strtoul(opt + 6, 0, (unsigned long *)&pause); + if (!strncmp(opt, "debug:", 6)) { + if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug)) + goto err; + } else if (!strncmp(opt, "phyaddr:", 8)) { + if (strict_strtoul(opt + 8, 0, + (unsigned long *)&phyaddr)) + goto err; + } else if (!strncmp(opt, "dma_txsize:", 11)) { + if (strict_strtoul(opt + 11, 0, + (unsigned long *)&dma_txsize)) + goto err; + } else if (!strncmp(opt, "dma_rxsize:", 11)) { + if (strict_strtoul(opt + 11, 0, + (unsigned long *)&dma_rxsize)) + goto err; + } else if (!strncmp(opt, "buf_sz:", 7)) { + if (strict_strtoul(opt + 7, 0, + (unsigned long *)&buf_sz)) + goto err; + } else if (!strncmp(opt, "tc:", 3)) { + if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc)) + goto err; + } else if (!strncmp(opt, "watchdog:", 9)) { + if (strict_strtoul(opt + 9, 0, + (unsigned long *)&watchdog)) + goto err; + } else if (!strncmp(opt, "flow_ctrl:", 10)) { + if (strict_strtoul(opt + 10, 0, + (unsigned long *)&flow_ctrl)) + goto err; + } else if (!strncmp(opt, "pause:", 6)) { + if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause)) + goto err; #ifdef CONFIG_STMMAC_TIMER - else if (!strncmp(opt, "tmrate:", 7)) - strict_strtoul(opt + 7, 0, (unsigned long *)&tmrate); + } else if (!strncmp(opt, "tmrate:", 7)) { + if (strict_strtoul(opt + 7, 0, + (unsigned long *)&tmrate)) + goto err; #endif + } } return 0; + +err: + pr_err("%s: ERROR broken module parameter conversion", __func__); + return -EINVAL; } __setup("stmmaceth=", stmmac_cmdline_opt); -- cgit v1.2.3-70-g09d2 From 36bcfe7d74782c07f601edc4831f6b1ef40e9e43 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 20 Jul 2011 00:05:23 +0000 Subject: stmmac: unify MAC and PHY configuration parameters (V2) Prior to this change, most PHY configuration parameters were passed into the STMMAC device as a separate PHY device. As well as being unusual, this made it difficult to make changes to the MAC/PHY relationship. This patch moves all the PHY parameters into the MAC configuration structure, mainly as a separate structure. This allows us to completely ignore the MDIO bus attached to a stmmac if desired, and not create the PHY bus. It also allows the stmmac driver to use a different PHY from the one it is connected to, for example a fixed PHY or bit banging PHY. Also derive the stmmac/PHY connection type (MII/RMII etc) from the mode can be passed into _configure_ethernet. STLinux kernel at git://git.stlinux.com/stm/linux-sh4-2.6.32.y.git provides several examples how to use this new infrastructure (that actually is easier to maintain and clearer). Signed-off-by: Stuart Menefy Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 6 +-- drivers/net/stmmac/stmmac_main.c | 95 +++------------------------------------- drivers/net/stmmac/stmmac_mdio.c | 83 ++++++++++++++++++++++++----------- include/linux/stmmac.h | 24 +++++----- 4 files changed, 77 insertions(+), 131 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 63979b75f08..de1929b2641 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -56,14 +56,9 @@ struct stmmac_priv { struct stmmac_extra_stats xstats; struct napi_struct napi; - phy_interface_t phy_interface; - int phy_addr; - int phy_mask; - int (*phy_reset) (void *priv); int rx_coe; int no_csum_insertion; - int phy_irq; struct phy_device *phydev; int oldlink; int speed; @@ -71,6 +66,7 @@ struct stmmac_priv { unsigned int flow_ctrl; unsigned int pause; struct mii_bus *mii; + int mii_irq[PHY_MAX_ADDR]; u32 msg_enable; spinlock_t lock; diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 40a6ae58280..c6e567e04ef 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -49,7 +49,6 @@ #include "stmmac.h" #define STMMAC_RESOURCE_NAME "stmmaceth" -#define PHY_RESOURCE_NAME "stmmacphy" #undef STMMAC_DEBUG /*#define STMMAC_DEBUG*/ @@ -305,18 +304,13 @@ static int stmmac_init_phy(struct net_device *dev) priv->speed = 0; priv->oldduplex = -1; - if (priv->phy_addr == -1) { - /* We don't have a PHY, so do nothing */ - return 0; - } - snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, - priv->phy_addr); + priv->plat->phy_addr); pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, - priv->phy_interface); + priv->plat->interface); if (IS_ERR(phydev)) { pr_err("%s: Could not attach to PHY\n", dev->name); @@ -335,7 +329,7 @@ static int stmmac_init_phy(struct net_device *dev) return -ENODEV; } pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" - " Link = %d\n", dev->name, phydev->phy_id, phydev->link); + " Link = %d\n", dev->name, phydev->phy_id, phydev->link); priv->phydev = phydev; @@ -1528,71 +1522,6 @@ static int stmmac_mac_device_setup(struct net_device *dev) return 0; } -static int stmmacphy_dvr_probe(struct platform_device *pdev) -{ - struct plat_stmmacphy_data *plat_dat = pdev->dev.platform_data; - - pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n", - plat_dat->bus_id); - - return 0; -} - -static int stmmacphy_dvr_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver stmmacphy_driver = { - .driver = { - .name = PHY_RESOURCE_NAME, - }, - .probe = stmmacphy_dvr_probe, - .remove = stmmacphy_dvr_remove, -}; - -/** - * stmmac_associate_phy - * @dev: pointer to device structure - * @data: points to the private structure. - * Description: Scans through all the PHYs we have registered and checks if - * any are associated with our MAC. If so, then just fill in - * the blanks in our local context structure - */ -static int stmmac_associate_phy(struct device *dev, void *data) -{ - struct stmmac_priv *priv = (struct stmmac_priv *)data; - struct plat_stmmacphy_data *plat_dat = dev->platform_data; - - DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__, - plat_dat->bus_id); - - /* Check that this phy is for the MAC being initialised */ - if (priv->plat->bus_id != plat_dat->bus_id) - return 0; - - /* OK, this PHY is connected to the MAC. - Go ahead and get the parameters */ - DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__); - priv->phy_irq = - platform_get_irq_byname(to_platform_device(dev), "phyirq"); - DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__, - plat_dat->bus_id, priv->phy_irq); - - /* Override with kernel parameters if supplied XXX CRS XXX - * this needs to have multiple instances */ - if ((phyaddr >= 0) && (phyaddr <= 31)) - plat_dat->phy_addr = phyaddr; - - priv->phy_addr = plat_dat->phy_addr; - priv->phy_mask = plat_dat->phy_mask; - priv->phy_interface = plat_dat->interface; - priv->phy_reset = plat_dat->phy_reset; - - DBG(probe, DEBUG, "%s: exiting\n", __func__); - return 1; /* forces exit of driver_for_each_device() */ -} - /** * stmmac_dvr_probe * @pdev: platform device pointer @@ -1683,14 +1612,10 @@ static int stmmac_dvr_probe(struct platform_device *pdev) if (ret < 0) goto out_plat_exit; - /* associate a PHY - it is provided by another platform bus */ - if (!driver_for_each_device - (&(stmmacphy_driver.driver), NULL, (void *)priv, - stmmac_associate_phy)) { - pr_err("No PHY device is associated with this MAC!\n"); - ret = -ENODEV; - goto out_unregister; - } + /* Override with kernel parameters if supplied XXX CRS XXX + * this needs to have multiple instances */ + if ((phyaddr >= 0) && (phyaddr <= 31)) + priv->plat->phy_addr = phyaddr; pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, @@ -1890,11 +1815,6 @@ static int __init stmmac_init_module(void) { int ret; - if (platform_driver_register(&stmmacphy_driver)) { - pr_err("No PHY devices registered!\n"); - return -ENODEV; - } - ret = platform_driver_register(&stmmac_driver); return ret; } @@ -1905,7 +1825,6 @@ static int __init stmmac_init_module(void) */ static void __exit stmmac_cleanup_module(void) { - platform_driver_unregister(&stmmacphy_driver); platform_driver_unregister(&stmmac_driver); } diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index 29a6bb6b805..9c3b9d5c341 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -113,9 +113,9 @@ static int stmmac_mdio_reset(struct mii_bus *bus) struct stmmac_priv *priv = netdev_priv(ndev); unsigned int mii_address = priv->hw->mii.addr; - if (priv->phy_reset) { + if (priv->plat->mdio_bus_data->phy_reset) { pr_debug("stmmac_mdio_reset: calling phy_reset\n"); - priv->phy_reset(priv->plat->bsp_priv); + priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv); } /* This is a workaround for problems with the STE101P PHY. @@ -138,30 +138,29 @@ int stmmac_mdio_register(struct net_device *ndev) struct mii_bus *new_bus; int *irqlist; struct stmmac_priv *priv = netdev_priv(ndev); + struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; int addr, found; + if (!mdio_bus_data) + return 0; + new_bus = mdiobus_alloc(); if (new_bus == NULL) return -ENOMEM; - irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (irqlist == NULL) { - err = -ENOMEM; - goto irqlist_alloc_fail; - } - - /* Assign IRQ to phy at address phy_addr */ - if (priv->phy_addr != -1) - irqlist[priv->phy_addr] = priv->phy_irq; + if (mdio_bus_data->irqs) + irqlist = mdio_bus_data->irqs; + else + irqlist = priv->mii_irq; new_bus->name = "STMMAC MII Bus"; new_bus->read = &stmmac_mdio_read; new_bus->write = &stmmac_mdio_write; new_bus->reset = &stmmac_mdio_reset; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id); new_bus->priv = ndev; new_bus->irq = irqlist; - new_bus->phy_mask = priv->phy_mask; + new_bus->phy_mask = mdio_bus_data->phy_mask; new_bus->parent = priv->device; err = mdiobus_register(new_bus); if (err != 0) { @@ -172,18 +171,50 @@ int stmmac_mdio_register(struct net_device *ndev) priv->mii = new_bus; found = 0; - for (addr = 0; addr < 32; addr++) { + for (addr = 0; addr < PHY_MAX_ADDR; addr++) { struct phy_device *phydev = new_bus->phy_map[addr]; if (phydev) { - if (priv->phy_addr == -1) { - priv->phy_addr = addr; - phydev->irq = priv->phy_irq; - irqlist[addr] = priv->phy_irq; + int act = 0; + char irq_num[4]; + char *irq_str; + + /* + * If an IRQ was provided to be assigned after + * the bus probe, do it here. + */ + if ((mdio_bus_data->irqs == NULL) && + (mdio_bus_data->probed_phy_irq > 0)) { + irqlist[addr] = mdio_bus_data->probed_phy_irq; + phydev->irq = mdio_bus_data->probed_phy_irq; } - pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n", - ndev->name, phydev->phy_id, addr, - phydev->irq, dev_name(&phydev->dev), - (addr == priv->phy_addr) ? " active" : ""); + + /* + * If we're going to bind the MAC to this PHY bus, + * and no PHY number was provided to the MAC, + * use the one probed here. + */ + if ((priv->plat->bus_id == mdio_bus_data->bus_id) && + (priv->plat->phy_addr == -1)) + priv->plat->phy_addr = addr; + + act = (priv->plat->bus_id == mdio_bus_data->bus_id) && + (priv->plat->phy_addr == addr); + switch (phydev->irq) { + case PHY_POLL: + irq_str = "POLL"; + break; + case PHY_IGNORE_INTERRUPT: + irq_str = "IGNORE"; + break; + default: + sprintf(irq_num, "%d", phydev->irq); + irq_str = irq_num; + break; + } + pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n", + ndev->name, phydev->phy_id, addr, + irq_str, dev_name(&phydev->dev), + act ? " active" : ""); found = 1; } } @@ -192,10 +223,9 @@ int stmmac_mdio_register(struct net_device *ndev) pr_warning("%s: No PHY found\n", ndev->name); return 0; + bus_register_fail: - kfree(irqlist); -irqlist_alloc_fail: - kfree(new_bus); + mdiobus_free(new_bus); return err; } @@ -210,7 +240,8 @@ int stmmac_mdio_unregister(struct net_device *ndev) mdiobus_unregister(priv->mii); priv->mii->priv = NULL; - kfree(priv->mii); + mdiobus_free(priv->mii); + priv->mii = NULL; return 0; } diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 05d775690b7..0dddc9e42b6 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -28,11 +28,21 @@ #include -/* platform data for platform device structure's platform_data field */ +/* Platfrom data for platform device structure's platform_data field */ + +struct stmmac_mdio_bus_data { + int bus_id; + int (*phy_reset)(void *priv); + unsigned int phy_mask; + int *irqs; + int probed_phy_irq; +}; -/* Private data for the STM on-board ethernet driver */ struct plat_stmmacenet_data { int bus_id; + int phy_addr; + int interface; + struct stmmac_mdio_bus_data *mdio_bus_data; int pbl; int clk_csr; int has_gmac; @@ -48,14 +58,4 @@ struct plat_stmmacenet_data { void *custom_cfg; void *bsp_priv; }; - -struct plat_stmmacphy_data { - int bus_id; - int phy_addr; - unsigned int phy_mask; - int interface; - int (*phy_reset)(void *priv); - void *priv; -}; #endif - -- cgit v1.2.3-70-g09d2 From 308859097831831a979f2e82cbeef0a94f438080 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 20 Jul 2011 05:57:04 +0000 Subject: ASIX: Add AX88772B USB ID This device can be found in Acer Iconia TAB W500 tablet dock. Signed-off-by: Marek Vasut Signed-off-by: David S. Miller --- drivers/net/usb/asix.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6998aa6b7bb..52502883523 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1501,6 +1501,10 @@ static const struct usb_device_id products [] = { // JVC MP-PRX1 Port Replicator USB_DEVICE (0x04f1, 0x3008), .driver_info = (unsigned long) &ax8817x_info, +}, { + // ASIX AX88772B 10/100 + USB_DEVICE (0x0b95, 0x772b), + .driver_info = (unsigned long) &ax88772_info, }, { // ASIX AX88772 10/100 USB_DEVICE (0x0b95, 0x7720), -- cgit v1.2.3-70-g09d2 From e101e7ddad7a16ada030d6d1f044381924bcc0c1 Mon Sep 17 00:00:00 2001 From: Shreyas Bhatewara Date: Wed, 20 Jul 2011 16:01:11 +0000 Subject: vmxnet3: set netdev parant device before calling netdev_info Parent device for netdev should be set before netdev_info() can be called otherwise there is a NULL pointer dereference and probe() fails. Signed-off-by: Shreyas N Bhatewara Signed-off-by: Scott J. Goldman -- Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 009277e1084..1a8cc5bf06b 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2993,6 +2993,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_ver; } + SET_NETDEV_DEV(netdev, &pdev->dev); vmxnet3_declare_features(adapter, dma64); adapter->dev_number = atomic_read(&devices_found); @@ -3038,7 +3039,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); - SET_NETDEV_DEV(netdev, &pdev->dev); err = register_netdev(netdev); if (err) { -- cgit v1.2.3-70-g09d2 From ebbf9295b17ed605f31f45d9269adb216be3a181 Mon Sep 17 00:00:00 2001 From: Shreyas Bhatewara Date: Wed, 20 Jul 2011 17:21:51 +0000 Subject: vmxnet3: fix publicity of NETIF_F_HIGHDMA NETIF_F_HIGHDMA is being disabled even when dma64 is true. This patch fixes it. CC: Michal Miroslaw Signed-off-by: Shreyas N Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 1a8cc5bf06b..1cbacb38965 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2647,7 +2647,7 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64) NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_LRO; if (dma64) - netdev->features |= NETIF_F_HIGHDMA; + netdev->hw_features |= NETIF_F_HIGHDMA; netdev->vlan_features = netdev->hw_features & ~(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_FILTER; -- cgit v1.2.3-70-g09d2 From 61463a30f65225e19e68f59dbd7b888bb308ec99 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 21 Jul 2011 16:22:31 +0000 Subject: can: make function can_get_bittiming static The function can_get_bittiming is not used anywhere else, so it should be static. Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: David S. Miller --- drivers/net/can/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index d0f8c7e67e7..9bf1116e5b5 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -208,7 +208,7 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt) return 0; } -int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) +static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt) { struct can_priv *priv = netdev_priv(dev); int err; -- cgit v1.2.3-70-g09d2 From 2e66f55b3afa290337a47e6ea134ac071c5dd9a7 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Wed, 20 Jul 2011 03:56:02 +0000 Subject: virtio_net: Fix panic in virtnet_remove Fix a panic in virtnet_remove. unregister_netdev has already freed up the netdev (and virtnet_info) due to dev->destructor being set, while virtnet_info is still required. Remove virtnet_free altogether, and move the freeing of the per-cpu statistics from virtnet_free to virtnet_remove. Tested patch below. Signed-off-by: Krishna Kumar Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index fbea637eb74..0c7321c35ad 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -705,14 +705,6 @@ static void virtnet_netpoll(struct net_device *dev) } #endif -static void virtnet_free(struct net_device *dev) -{ - struct virtnet_info *vi = netdev_priv(dev); - - free_percpu(vi->stats); - free_netdev(dev); -} - static int virtnet_open(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); @@ -959,7 +951,6 @@ static int virtnet_probe(struct virtio_device *vdev) /* Set up network device as normal. */ dev->netdev_ops = &virtnet_netdev; dev->features = NETIF_F_HIGHDMA; - dev->destructor = virtnet_free; SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops); SET_NETDEV_DEV(dev, &vdev->dev); @@ -1122,6 +1113,7 @@ static void __devexit virtnet_remove(struct virtio_device *vdev) while (vi->pages) __free_pages(get_a_page(vi, GFP_KERNEL), 0); + free_percpu(vi->stats); free_netdev(vi->dev); } -- cgit v1.2.3-70-g09d2 From 2dc1deb659d1fc29aaafc2c0b987547d6b383602 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 19 Jul 2011 19:52:33 +0000 Subject: be2net: request native mode each time the card is reset Currently be3-native mode is requested only in probe(). It must be requested, each time the card is reset either after an EEH error or after sleep/hibernation. Also, the be_cmd_check_native_mode() is better named be_cmd_req_native_mode() Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 2 +- drivers/net/benet/be_cmds.h | 2 +- drivers/net/benet/be_main.c | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index f520a5c7503..054fa67bc4e 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -2390,7 +2390,7 @@ err: } /* Uses mbox */ -int be_cmd_check_native_mode(struct be_adapter *adapter) +int be_cmd_req_native_mode(struct be_adapter *adapter) { struct be_mcc_wrb *wrb; struct be_cmd_req_set_func_cap *req; diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 1151df6b002..8e4d48824fe 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -1545,7 +1545,7 @@ extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern void be_detect_dump_ue(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter); extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); -extern int be_cmd_check_native_mode(struct be_adapter *adapter); +extern int be_cmd_req_native_mode(struct be_adapter *adapter); extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ae2d2622a18..c411bb1845f 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2511,6 +2511,8 @@ static int be_setup(struct be_adapter *adapter) int status; u8 mac[ETH_ALEN]; + be_cmd_req_native_mode(adapter); + cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST; @@ -2618,6 +2620,8 @@ static int be_clear(struct be_adapter *adapter) be_cmd_if_destroy(adapter, adapter->if_handle, 0); + adapter->be3_native = 0; + /* tell fw we're done with firing cmds */ be_cmd_fw_clean(adapter); return 0; @@ -3215,8 +3219,6 @@ static int be_get_config(struct be_adapter *adapter) if (status) return status; - be_cmd_check_native_mode(adapter); - if ((num_vfs && adapter->sriov_enabled) || (adapter->function_mode & 0x400) || lancer_chip(adapter) || !be_physfn(adapter)) { -- cgit v1.2.3-70-g09d2 From e933d0198d399842f075c2c8af0f38630e7e4bee Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Wed, 20 Jul 2011 00:08:53 +0000 Subject: netxen: add fw version compatibility check o Minimum fw version supported for P3 chip is 4.0.505 o File Fw > 4.0.554 is not supported if flash fw < 4.0.554. o In mn firmware case, file fw older than flash fw is allowed. o Change variable names for readability o Update driver version 4.0.76 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 5 ++- drivers/net/netxen/netxen_nic_init.c | 72 ++++++++++++++++++++++++++++++------ drivers/net/netxen/netxen_nic_main.c | 4 ++ 3 files changed, 68 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 77220687b92..f744d291218 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 75 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.75" +#define _NETXEN_NIC_LINUX_SUBVERSION 76 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.76" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -1302,6 +1302,7 @@ int netxen_nic_wol_supported(struct netxen_adapter *adapter); int netxen_init_dummy_dma(struct netxen_adapter *adapter); void netxen_free_dummy_dma(struct netxen_adapter *adapter); +int netxen_check_flash_fw_compatibility(struct netxen_adapter *adapter); int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); int netxen_load_firmware(struct netxen_adapter *adapter); int netxen_need_fw_reset(struct netxen_adapter *adapter); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index ca59b4f026f..e8993a76a08 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -964,6 +964,35 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) return 0; } +#define NETXEN_MIN_P3_FW_SUPP NETXEN_VERSION_CODE(4, 0, 505) + +int +netxen_check_flash_fw_compatibility(struct netxen_adapter *adapter) +{ + u32 flash_fw_ver, min_fw_ver; + + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) + return 0; + + if (netxen_rom_fast_read(adapter, + NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { + dev_err(&adapter->pdev->dev, "Unable to read flash fw" + "version\n"); + return -EIO; + } + + flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); + min_fw_ver = NETXEN_MIN_P3_FW_SUPP; + if (flash_fw_ver >= min_fw_ver) + return 0; + + dev_info(&adapter->pdev->dev, "Flash fw[%d.%d.%d] is < min fw supported" + "[4.0.505]. Please update firmware on flash\n", + _major(flash_fw_ver), _minor(flash_fw_ver), + _build(flash_fw_ver)); + return -EINVAL; +} + static char *fw_name[] = { NX_P2_MN_ROMIMAGE_NAME, NX_P3_CT_ROMIMAGE_NAME, @@ -1071,10 +1100,12 @@ static int netxen_validate_firmware(struct netxen_adapter *adapter) { __le32 val; - u32 ver, min_ver, bios; + __le32 flash_fw_ver; + u32 file_fw_ver, min_ver, bios; struct pci_dev *pdev = adapter->pdev; const struct firmware *fw = adapter->fw; u8 fw_type = adapter->fw_type; + u32 crbinit_fix_fw; if (fw_type == NX_UNIFIED_ROMIMAGE) { if (netxen_nic_validate_unified_romimage(adapter)) @@ -1091,16 +1122,18 @@ netxen_validate_firmware(struct netxen_adapter *adapter) val = nx_get_fw_version(adapter); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - min_ver = NETXEN_VERSION_CODE(4, 0, 216); + min_ver = NETXEN_MIN_P3_FW_SUPP; else min_ver = NETXEN_VERSION_CODE(3, 4, 216); - ver = NETXEN_DECODE_VERSION(val); + file_fw_ver = NETXEN_DECODE_VERSION(val); - if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { + if ((_major(file_fw_ver) > _NETXEN_NIC_LINUX_MAJOR) || + (file_fw_ver < min_ver)) { dev_err(&pdev->dev, "%s: firmware version %d.%d.%d unsupported\n", - fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); + fw_name[fw_type], _major(file_fw_ver), _minor(file_fw_ver), + _build(file_fw_ver)); return -EINVAL; } @@ -1112,17 +1145,34 @@ netxen_validate_firmware(struct netxen_adapter *adapter) return -EINVAL; } - /* check if flashed firmware is newer */ if (netxen_rom_fast_read(adapter, - NX_FW_VERSION_OFFSET, (int *)&val)) + NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { + dev_err(&pdev->dev, "Unable to read flash fw version\n"); return -EIO; - val = NETXEN_DECODE_VERSION(val); - if (val > ver) { - dev_info(&pdev->dev, "%s: firmware is older than flash\n", - fw_name[fw_type]); + } + flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); + + /* New fw from file is not allowed, if fw on flash is < 4.0.554 */ + crbinit_fix_fw = NETXEN_VERSION_CODE(4, 0, 554); + if (file_fw_ver >= crbinit_fix_fw && flash_fw_ver < crbinit_fix_fw && + NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + dev_err(&pdev->dev, "Incompatibility detected between driver " + "and firmware version on flash. This configuration " + "is not recommended. Please update the firmware on " + "flash immediately\n"); return -EINVAL; } + /* check if flashed firmware is newer only for no-mn and P2 case*/ + if (!netxen_p3_has_mn(adapter) || + NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + if (flash_fw_ver > file_fw_ver) { + dev_info(&pdev->dev, "%s: firmware is older than flash\n", + fw_name[fw_type]); + return -EINVAL; + } + } + NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); return 0; } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 30f41e62049..f574edff7fc 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1388,6 +1388,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } + err = netxen_check_flash_fw_compatibility(adapter); + if (err) + goto err_out_iounmap; + if (adapter->portnum == 0) { val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); if (val != 0xffffffff && val != 0) { -- cgit v1.2.3-70-g09d2 From 6d9e5130b96daa1656966f7271e8a0928b3906c4 Mon Sep 17 00:00:00 2001 From: Nicolas Schichan Date: Sat, 9 Jul 2011 00:24:18 +0000 Subject: e1000: always call e1000_check_for_link() on e1000_ce4100 MACs. Interrupts about link lost or rx sequence errors are not reported by the ce4100 hardware, leading to transitions from link UP to link DOWN never being reported. Signed-off-by: Nicolas Schichan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000/e1000_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index acaebecf0ca..f97afda941d 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2402,13 +2402,16 @@ bool e1000_has_link(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; bool link_active = false; - /* get_link_status is set on LSC (link status) interrupt or - * rx sequence error interrupt. get_link_status will stay - * false until the e1000_check_for_link establishes link - * for copper adapters ONLY + /* get_link_status is set on LSC (link status) interrupt or rx + * sequence error interrupt (except on intel ce4100). + * get_link_status will stay false until the + * e1000_check_for_link establishes link for copper adapters + * ONLY */ switch (hw->media_type) { case e1000_media_type_copper: + if (hw->mac_type == e1000_ce4100) + hw->get_link_status = 1; if (hw->get_link_status) { e1000_check_for_link(hw); link_active = !hw->get_link_status; -- cgit v1.2.3-70-g09d2 From a14bc2bb7075e59be635a2470dc0a32c5a0e8e21 Mon Sep 17 00:00:00 2001 From: Robert Healy Date: Tue, 12 Jul 2011 08:46:20 +0000 Subject: igb: Fix for DH89xxCC near end loopback test On this chipset it is required to configure the MPHY block for loopback tests. If MPHY is not configured then all loopback tests will report failures. Signed-off-by: Robert Healy Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_defines.h | 10 ++++++++++ drivers/net/igb/igb_ethtool.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 2cd4082c86c..7b8ddd830f1 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -512,6 +512,16 @@ #define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 #define E1000_GCR_CAP_VER2 0x00040000 +/* mPHY Address Control and Data Registers */ +#define E1000_MPHY_ADDR_CTL 0x0024 /* mPHY Address Control Register */ +#define E1000_MPHY_ADDR_CTL_OFFSET_MASK 0xFFFF0000 +#define E1000_MPHY_DATA 0x0E10 /* mPHY Data Register */ + +/* mPHY PCS CLK Register */ +#define E1000_MPHY_PCS_CLK_REG_OFFSET 0x0004 /* mPHY PCS CLK AFE CSR Offset */ +/* mPHY Near End Digital Loopback Override Bit */ +#define E1000_MPHY_PCS_CLK_REG_DIGINELBEN 0x10 + /* PHY Control Register */ #define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ #define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index ed63ff4cf6d..ff244ce803c 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1461,6 +1461,22 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) /* use CTRL_EXT to identify link type as SGMII can appear as copper */ if (reg & E1000_CTRL_EXT_LINK_MODE_MASK) { + if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) { + + /* Enable DH89xxCC MPHY for near end loopback */ + reg = rd32(E1000_MPHY_ADDR_CTL); + reg = (reg & E1000_MPHY_ADDR_CTL_OFFSET_MASK) | + E1000_MPHY_PCS_CLK_REG_OFFSET; + wr32(E1000_MPHY_ADDR_CTL, reg); + + reg = rd32(E1000_MPHY_DATA); + reg |= E1000_MPHY_PCS_CLK_REG_DIGINELBEN; + wr32(E1000_MPHY_DATA, reg); + } + reg = rd32(E1000_RCTL); reg |= E1000_RCTL_LBM_TCVR; wr32(E1000_RCTL, reg); @@ -1502,6 +1518,23 @@ static void igb_loopback_cleanup(struct igb_adapter *adapter) u32 rctl; u16 phy_reg; + if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) || + (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) { + u32 reg; + + /* Disable near end loopback on DH89xxCC */ + reg = rd32(E1000_MPHY_ADDR_CTL); + reg = (reg & E1000_MPHY_ADDR_CTL_OFFSET_MASK) | + E1000_MPHY_PCS_CLK_REG_OFFSET; + wr32(E1000_MPHY_ADDR_CTL, reg); + + reg = rd32(E1000_MPHY_DATA); + reg &= ~E1000_MPHY_PCS_CLK_REG_DIGINELBEN; + wr32(E1000_MPHY_DATA, reg); + } + rctl = rd32(E1000_RCTL); rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); wr32(E1000_RCTL, rctl); -- cgit v1.2.3-70-g09d2 From 6440752c872e418452a2cbbf5e73d546affe2b28 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 11 Jun 2011 01:44:53 +0000 Subject: ixgbe: Update ATR to use recorded TX queues instead of CPU for routing This change is meant to update ATR so that it will use the recorded RX queue instead of the CPU in the case of routing. This change is meant to help ixgbe default behavior to more closely match that of the kernel. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index de307965dfe..f05ddf31a19 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6795,11 +6795,10 @@ static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) { struct ixgbe_adapter *adapter = netdev_priv(dev); - int txq = smp_processor_id(); + int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : + smp_processor_id(); #ifdef IXGBE_FCOE - __be16 protocol; - - protocol = vlan_get_protocol(skb); + __be16 protocol = vlan_get_protocol(skb); if (((protocol == htons(ETH_P_FCOE)) || (protocol == htons(ETH_P_FIP))) && -- cgit v1.2.3-70-g09d2 From 82d4e46e2a398154273044dd9813206f0d85bc09 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 11 Jun 2011 01:44:58 +0000 Subject: ixgbe: inline the ixgbe_maybe_stop_tx function The ixgbe_maybe_stop_tx function is only a few lines long and is called multiple times through the xmit hotpath. In order to streamline things it makes sense to just inline it. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f05ddf31a19..7275c5cc09b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6785,7 +6785,7 @@ static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) return 0; } -static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) +static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) { if (likely(ixgbe_desc_unused(tx_ring) >= size)) return 0; -- cgit v1.2.3-70-g09d2 From 08c8833b29cfa4343ff132eebc5648b234eb3f85 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 11 Jun 2011 01:45:03 +0000 Subject: ixgbe: add structure for containing RX/TX rings to q_vector This patch adds support for a ring container structure to be used within the q_vector. The basic idea is to provide a means of separating the RX and TX rings while maintaining a common structure for their containment. The advantage to this is that later we should be able to pass this structure to the update_itr functions without needing to pass individual rings. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 16 ++-- drivers/net/ixgbe/ixgbe_ethtool.c | 6 +- drivers/net/ixgbe/ixgbe_main.c | 150 +++++++++++++++++++------------------- 3 files changed, 88 insertions(+), 84 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 744b6410813..a5ed9fd69fd 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -277,6 +277,15 @@ struct ixgbe_ring_feature { int mask; } ____cacheline_internodealigned_in_smp; +struct ixgbe_ring_container { +#if MAX_RX_QUEUES > MAX_TX_QUEUES + DECLARE_BITMAP(idx, MAX_RX_QUEUES); +#else + DECLARE_BITMAP(idx, MAX_TX_QUEUES); +#endif + u8 count; /* total number of rings in vector */ + u8 itr; /* current ITR setting for ring */ +}; #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \ ? 8 : 1) @@ -294,12 +303,7 @@ struct ixgbe_q_vector { int cpu; /* CPU for DCA */ #endif struct napi_struct napi; - DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */ - DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ - u8 rxr_count; /* Rx ring count assigned to this vector */ - u8 txr_count; /* Tx ring count assigned to this vector */ - u8 tx_itr; - u8 rx_itr; + struct ixgbe_ring_container rx, tx; u32 eitr; cpumask_var_t affinity_mask; char name[IFNAMSIZ + 9]; diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 074e9baf069..cd842f9dcae 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2122,7 +2122,7 @@ static int ixgbe_get_coalesce(struct net_device *netdev, } /* if in mixed tx/rx queues per vector mode, report only rx settings */ - if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count) + if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count) return 0; /* only valid if in constant ITR mode */ @@ -2187,7 +2187,7 @@ static int ixgbe_set_coalesce(struct net_device *netdev, bool need_reset = false; /* don't accept tx specific changes if we've got mixed RxTx vectors */ - if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count + if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count && ec->tx_coalesce_usecs) return -EINVAL; @@ -2261,7 +2261,7 @@ static int ixgbe_set_coalesce(struct net_device *netdev, int num_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; for (i = 0; i < num_vectors; i++) { q_vector = adapter->q_vector[i]; - if (q_vector->txr_count && !q_vector->rxr_count) + if (q_vector->tx.count && !q_vector->rx.count) /* tx only */ q_vector->eitr = adapter->tx_eitr_param; else diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 7275c5cc09b..bd1fd8f422d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -959,17 +959,17 @@ static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector) if (q_vector->cpu == cpu) goto out_no_update; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { ixgbe_update_tx_dca(adapter, adapter->tx_ring[r_idx], cpu); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { ixgbe_update_rx_dca(adapter, adapter->rx_ring[r_idx], cpu); - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } @@ -1517,31 +1517,31 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) for (v_idx = 0; v_idx < q_vectors; v_idx++) { q_vector = adapter->q_vector[v_idx]; /* XXX for_each_set_bit(...) */ - r_idx = find_first_bit(q_vector->rxr_idx, + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + for (i = 0; i < q_vector->rx.count; i++) { u8 reg_idx = adapter->rx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 0, reg_idx, v_idx); - r_idx = find_next_bit(q_vector->rxr_idx, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->txr_idx, + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + for (i = 0; i < q_vector->tx.count; i++) { u8 reg_idx = adapter->tx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 1, reg_idx, v_idx); - r_idx = find_next_bit(q_vector->txr_idx, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } - if (q_vector->txr_count && !q_vector->rxr_count) + if (q_vector->tx.count && !q_vector->rx.count) /* tx only */ q_vector->eitr = adapter->tx_eitr_param; - else if (q_vector->rxr_count) + else if (q_vector->rx.count) /* rx or mixed */ q_vector->eitr = adapter->rx_eitr_param; @@ -1705,37 +1705,37 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) u32 new_itr; u8 current_itr, ret_itr; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { struct ixgbe_ring *tx_ring = adapter->tx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->tx_itr, + q_vector->tx.itr, tx_ring->total_packets, tx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ - q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ? - q_vector->tx_itr - 1 : ret_itr); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + q_vector->tx.itr = ((q_vector->tx.itr > ret_itr) ? + q_vector->tx.itr - 1 : ret_itr); + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { struct ixgbe_ring *rx_ring = adapter->rx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->rx_itr, + q_vector->rx.itr, rx_ring->total_packets, rx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ - q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ? - q_vector->rx_itr - 1 : ret_itr); - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + q_vector->rx.itr = ((q_vector->rx.itr > ret_itr) ? + q_vector->rx.itr - 1 : ret_itr); + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } - current_itr = max(q_vector->rx_itr, q_vector->tx_itr); + current_itr = max(q_vector->rx.itr, q_vector->tx.itr); switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ @@ -1995,15 +1995,15 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) struct ixgbe_ring *tx_ring; int i, r_idx; - if (!q_vector->txr_count) + if (!q_vector->tx.count) return IRQ_HANDLED; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { tx_ring = adapter->tx_ring[r_idx]; tx_ring->total_bytes = 0; tx_ring->total_packets = 0; - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } @@ -2031,16 +2031,16 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { rx_ring = adapter->rx_ring[r_idx]; rx_ring->total_bytes = 0; rx_ring->total_packets = 0; - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } - if (!q_vector->rxr_count) + if (!q_vector->rx.count) return IRQ_HANDLED; /* EIAM disabled interrupts (on this vector) for us */ @@ -2057,24 +2057,24 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) int r_idx; int i; - if (!q_vector->txr_count && !q_vector->rxr_count) + if (!q_vector->tx.count && !q_vector->rx.count) return IRQ_HANDLED; - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { ring = adapter->tx_ring[r_idx]; ring->total_bytes = 0; ring->total_packets = 0; - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { ring = adapter->rx_ring[r_idx]; ring->total_bytes = 0; ring->total_packets = 0; - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } @@ -2106,7 +2106,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); rx_ring = adapter->rx_ring[r_idx]; ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget); @@ -2147,27 +2147,27 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->tx.count; i++) { ring = adapter->tx_ring[r_idx]; tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } /* attempt to distribute budget to each queue fairly, but don't allow * the budget to go below 1 because we'll exit polling */ - budget /= (q_vector->rxr_count ?: 1); + budget /= (q_vector->rx.count ?: 1); budget = max(budget, 1); - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rx.count; i++) { ring = adapter->rx_ring[r_idx]; ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget); - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); ring = adapter->rx_ring[r_idx]; /* If all Rx work done, exit the polling mode */ if (work_done < budget) { @@ -2205,7 +2205,7 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) ixgbe_update_dca(q_vector); #endif - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); + r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); tx_ring = adapter->tx_ring[r_idx]; if (!ixgbe_clean_tx_irq(q_vector, tx_ring)) @@ -2230,8 +2230,8 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; struct ixgbe_ring *rx_ring = a->rx_ring[r_idx]; - set_bit(r_idx, q_vector->rxr_idx); - q_vector->rxr_count++; + set_bit(r_idx, q_vector->rx.idx); + q_vector->rx.count++; rx_ring->q_vector = q_vector; } @@ -2241,8 +2241,8 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; struct ixgbe_ring *tx_ring = a->tx_ring[t_idx]; - set_bit(t_idx, q_vector->txr_idx); - q_vector->txr_count++; + set_bit(t_idx, q_vector->tx.idx); + q_vector->tx.count++; tx_ring->q_vector = q_vector; } @@ -2332,10 +2332,10 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) if (err) return err; -#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count) \ +#define SET_HANDLER(_v) (((_v)->rx.count && (_v)->tx.count) \ ? &ixgbe_msix_clean_many : \ - (_v)->rxr_count ? &ixgbe_msix_clean_rx : \ - (_v)->txr_count ? &ixgbe_msix_clean_tx : \ + (_v)->rx.count ? &ixgbe_msix_clean_rx : \ + (_v)->tx.count ? &ixgbe_msix_clean_tx : \ NULL) for (vector = 0; vector < q_vectors; vector++) { struct ixgbe_q_vector *q_vector = adapter->q_vector[vector]; @@ -2394,16 +2394,16 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) u32 new_itr = q_vector->eitr; u8 current_itr; - q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->tx_itr, + q_vector->tx.itr = ixgbe_update_itr(adapter, new_itr, + q_vector->tx.itr, tx_ring->total_packets, tx_ring->total_bytes); - q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->rx_itr, + q_vector->rx.itr = ixgbe_update_itr(adapter, new_itr, + q_vector->rx.itr, rx_ring->total_packets, rx_ring->total_bytes); - current_itr = max(q_vector->rx_itr, q_vector->tx_itr); + current_itr = max(q_vector->rx.itr, q_vector->tx.itr); switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ @@ -2553,10 +2553,10 @@ static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter) for (i = 0; i < q_vectors; i++) { struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; - bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES); - bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES); - q_vector->rxr_count = 0; - q_vector->txr_count = 0; + bitmap_zero(q_vector->rx.idx, MAX_RX_QUEUES); + bitmap_zero(q_vector->tx.idx, MAX_TX_QUEUES); + q_vector->rx.count = 0; + q_vector->tx.count = 0; } } @@ -2601,8 +2601,8 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) i--; for (; i >= 0; i--) { /* free only the irqs that were actually requested */ - if (!adapter->q_vector[i]->rxr_count && - !adapter->q_vector[i]->txr_count) + if (!adapter->q_vector[i]->rx.count && + !adapter->q_vector[i]->tx.count) continue; free_irq(adapter->msix_entries[i].vector, @@ -3616,10 +3616,10 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) q_vector = adapter->q_vector[q_idx]; napi = &q_vector->napi; if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - if (!q_vector->rxr_count || !q_vector->txr_count) { - if (q_vector->txr_count == 1) + if (!q_vector->rx.count || !q_vector->tx.count) { + if (q_vector->tx.count == 1) napi->poll = &ixgbe_clean_txonly; - else if (q_vector->rxr_count == 1) + else if (q_vector->rx.count == 1) napi->poll = &ixgbe_clean_rxonly; } } @@ -4965,7 +4965,7 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) if (!q_vector) goto err_out; q_vector->adapter = adapter; - if (q_vector->txr_count && !q_vector->rxr_count) + if (q_vector->tx.count && !q_vector->rx.count) q_vector->eitr = adapter->tx_eitr_param; else q_vector->eitr = adapter->rx_eitr_param; @@ -5979,7 +5979,7 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter) /* get one bit for every active tx/rx interrupt vector */ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { struct ixgbe_q_vector *qv = adapter->q_vector[i]; - if (qv->rxr_count || qv->txr_count) + if (qv->rx.count || qv->tx.count) eics |= ((u64)1 << i); } } -- cgit v1.2.3-70-g09d2 From bd19805803a954415ec36a559fd3b8a0a3647d7c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 11 Jun 2011 01:45:08 +0000 Subject: ixgbe: Move interrupt related values out of ring and into q_vector This change moves work_limit, total_packets, and total_bytes into the ring container struct of the q_vector. The advantage of this is that it should reduce the size of memory used in the event of multiple rings being assigned to a single q_vector. In addition it should help to reduce the total workload for calculating itr since now total_packets and total_bytes will be the total work done of the interrupt instead of for the ring. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 24 +++--- drivers/net/ixgbe/ixgbe_ethtool.c | 6 +- drivers/net/ixgbe/ixgbe_main.c | 170 ++++++++++---------------------------- 3 files changed, 62 insertions(+), 138 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index a5ed9fd69fd..fbae7352b03 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -214,12 +214,10 @@ struct ixgbe_ring { struct ixgbe_rx_buffer *rx_buffer_info; }; unsigned long state; - u8 atr_sample_rate; - u8 atr_count; + u8 __iomem *tail; + u16 count; /* amount of descriptors */ u16 rx_buf_len; - u16 next_to_use; - u16 next_to_clean; u8 queue_index; /* needed for multiqueue queue management */ u8 reg_idx; /* holds the special value that gets @@ -227,15 +225,13 @@ struct ixgbe_ring { * associated with this ring, which is * different for DCB and RSS modes */ - u8 dcb_tc; - - u16 work_limit; /* max work per interrupt */ - - u8 __iomem *tail; + u8 atr_sample_rate; + u8 atr_count; - unsigned int total_bytes; - unsigned int total_packets; + u16 next_to_use; + u16 next_to_clean; + u8 dcb_tc; struct ixgbe_queue_stats stats; struct u64_stats_sync syncp; union { @@ -283,6 +279,9 @@ struct ixgbe_ring_container { #else DECLARE_BITMAP(idx, MAX_TX_QUEUES); #endif + unsigned int total_bytes; /* total bytes processed this int */ + unsigned int total_packets; /* total packets processed this int */ + u16 work_limit; /* total work allowed per interrupt */ u8 count; /* total number of rings in vector */ u8 itr; /* current ITR setting for ring */ }; @@ -417,6 +416,9 @@ struct ixgbe_adapter { u16 eitr_low; u16 eitr_high; + /* Work limits */ + u16 tx_work_limit; + /* TX */ struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp; int num_tx_queues; diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index cd842f9dcae..6035cfa1b4c 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2103,7 +2103,7 @@ static int ixgbe_get_coalesce(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); - ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0]->work_limit; + ec->tx_max_coalesced_frames_irq = adapter->tx_work_limit; /* only valid if in constant ITR mode */ switch (adapter->rx_itr_setting) { @@ -2192,7 +2192,7 @@ static int ixgbe_set_coalesce(struct net_device *netdev, return -EINVAL; if (ec->tx_max_coalesced_frames_irq) - adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq; + adapter->tx_work_limit = ec->tx_max_coalesced_frames_irq; if (ec->rx_coalesce_usecs > 1) { /* check the limits */ @@ -2267,12 +2267,14 @@ static int ixgbe_set_coalesce(struct net_device *netdev, else /* rx only or mixed */ q_vector->eitr = adapter->rx_eitr_param; + q_vector->tx.work_limit = adapter->tx_work_limit; ixgbe_write_eitr(q_vector); } /* Legacy Interrupt Mode */ } else { q_vector = adapter->q_vector[0]; q_vector->eitr = adapter->rx_eitr_param; + q_vector->tx.work_limit = adapter->tx_work_limit; ixgbe_write_eitr(q_vector); } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index bd1fd8f422d..298c95b1480 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -805,7 +805,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && - (count < tx_ring->work_limit)) { + (count < q_vector->tx.work_limit)) { bool cleaned = false; rmb(); /* read buffer_info after eop_desc */ for ( ; !cleaned; count++) { @@ -834,11 +834,11 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } tx_ring->next_to_clean = i; - tx_ring->total_bytes += total_bytes; - tx_ring->total_packets += total_packets; - u64_stats_update_begin(&tx_ring->syncp); - tx_ring->stats.packets += total_packets; tx_ring->stats.bytes += total_bytes; + tx_ring->stats.packets += total_packets; + u64_stats_update_begin(&tx_ring->syncp); + q_vector->tx.total_bytes += total_bytes; + q_vector->tx.total_packets += total_packets; u64_stats_update_end(&tx_ring->syncp); if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) { @@ -886,7 +886,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } } - return count < tx_ring->work_limit; + return count < q_vector->tx.work_limit; } #ifdef CONFIG_IXGBE_DCA @@ -1486,12 +1486,12 @@ next_desc: } #endif /* IXGBE_FCOE */ - rx_ring->total_packets += total_rx_packets; - rx_ring->total_bytes += total_rx_bytes; u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets += total_rx_packets; rx_ring->stats.bytes += total_rx_bytes; u64_stats_update_end(&rx_ring->syncp); + q_vector->rx.total_packets += total_rx_packets; + q_vector->rx.total_bytes += total_rx_bytes; } static int ixgbe_clean_rxonly(struct napi_struct *, int); @@ -1597,11 +1597,8 @@ enum latency_range { /** * ixgbe_update_itr - update the dynamic ITR value based on statistics - * @adapter: pointer to adapter - * @eitr: eitr setting (ints per sec) to give last timeslice - * @itr_setting: current throttle rate in ints/second - * @packets: the number of packets during this measurement interval - * @bytes: the number of bytes during this measurement interval + * @q_vector: structure containing interrupt and ring information + * @ring_container: structure containing ring performance data * * Stores a new ITR value based on packets and byte * counts during the last interrupt. The advantage of per interrupt @@ -1613,17 +1610,18 @@ enum latency_range { * this functionality is controlled by the InterruptThrottleRate module * parameter (see ixgbe_param.c) **/ -static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, - u32 eitr, u8 itr_setting, - int packets, int bytes) +static void ixgbe_update_itr(struct ixgbe_q_vector *q_vector, + struct ixgbe_ring_container *ring_container) { - unsigned int retval = itr_setting; - u32 timepassed_us; u64 bytes_perint; + struct ixgbe_adapter *adapter = q_vector->adapter; + int bytes = ring_container->total_bytes; + int packets = ring_container->total_packets; + u32 timepassed_us; + u8 itr_setting = ring_container->itr; if (packets == 0) - goto update_itr_done; - + return; /* simple throttlerate management * 0-20MB/s lowest (100000 ints/s) @@ -1631,28 +1629,32 @@ static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, * 100-1249MB/s bulk (8000 ints/s) */ /* what was last interrupt timeslice? */ - timepassed_us = 1000000/eitr; + timepassed_us = 1000000/q_vector->eitr; bytes_perint = bytes / timepassed_us; /* bytes/usec */ switch (itr_setting) { case lowest_latency: if (bytes_perint > adapter->eitr_low) - retval = low_latency; + itr_setting = low_latency; break; case low_latency: if (bytes_perint > adapter->eitr_high) - retval = bulk_latency; + itr_setting = bulk_latency; else if (bytes_perint <= adapter->eitr_low) - retval = lowest_latency; + itr_setting = lowest_latency; break; case bulk_latency: if (bytes_perint <= adapter->eitr_high) - retval = low_latency; + itr_setting = low_latency; break; } -update_itr_done: - return retval; + /* clear work counters since we have the values we need */ + ring_container->total_bytes = 0; + ring_container->total_packets = 0; + + /* write updated itr to ring container */ + ring_container->itr = itr_setting; } /** @@ -1698,42 +1700,13 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg); } -static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) +static void ixgbe_set_itr(struct ixgbe_q_vector *q_vector) { - struct ixgbe_adapter *adapter = q_vector->adapter; - int i, r_idx; - u32 new_itr; - u8 current_itr, ret_itr; - - r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->tx.count; i++) { - struct ixgbe_ring *tx_ring = adapter->tx_ring[r_idx]; - ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->tx.itr, - tx_ring->total_packets, - tx_ring->total_bytes); - /* if the result for this queue would decrease interrupt - * rate for this vector then use that result */ - q_vector->tx.itr = ((q_vector->tx.itr > ret_itr) ? - q_vector->tx.itr - 1 : ret_itr); - r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, - r_idx + 1); - } + u32 new_itr = q_vector->eitr; + u8 current_itr; - r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rx.count; i++) { - struct ixgbe_ring *rx_ring = adapter->rx_ring[r_idx]; - ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->rx.itr, - rx_ring->total_packets, - rx_ring->total_bytes); - /* if the result for this queue would decrease interrupt - * rate for this vector then use that result */ - q_vector->rx.itr = ((q_vector->rx.itr > ret_itr) ? - q_vector->rx.itr - 1 : ret_itr); - r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, - r_idx + 1); - } + ixgbe_update_itr(q_vector, &q_vector->tx); + ixgbe_update_itr(q_vector, &q_vector->rx); current_itr = max(q_vector->rx.itr, q_vector->tx.itr); @@ -1746,16 +1719,17 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) new_itr = 20000; /* aka hwitr = ~200 */ break; case bulk_latency: - default: new_itr = 8000; break; + default: + break; } if (new_itr != q_vector->eitr) { /* do an exponential smoothing */ new_itr = ((q_vector->eitr * 9) + new_itr)/10; - /* save the algorithm value here, not the smoothed one */ + /* save the algorithm value here */ q_vector->eitr = new_itr; ixgbe_write_eitr(q_vector); @@ -2001,8 +1975,6 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); for (i = 0; i < q_vector->tx.count; i++) { tx_ring = adapter->tx_ring[r_idx]; - tx_ring->total_bytes = 0; - tx_ring->total_packets = 0; r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } @@ -2034,8 +2006,6 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rx.count; i++) { rx_ring = adapter->rx_ring[r_idx]; - rx_ring->total_bytes = 0; - rx_ring->total_packets = 0; r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } @@ -2063,8 +2033,6 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) r_idx = find_first_bit(q_vector->tx.idx, adapter->num_tx_queues); for (i = 0; i < q_vector->tx.count; i++) { ring = adapter->tx_ring[r_idx]; - ring->total_bytes = 0; - ring->total_packets = 0; r_idx = find_next_bit(q_vector->tx.idx, adapter->num_tx_queues, r_idx + 1); } @@ -2072,8 +2040,6 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) r_idx = find_first_bit(q_vector->rx.idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rx.count; i++) { ring = adapter->rx_ring[r_idx]; - ring->total_bytes = 0; - ring->total_packets = 0; r_idx = find_next_bit(q_vector->rx.idx, adapter->num_rx_queues, r_idx + 1); } @@ -2115,7 +2081,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); if (adapter->rx_itr_setting & 1) - ixgbe_set_itr_msix(q_vector); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); @@ -2173,7 +2139,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); if (adapter->rx_itr_setting & 1) - ixgbe_set_itr_msix(q_vector); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); @@ -2215,7 +2181,7 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); if (adapter->tx_itr_setting & 1) - ixgbe_set_itr_msix(q_vector); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); @@ -2244,6 +2210,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, set_bit(t_idx, q_vector->tx.idx); q_vector->tx.count++; tx_ring->q_vector = q_vector; + q_vector->tx.work_limit = a->tx_work_limit; } /** @@ -2386,51 +2353,6 @@ free_queue_irqs: return err; } -static void ixgbe_set_itr(struct ixgbe_adapter *adapter) -{ - struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; - struct ixgbe_ring *rx_ring = adapter->rx_ring[0]; - struct ixgbe_ring *tx_ring = adapter->tx_ring[0]; - u32 new_itr = q_vector->eitr; - u8 current_itr; - - q_vector->tx.itr = ixgbe_update_itr(adapter, new_itr, - q_vector->tx.itr, - tx_ring->total_packets, - tx_ring->total_bytes); - q_vector->rx.itr = ixgbe_update_itr(adapter, new_itr, - q_vector->rx.itr, - rx_ring->total_packets, - rx_ring->total_bytes); - - current_itr = max(q_vector->rx.itr, q_vector->tx.itr); - - switch (current_itr) { - /* counts and packets in update_itr are dependent on these numbers */ - case lowest_latency: - new_itr = 100000; - break; - case low_latency: - new_itr = 20000; /* aka hwitr = ~200 */ - break; - case bulk_latency: - new_itr = 8000; - break; - default: - break; - } - - if (new_itr != q_vector->eitr) { - /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 9) + new_itr)/10; - - /* save the algorithm value here */ - q_vector->eitr = new_itr; - - ixgbe_write_eitr(q_vector); - } -} - /** * ixgbe_irq_enable - Enable default interrupt generation settings * @adapter: board private structure @@ -2528,10 +2450,6 @@ static irqreturn_t ixgbe_intr(int irq, void *data) ixgbe_check_fan_failure(adapter, eicr); if (napi_schedule_prep(&(q_vector->napi))) { - adapter->tx_ring[0]->total_packets = 0; - adapter->tx_ring[0]->total_bytes = 0; - adapter->rx_ring[0]->total_packets = 0; - adapter->rx_ring[0]->total_bytes = 0; /* would disable interrupts here but EIAM disabled it */ __napi_schedule(&(q_vector->napi)); } @@ -4299,7 +4217,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); if (adapter->rx_itr_setting & 1) - ixgbe_set_itr(adapter); + ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE); } @@ -5224,6 +5142,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->tx_ring_count = IXGBE_DEFAULT_TXD; adapter->rx_ring_count = IXGBE_DEFAULT_RXD; + /* set default work limits */ + adapter->tx_work_limit = adapter->tx_ring_count; + /* initialize eeprom parameters */ if (ixgbe_init_eeprom_params_generic(hw)) { e_dev_err("EEPROM initialization failed\n"); @@ -5270,7 +5191,6 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring) tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; - tx_ring->work_limit = tx_ring->count; return 0; err: -- cgit v1.2.3-70-g09d2 From ff886dfce2bdacbe71583ec973cec117973d8859 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 11 Jun 2011 01:45:13 +0000 Subject: ixgbe: Pass staterr instead of re-reading status and error bits from descriptor This change is meant to address possible race conditions from the status and error bits on the RX descriptors being re-read by multiple functions in the RX cleanup path. To resolve this I have added code that will pass the staterr value to those functions. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 5 +++-- drivers/net/ixgbe/ixgbe_fcoe.c | 35 ++++++----------------------------- drivers/net/ixgbe/ixgbe_main.c | 39 ++++++++++++++++++++++++++++----------- 3 files changed, 37 insertions(+), 42 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index fbae7352b03..0d610c73164 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -600,8 +600,9 @@ extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, u32 tx_flags, u8 *hdr_len); extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, - union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb); + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb, + u32 staterr); extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, struct scatterlist *sgl, unsigned int sgc); extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index f0c1018bbf3..824edae7786 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -36,25 +36,6 @@ #include #include -/** - * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type - * @rx_desc: advanced rx descriptor - * - * Returns : true if it is FCoE pkt - */ -static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc) -{ - u16 p; - - p = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info); - if (p & IXGBE_RXDADV_PKTTYPE_ETQF) { - p &= IXGBE_RXDADV_PKTTYPE_ETQF_MASK; - p >>= IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT; - return p == IXGBE_ETQF_FILTER_FCOE; - } - return false; -} - /** * ixgbe_fcoe_clear_ddp - clear the given ddp context * @ddp - ptr to the ixgbe_fcoe_ddp @@ -136,7 +117,6 @@ out_ddp_put: return len; } - /** * ixgbe_fcoe_ddp_setup - called to set up ddp context * @netdev: the corresponding net_device @@ -380,23 +360,20 @@ int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, */ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb) + struct sk_buff *skb, + u32 staterr) { u16 xid; u32 fctl; - u32 sterr, fceofe, fcerr, fcstat; + u32 fceofe, fcerr, fcstat; int rc = -EINVAL; struct ixgbe_fcoe *fcoe; struct ixgbe_fcoe_ddp *ddp; struct fc_frame_header *fh; struct fcoe_crc_eof *crc; - if (!ixgbe_rx_is_fcoe(rx_desc)) - goto ddp_out; - - sterr = le32_to_cpu(rx_desc->wb.upper.status_error); - fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR); - fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE); + fcerr = (staterr & IXGBE_RXDADV_ERR_FCERR); + fceofe = (staterr & IXGBE_RXDADV_ERR_FCEOFE); if (fcerr == IXGBE_FCERR_BADCRC) skb_checksum_none_assert(skb); else @@ -425,7 +402,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, if (fcerr | fceofe) goto ddp_out; - fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT); + fcstat = (staterr & IXGBE_RXDADV_STAT_FCSTAT); if (fcstat) { /* update length of DDPed data */ ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 298c95b1480..a222af378a3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1038,6 +1038,24 @@ static inline void ixgbe_rx_hash(union ixgbe_adv_rx_desc *rx_desc, skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); } +/** + * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type + * @adapter: address of board private structure + * @rx_desc: advanced rx descriptor + * + * Returns : true if it is FCoE pkt + */ +static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, + union ixgbe_adv_rx_desc *rx_desc) +{ + __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + + return (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_ETQF_MASK)) == + (cpu_to_le16(IXGBE_ETQF_FILTER_FCOE << + IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); +} + /** * ixgbe_receive_skb - Send a completed packet up the stack * @adapter: board private structure @@ -1070,14 +1088,14 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, * @adapter: address of board private structure * @status_err: hardware indication of status of receive * @skb: skb currently being received and modified + * @status_err: status error value of last descriptor in packet **/ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb) + struct sk_buff *skb, + u32 status_err) { - u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); - - skb_checksum_none_assert(skb); + skb->ip_summed = CHECKSUM_NONE; /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) @@ -1421,14 +1439,12 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, } /* ERR_MASK will only have valid bits if EOP set */ - if (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) { - /* trim packet back to size 0 and recycle it */ - __pskb_trim(skb, 0); - rx_buffer_info->skb = skb; + if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { + dev_kfree_skb_any(skb); goto next_desc; } - ixgbe_rx_checksum(adapter, rx_desc, skb); + ixgbe_rx_checksum(adapter, rx_desc, skb, staterr); if (adapter->netdev->features & NETIF_F_RXHASH) ixgbe_rx_hash(rx_desc, skb); @@ -1439,8 +1455,9 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, skb->protocol = eth_type_trans(skb, rx_ring->netdev); #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); + if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { + ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb, + staterr); if (!ddp_bytes) goto next_desc; } -- cgit v1.2.3-70-g09d2 From 34c6ee8181d6ec1ed761ed2fdac4f1b0358e5447 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Tue, 12 Jul 2011 08:13:41 +0000 Subject: ixgbe: remove ifdef check for non-existent define Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a222af378a3..358f6c9dafe 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6021,9 +6021,7 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) (flow_tx ? "TX" : "None")))); netif_carrier_on(netdev); -#ifdef HAVE_IPLINK_VF_CONFIG ixgbe_check_vf_rate_limit(adapter); -#endif /* HAVE_IPLINK_VF_CONFIG */ } /** -- cgit v1.2.3-70-g09d2 From 9417c464ba834ae29982fcd71bc59dc8e734327c Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Sat, 16 Jul 2011 07:31:33 +0000 Subject: ixgbe: only enable WoL for magic packet by default Martin Wilck reported that systems using the ixgbe-driver that were capable of WoL were rebooting almost as soon as they were shut down. This is because the default WoL settings enabled magic packet, broadcast, unicast, and multicast. Other Intel devices seem to use the stored eeprom value for initial WoL capabilities. The 82578DM (e1000e) and 82576 (igb) the devices I looked at had only the magic packet enabled in the eeprom, so that seems appropriate on ixgbe-based devices as well. I set the WoL options on my 82578DM to be the same default as the ixgbe devices (umbg) and saw the same as Martin -- almost as soon as my box shutdown, it booted again. This patch changes the default to only be the magic packet. This is the same as the default for most Intel and non-Intel hardware currently upstream. Signed-off-by: Andy Gospodarek CC: Martin Wilck Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 358f6c9dafe..c6fa9c7eb73 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -7515,18 +7515,15 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, case IXGBE_DEV_ID_82599_SFP: /* Only this subdevice supports WOL */ if (pdev->subsystem_device == IXGBE_SUBDEV_ID_82599_SFP) - adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + adapter->wol = IXGBE_WUFC_MAG; break; case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: /* All except this subdevice support WOL */ if (pdev->subsystem_device != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) - adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + adapter->wol = IXGBE_WUFC_MAG; break; case IXGBE_DEV_ID_82599_KX4: - adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + adapter->wol = IXGBE_WUFC_MAG; break; default: adapter->wol = 0; -- cgit v1.2.3-70-g09d2 From 082757afcf7d6e44b24c4927ce5b158196d63e84 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 21 Jul 2011 05:55:00 +0000 Subject: ixgbe: convert to ndo_fix_features Private rx_csum flags are now duplicate of netdev->features & NETIF_F_RXCSUM. We remove those duplicates and now use the net_device_ops ndo_set_features. This was based on the original patch submitted by Michal Miroslaw . I also removed the special case not requiring a reset for X540 hardware. It is needed just as it is in 82599 hardware. Signed-off-by: Don Skidmore Cc: Michal Miroslaw Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 5 +- drivers/net/ixgbe/ixgbe_ethtool.c | 188 -------------------------------------- drivers/net/ixgbe/ixgbe_main.c | 135 ++++++++++++++++++++++----- 3 files changed, 111 insertions(+), 217 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 0d610c73164..e04a8e49e6d 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -587,13 +587,10 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, u16 soft_id); extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, union ixgbe_atr_input *mask); -extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring); -extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring); extern void ixgbe_set_rx_mode(struct net_device *netdev); extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); +extern void ixgbe_do_reset(struct net_device *netdev); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 6035cfa1b4c..dc649553a0a 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -442,109 +442,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, return 0; } -static void ixgbe_do_reset(struct net_device *netdev) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - - if (netif_running(netdev)) - ixgbe_reinit_locked(adapter); - else - ixgbe_reset(adapter); -} - -static u32 ixgbe_get_rx_csum(struct net_device *netdev) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED; -} - -static void ixgbe_set_rsc(struct ixgbe_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = adapter->rx_ring[i]; - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { - set_ring_rsc_enabled(ring); - ixgbe_configure_rscctl(adapter, ring); - } else { - ixgbe_clear_rscctl(adapter, ring); - } - } -} - -static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - bool need_reset = false; - - if (data) { - adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; - } else { - adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; - - if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) { - adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; - netdev->features &= ~NETIF_F_LRO; - } - - switch (adapter->hw.mac.type) { - case ixgbe_mac_X540: - ixgbe_set_rsc(adapter); - break; - case ixgbe_mac_82599EB: - need_reset = true; - break; - default: - break; - } - } - - if (need_reset) - ixgbe_do_reset(netdev); - - return 0; -} - -static u32 ixgbe_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_IP_CSUM) != 0; -} - -static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - u32 feature_list; - - feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - feature_list |= NETIF_F_SCTP_CSUM; - break; - default: - break; - } - if (data) - netdev->features |= feature_list; - else - netdev->features &= ~feature_list; - - return 0; -} - -static int ixgbe_set_tso(struct net_device *netdev, u32 data) -{ - if (data) { - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - } else { - netdev->features &= ~NETIF_F_TSO; - netdev->features &= ~NETIF_F_TSO6; - } - return 0; -} - static u32 ixgbe_get_msglevel(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -2289,81 +2186,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev, return 0; } -static int ixgbe_set_flags(struct net_device *netdev, u32 data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - bool need_reset = false; - int rc; - -#ifdef CONFIG_IXGBE_DCB - if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && - !(data & ETH_FLAG_RXVLAN)) - return -EINVAL; -#endif - - need_reset = (data & ETH_FLAG_RXVLAN) != - (netdev->features & NETIF_F_HW_VLAN_RX); - - if ((data & ETH_FLAG_RXHASH) && - !(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) - return -EOPNOTSUPP; - - rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE | - ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | - ETH_FLAG_RXHASH); - if (rc) - return rc; - - /* if state changes we need to update adapter->flags and reset */ - if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) && - (!!(data & ETH_FLAG_LRO) != - !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { - if ((data & ETH_FLAG_LRO) && - (!adapter->rx_itr_setting || - (adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) { - e_info(probe, "rx-usecs set too low, " - "not enabling RSC.\n"); - } else { - adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; - switch (adapter->hw.mac.type) { - case ixgbe_mac_X540: - ixgbe_set_rsc(adapter); - break; - case ixgbe_mac_82599EB: - need_reset = true; - break; - default: - break; - } - } - } - - /* - * Check if Flow Director n-tuple support was enabled or disabled. If - * the state changed, we need to reset. - */ - if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { - /* turn off ATR, enable perfect filters and reset */ - if (data & ETH_FLAG_NTUPLE) { - adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - need_reset = true; - } - } else if (!(data & ETH_FLAG_NTUPLE)) { - /* turn off Flow Director, set ATR and reset */ - adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) && - !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; - need_reset = true; - } - - if (need_reset) - ixgbe_do_reset(netdev); - - return 0; -} - static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter, struct ethtool_rxnfc *cmd) { @@ -2746,16 +2568,8 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .set_ringparam = ixgbe_set_ringparam, .get_pauseparam = ixgbe_get_pauseparam, .set_pauseparam = ixgbe_set_pauseparam, - .get_rx_csum = ixgbe_get_rx_csum, - .set_rx_csum = ixgbe_set_rx_csum, - .get_tx_csum = ixgbe_get_tx_csum, - .set_tx_csum = ixgbe_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, .get_msglevel = ixgbe_get_msglevel, .set_msglevel = ixgbe_set_msglevel, - .get_tso = ethtool_op_get_tso, - .set_tso = ixgbe_set_tso, .self_test = ixgbe_diag_test, .get_strings = ixgbe_get_strings, .set_phys_id = ixgbe_set_phys_id, @@ -2763,8 +2577,6 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .get_ethtool_stats = ixgbe_get_ethtool_stats, .get_coalesce = ixgbe_get_coalesce, .set_coalesce = ixgbe_set_coalesce, - .get_flags = ethtool_op_get_flags, - .set_flags = ixgbe_set_flags, .get_rxnfc = ixgbe_get_rxnfc, .set_rxnfc = ixgbe_set_rxnfc, }; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c6fa9c7eb73..1be617545dc 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2861,29 +2861,12 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } -/** - * ixgbe_clear_rscctl - disable RSC for the indicated ring - * @adapter: address of board private structure - * @ring: structure containing ring specific data - **/ -void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 rscctrl; - u8 reg_idx = ring->reg_idx; - - rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); - rscctrl &= ~IXGBE_RSCCTL_RSCEN; - IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); -} - /** * ixgbe_configure_rscctl - enable RSC for the indicated ring * @adapter: address of board private structure * @index: index of ring to set **/ -void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, +static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; @@ -7122,6 +7105,98 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) return 0; } +void ixgbe_do_reset(struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); +} + +static u32 ixgbe_fix_features(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + +#ifdef CONFIG_DCB + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) + data &= ~NETIF_F_HW_VLAN_RX; +#endif + + /* return error if RXHASH is being enabled when RSS is not supported */ + if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + data &= ~NETIF_F_RXHASH; + + /* If Rx checksum is disabled, then RSC/LRO should also be disabled */ + if (!(data & NETIF_F_RXCSUM)) + data &= ~NETIF_F_LRO; + + /* Turn off LRO if not RSC capable or invalid ITR settings */ + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) { + data &= ~NETIF_F_LRO; + } else if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && + (adapter->rx_itr_setting != 1 && + adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE)) { + data &= ~NETIF_F_LRO; + e_info(probe, "rx-usecs set too low, not enabling RSC\n"); + } + + return data; +} + +static int ixgbe_set_features(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool need_reset = false; + + /* If Rx checksum is disabled, then RSC/LRO should also be disabled */ + if (!(data & NETIF_F_RXCSUM)) + adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; + else + adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; + + /* Make sure RSC matches LRO, reset if change */ + if (!!(data & NETIF_F_LRO) != + !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { + adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_82599EB: + need_reset = true; + break; + default: + break; + } + } + + /* + * Check if Flow Director n-tuple support was enabled or disabled. If + * the state changed, we need to reset. + */ + if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { + /* turn off ATR, enable perfect filters and reset */ + if (data & NETIF_F_NTUPLE) { + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + need_reset = true; + } + } else if (!(data & NETIF_F_NTUPLE)) { + /* turn off Flow Director, set ATR and reset */ + adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) && + !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + need_reset = true; + } + + if (need_reset) + ixgbe_do_reset(netdev); + + return 0; + +} + static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = ixgbe_open, .ndo_stop = ixgbe_close, @@ -7153,6 +7228,8 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_fcoe_disable = ixgbe_fcoe_disable, .ndo_fcoe_get_wwn = ixgbe_fcoe_get_wwn, #endif /* IXGBE_FCOE */ + .ndo_set_features = ixgbe_set_features, + .ndo_fix_features = ixgbe_fix_features, }; static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter, @@ -7420,20 +7497,24 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; + NETIF_F_HW_VLAN_FILTER | + NETIF_F_TSO | + NETIF_F_TSO6 | + NETIF_F_GRO | + NETIF_F_RXHASH | + NETIF_F_RXCSUM; - netdev->features |= NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - netdev->features |= NETIF_F_GRO; - netdev->features |= NETIF_F_RXHASH; + netdev->hw_features = netdev->features; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: netdev->features |= NETIF_F_SCTP_CSUM; + netdev->hw_features |= NETIF_F_SCTP_CSUM | + NETIF_F_NTUPLE; break; default: break; @@ -7472,6 +7553,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_HIGHDMA; } + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) + netdev->hw_features |= NETIF_F_LRO; if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) netdev->features |= NETIF_F_LRO; @@ -7508,8 +7591,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (err) goto err_sw_init; - if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) { + netdev->hw_features &= ~NETIF_F_RXHASH; netdev->features &= ~NETIF_F_RXHASH; + } switch (pdev->device) { case IXGBE_DEV_ID_82599_SFP: -- cgit v1.2.3-70-g09d2 From ecdfeee25f7e9779dc3eed608e54271e6ed17000 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 21 Jul 2011 23:24:52 -0700 Subject: acenic: include NET_SKB_PAD headroom to incoming skbs Some workloads need some headroom (NET_SKB_PAD) to avoid expensive reallocations. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/acenic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 02fcb5c997e..536038b2271 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -1657,7 +1657,7 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs) struct rx_desc *rd; dma_addr_t mapping; - skb = alloc_skb(ACE_STD_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC); + skb = dev_alloc_skb(ACE_STD_BUFSIZE + NET_IP_ALIGN); if (!skb) break; @@ -1718,7 +1718,7 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs) struct rx_desc *rd; dma_addr_t mapping; - skb = alloc_skb(ACE_MINI_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC); + skb = dev_alloc_skb(ACE_MINI_BUFSIZE + NET_IP_ALIGN); if (!skb) break; @@ -1774,7 +1774,7 @@ static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs) struct rx_desc *rd; dma_addr_t mapping; - skb = alloc_skb(ACE_JUMBO_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC); + skb = dev_alloc_skb(ACE_JUMBO_BUFSIZE + NET_IP_ALIGN); if (!skb) break; -- cgit v1.2.3-70-g09d2