Search Linux Wireless

[PATCH 4/5] mwifiex: firmware dump code rearrangement in pcie.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Xinming Hu <huxm@xxxxxxxxxxx>

The next patch will refer to pcie_work in mwifiex_pcie_remove function.
This patch puts pcie_work related functions ahead to mwifiex_pcie_remove
to avoid static forward declaration.

Signed-off-by: Xinming Hu <huxm@xxxxxxxxxxx>
Signed-off-by: Amitkumar Karwar <akarwar@xxxxxxxxxxx>
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 590 ++++++++++++++--------------
 1 file changed, 294 insertions(+), 296 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 9147e6a..986bf07 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -65,6 +65,42 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
 }
 
 /*
+ * This function writes data into PCIE card register.
+ */
+static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
+{
+	struct pcie_service_card *card = adapter->card;
+
+	iowrite32(data, card->pci_mmap1 + reg);
+
+	return 0;
+}
+
+/*  This function reads data from PCIE card register.
+ */
+static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
+{
+	struct pcie_service_card *card = adapter->card;
+
+	*data = ioread32(card->pci_mmap1 + reg);
+	if (*data == 0xffffffff)
+		return 0xffffffff;
+
+	return 0;
+}
+
+/* This function reads u8 data from PCIE card register. */
+static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
+				 int reg, u8 *data)
+{
+	struct pcie_service_card *card = adapter->card;
+
+	*data = ioread8(card->pci_mmap1 + reg);
+
+	return 0;
+}
+
+/*
  * This function reads sleep cookie and checks if FW is ready
  */
 static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
@@ -88,6 +124,249 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
 	return false;
 }
 
+/* Function to dump PCIE scratch registers in case of FW crash
+ */
+static int
+mwifiex_pcie_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
+{
+	char *p = drv_buf;
+	char buf[256], *ptr;
+	int i;
+	u32 value;
+	struct pcie_service_card *card = adapter->card;
+	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+	int pcie_scratch_reg[] = {PCIE_SCRATCH_12_REG,
+				  PCIE_SCRATCH_13_REG,
+				  PCIE_SCRATCH_14_REG};
+
+	if (!p)
+		return 0;
+
+	mwifiex_dbg(adapter, MSG, "PCIE register dump start\n");
+
+	if (mwifiex_read_reg(adapter, reg->fw_status, &value)) {
+		mwifiex_dbg(adapter, ERROR, "failed to read firmware status");
+		return 0;
+	}
+
+	ptr = buf;
+	mwifiex_dbg(adapter, MSG, "pcie scratch register:");
+	for (i = 0; i < ARRAY_SIZE(pcie_scratch_reg); i++) {
+		mwifiex_read_reg(adapter, pcie_scratch_reg[i], &value);
+		ptr += sprintf(ptr, "reg:0x%x, value=0x%x\n",
+			       pcie_scratch_reg[i], value);
+	}
+
+	mwifiex_dbg(adapter, MSG, "%s\n", buf);
+	p += sprintf(p, "%s\n", buf);
+
+	mwifiex_dbg(adapter, MSG, "PCIE register dump end\n");
+
+	return p - drv_buf;
+}
+
+/* This function read/write firmware */
+static enum rdwr_status
+mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
+{
+	int ret, tries;
+	u8 ctrl_data;
+	u32 fw_status;
+	struct pcie_service_card *card = adapter->card;
+	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+
+	if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status))
+		return RDWR_STATUS_FAILURE;
+
+	ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
+				reg->fw_dump_host_ready);
+	if (ret) {
+		mwifiex_dbg(adapter, ERROR,
+			    "PCIE write err\n");
+		return RDWR_STATUS_FAILURE;
+	}
+
+	for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+		mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
+		if (ctrl_data == FW_DUMP_DONE)
+			return RDWR_STATUS_SUCCESS;
+		if (doneflag && ctrl_data == doneflag)
+			return RDWR_STATUS_DONE;
+		if (ctrl_data != reg->fw_dump_host_ready) {
+			mwifiex_dbg(adapter, WARN,
+				    "The ctrl reg was changed, re-try again!\n");
+			ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
+						reg->fw_dump_host_ready);
+			if (ret) {
+				mwifiex_dbg(adapter, ERROR,
+					    "PCIE write err\n");
+				return RDWR_STATUS_FAILURE;
+			}
+		}
+		usleep_range(100, 200);
+	}
+
+	mwifiex_dbg(adapter, ERROR, "Fail to pull ctrl_data\n");
+	return RDWR_STATUS_FAILURE;
+}
+
+/* This function dump firmware memory to file */
+static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
+{
+	struct pcie_service_card *card = adapter->card;
+	const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
+	unsigned int reg, reg_start, reg_end;
+	u8 *dbg_ptr, *end_ptr, *tmp_ptr, fw_dump_num, dump_num;
+	u8 idx, i, read_reg, doneflag = 0;
+	enum rdwr_status stat;
+	u32 memory_size;
+	int ret;
+
+	if (!card->pcie.can_dump_fw)
+		return;
+
+	for (idx = 0; idx < adapter->num_mem_types; idx++) {
+		struct memory_type_mapping *entry =
+				&adapter->mem_type_mapping_tbl[idx];
+
+		if (entry->mem_ptr) {
+			vfree(entry->mem_ptr);
+			entry->mem_ptr = NULL;
+		}
+		entry->mem_size = 0;
+	}
+
+	mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump start ==\n");
+
+	/* Read the number of the memories which will dump */
+	stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
+	if (stat == RDWR_STATUS_FAILURE)
+		return;
+
+	reg = creg->fw_dump_start;
+	mwifiex_read_reg_byte(adapter, reg, &fw_dump_num);
+
+	/* W8997 chipset firmware dump will be restore in single region*/
+	if (fw_dump_num == 0)
+		dump_num = 1;
+	else
+		dump_num = fw_dump_num;
+
+	/* Read the length of every memory which will dump */
+	for (idx = 0; idx < dump_num; idx++) {
+		struct memory_type_mapping *entry =
+				&adapter->mem_type_mapping_tbl[idx];
+		memory_size = 0;
+		if (fw_dump_num != 0) {
+			stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
+			if (stat == RDWR_STATUS_FAILURE)
+				return;
+
+			reg = creg->fw_dump_start;
+			for (i = 0; i < 4; i++) {
+				mwifiex_read_reg_byte(adapter, reg, &read_reg);
+				memory_size |= (read_reg << (i * 8));
+				reg++;
+			}
+		} else {
+			memory_size = MWIFIEX_FW_DUMP_MAX_MEMSIZE;
+		}
+
+		if (memory_size == 0) {
+			mwifiex_dbg(adapter, MSG, "Firmware dump Finished!\n");
+			ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
+						creg->fw_dump_read_done);
+			if (ret) {
+				mwifiex_dbg(adapter, ERROR, "PCIE write err\n");
+				return;
+			}
+			break;
+		}
+
+		mwifiex_dbg(adapter, DUMP,
+			    "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
+		entry->mem_ptr = vmalloc(memory_size + 1);
+		entry->mem_size = memory_size;
+		if (!entry->mem_ptr)
+			return;
+
+		dbg_ptr = entry->mem_ptr;
+		end_ptr = dbg_ptr + memory_size;
+
+		doneflag = entry->done_flag;
+		mwifiex_dbg(adapter, DUMP, "Start %s output, please wait...\n",
+			    entry->mem_name);
+
+		do {
+			stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
+			if (stat == RDWR_STATUS_FAILURE)
+				return;
+
+			reg_start = creg->fw_dump_start;
+			reg_end = creg->fw_dump_end;
+			for (reg = reg_start; reg <= reg_end; reg++) {
+				mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
+				if (dbg_ptr < end_ptr) {
+					dbg_ptr++;
+					continue;
+				}
+				mwifiex_dbg(adapter, ERROR,
+					    "pre-allocated buf not enough\n");
+				tmp_ptr =
+					vzalloc(memory_size + MWIFIEX_SIZE_4K);
+				if (!tmp_ptr)
+					return;
+				memcpy(tmp_ptr, entry->mem_ptr, memory_size);
+				vfree(entry->mem_ptr);
+				entry->mem_ptr = tmp_ptr;
+				tmp_ptr = NULL;
+				dbg_ptr = entry->mem_ptr + memory_size;
+				memory_size += MWIFIEX_SIZE_4K;
+				end_ptr = entry->mem_ptr + memory_size;
+			}
+
+			if (stat != RDWR_STATUS_DONE)
+				continue;
+
+			mwifiex_dbg(adapter, DUMP,
+				    "%s done: size=0x%tx\n",
+				    entry->mem_name, dbg_ptr - entry->mem_ptr);
+			break;
+		} while (true);
+	}
+	mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump end ==\n");
+}
+
+static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
+{
+	mwifiex_drv_info_dump(adapter);
+	mwifiex_pcie_fw_dump(adapter);
+	mwifiex_upload_device_dump(adapter);
+}
+
+static unsigned long iface_work_flags;
+static struct mwifiex_adapter *save_adapter;
+static void mwifiex_pcie_work(struct work_struct *work)
+{
+	if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
+			       &iface_work_flags))
+		mwifiex_pcie_device_dump_work(save_adapter);
+}
+
+static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
+
+/* This function dumps FW information */
+static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
+{
+	save_adapter = adapter;
+	if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
+		return;
+
+	set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
+
+	schedule_work(&pcie_work);
+}
+
 #ifdef CONFIG_PM_SLEEP
 /*
  * Kernel needs to suspend all functions separately. Therefore all
@@ -353,58 +632,21 @@ static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
 				mwifiex_pcie_resume);
 #endif
 
-/* PCI Device Driver */
-static struct pci_driver __refdata mwifiex_pcie = {
-	.name     = "mwifiex_pcie",
-	.id_table = mwifiex_ids,
-	.probe    = mwifiex_pcie_probe,
-	.remove   = mwifiex_pcie_remove,
-#ifdef CONFIG_PM_SLEEP
-	.driver   = {
-		.pm = &mwifiex_pcie_pm_ops,
-	},
-#endif
-	.shutdown = mwifiex_pcie_shutdown,
-	.err_handler = mwifiex_pcie_err_handler,
-};
-
-/*
- * This function writes data into PCIE card register.
- */
-static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
-{
-	struct pcie_service_card *card = adapter->card;
-
-	iowrite32(data, card->pci_mmap1 + reg);
-
-	return 0;
-}
-
-/*
- * This function reads data from PCIE card register.
- */
-static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
-{
-	struct pcie_service_card *card = adapter->card;
-
-	*data = ioread32(card->pci_mmap1 + reg);
-	if (*data == 0xffffffff)
-		return 0xffffffff;
-
-	return 0;
-}
-
-/* This function reads u8 data from PCIE card register. */
-static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
-				 int reg, u8 *data)
-{
-	struct pcie_service_card *card = adapter->card;
-
-	*data = ioread8(card->pci_mmap1 + reg);
-
-	return 0;
-}
-
+/* PCI Device Driver */
+static struct pci_driver __refdata mwifiex_pcie = {
+	.name     = "mwifiex_pcie",
+	.id_table = mwifiex_ids,
+	.probe    = mwifiex_pcie_probe,
+	.remove   = mwifiex_pcie_remove,
+#ifdef CONFIG_PM_SLEEP
+	.driver   = {
+		.pm = &mwifiex_pcie_pm_ops,
+	},
+#endif
+	.shutdown = mwifiex_pcie_shutdown,
+	.err_handler = mwifiex_pcie_err_handler,
+};
+
 /*
  * This function adds delay loop to ensure FW is awake before proceeding.
  */
@@ -2482,250 +2724,6 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
 	return 0;
 }
 
-/* Function to dump PCIE scratch registers in case of FW crash
- */
-static int
-mwifiex_pcie_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
-{
-	char *p = drv_buf;
-	char buf[256], *ptr;
-	int i;
-	u32 value;
-	struct pcie_service_card *card = adapter->card;
-	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
-	int pcie_scratch_reg[] = {PCIE_SCRATCH_12_REG,
-				  PCIE_SCRATCH_13_REG,
-				  PCIE_SCRATCH_14_REG};
-
-	if (!p)
-		return 0;
-
-	mwifiex_dbg(adapter, MSG, "PCIE register dump start\n");
-
-	if (mwifiex_read_reg(adapter, reg->fw_status, &value)) {
-		mwifiex_dbg(adapter, ERROR, "failed to read firmware status");
-		return 0;
-	}
-
-	ptr = buf;
-	mwifiex_dbg(adapter, MSG, "pcie scratch register:");
-	for (i = 0; i < ARRAY_SIZE(pcie_scratch_reg); i++) {
-		mwifiex_read_reg(adapter, pcie_scratch_reg[i], &value);
-		ptr += sprintf(ptr, "reg:0x%x, value=0x%x\n",
-			       pcie_scratch_reg[i], value);
-	}
-
-	mwifiex_dbg(adapter, MSG, "%s\n", buf);
-	p += sprintf(p, "%s\n", buf);
-
-	mwifiex_dbg(adapter, MSG, "PCIE register dump end\n");
-
-	return p - drv_buf;
-}
-
-/* This function read/write firmware */
-static enum rdwr_status
-mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
-{
-	int ret, tries;
-	u8 ctrl_data;
-	u32 fw_status;
-	struct pcie_service_card *card = adapter->card;
-	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
-
-	if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status))
-		return RDWR_STATUS_FAILURE;
-
-	ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
-				reg->fw_dump_host_ready);
-	if (ret) {
-		mwifiex_dbg(adapter, ERROR,
-			    "PCIE write err\n");
-		return RDWR_STATUS_FAILURE;
-	}
-
-	for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
-		mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
-		if (ctrl_data == FW_DUMP_DONE)
-			return RDWR_STATUS_SUCCESS;
-		if (doneflag && ctrl_data == doneflag)
-			return RDWR_STATUS_DONE;
-		if (ctrl_data != reg->fw_dump_host_ready) {
-			mwifiex_dbg(adapter, WARN,
-				    "The ctrl reg was changed, re-try again!\n");
-			ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
-						reg->fw_dump_host_ready);
-			if (ret) {
-				mwifiex_dbg(adapter, ERROR,
-					    "PCIE write err\n");
-				return RDWR_STATUS_FAILURE;
-			}
-		}
-		usleep_range(100, 200);
-	}
-
-	mwifiex_dbg(adapter, ERROR, "Fail to pull ctrl_data\n");
-	return RDWR_STATUS_FAILURE;
-}
-
-/* This function dump firmware memory to file */
-static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
-{
-	struct pcie_service_card *card = adapter->card;
-	const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
-	unsigned int reg, reg_start, reg_end;
-	u8 *dbg_ptr, *end_ptr, *tmp_ptr, fw_dump_num, dump_num;
-	u8 idx, i, read_reg, doneflag = 0;
-	enum rdwr_status stat;
-	u32 memory_size;
-	int ret;
-
-	if (!card->pcie.can_dump_fw)
-		return;
-
-	for (idx = 0; idx < adapter->num_mem_types; idx++) {
-		struct memory_type_mapping *entry =
-				&adapter->mem_type_mapping_tbl[idx];
-
-		if (entry->mem_ptr) {
-			vfree(entry->mem_ptr);
-			entry->mem_ptr = NULL;
-		}
-		entry->mem_size = 0;
-	}
-
-	mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump start ==\n");
-
-	/* Read the number of the memories which will dump */
-	stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
-	if (stat == RDWR_STATUS_FAILURE)
-		return;
-
-	reg = creg->fw_dump_start;
-	mwifiex_read_reg_byte(adapter, reg, &fw_dump_num);
-
-	/* W8997 chipset firmware dump will be restore in single region*/
-	if (fw_dump_num == 0)
-		dump_num = 1;
-	else
-		dump_num = fw_dump_num;
-
-	/* Read the length of every memory which will dump */
-	for (idx = 0; idx < dump_num; idx++) {
-		struct memory_type_mapping *entry =
-				&adapter->mem_type_mapping_tbl[idx];
-		memory_size = 0;
-		if (fw_dump_num != 0) {
-			stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
-			if (stat == RDWR_STATUS_FAILURE)
-				return;
-
-			reg = creg->fw_dump_start;
-			for (i = 0; i < 4; i++) {
-				mwifiex_read_reg_byte(adapter, reg, &read_reg);
-				memory_size |= (read_reg << (i * 8));
-				reg++;
-			}
-		} else {
-			memory_size = MWIFIEX_FW_DUMP_MAX_MEMSIZE;
-		}
-
-		if (memory_size == 0) {
-			mwifiex_dbg(adapter, MSG, "Firmware dump Finished!\n");
-			ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
-						creg->fw_dump_read_done);
-			if (ret) {
-				mwifiex_dbg(adapter, ERROR, "PCIE write err\n");
-				return;
-			}
-			break;
-		}
-
-		mwifiex_dbg(adapter, DUMP,
-			    "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
-		entry->mem_ptr = vmalloc(memory_size + 1);
-		entry->mem_size = memory_size;
-		if (!entry->mem_ptr) {
-			mwifiex_dbg(adapter, ERROR,
-				    "Vmalloc %s failed\n", entry->mem_name);
-			return;
-		}
-		dbg_ptr = entry->mem_ptr;
-		end_ptr = dbg_ptr + memory_size;
-
-		doneflag = entry->done_flag;
-		mwifiex_dbg(adapter, DUMP, "Start %s output, please wait...\n",
-			    entry->mem_name);
-
-		do {
-			stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
-			if (RDWR_STATUS_FAILURE == stat)
-				return;
-
-			reg_start = creg->fw_dump_start;
-			reg_end = creg->fw_dump_end;
-			for (reg = reg_start; reg <= reg_end; reg++) {
-				mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
-				if (dbg_ptr < end_ptr) {
-					dbg_ptr++;
-					continue;
-				}
-				mwifiex_dbg(adapter, ERROR,
-					    "pre-allocated buf not enough\n");
-				tmp_ptr =
-					vzalloc(memory_size + MWIFIEX_SIZE_4K);
-				if (!tmp_ptr)
-					return;
-				memcpy(tmp_ptr, entry->mem_ptr, memory_size);
-				vfree(entry->mem_ptr);
-				entry->mem_ptr = tmp_ptr;
-				tmp_ptr = NULL;
-				dbg_ptr = entry->mem_ptr + memory_size;
-				memory_size += MWIFIEX_SIZE_4K;
-				end_ptr = entry->mem_ptr + memory_size;
-			}
-
-			if (stat != RDWR_STATUS_DONE)
-				continue;
-
-			mwifiex_dbg(adapter, DUMP,
-				    "%s done: size=0x%tx\n",
-				    entry->mem_name, dbg_ptr - entry->mem_ptr);
-			break;
-		} while (true);
-	}
-	mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump end ==\n");
-}
-
-static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
-{
-	mwifiex_drv_info_dump(adapter);
-	mwifiex_pcie_fw_dump(adapter);
-	mwifiex_upload_device_dump(adapter);
-}
-
-static unsigned long iface_work_flags;
-static struct mwifiex_adapter *save_adapter;
-static void mwifiex_pcie_work(struct work_struct *work)
-{
-	if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
-			       &iface_work_flags))
-		mwifiex_pcie_device_dump_work(save_adapter);
-}
-
-static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
-/* This function dumps FW information */
-static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
-{
-	save_adapter = adapter;
-	if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
-		return;
-
-	set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
-
-	schedule_work(&pcie_work);
-}
-
 /*
  * This function initializes the PCI-E host memory space, WCB rings, etc.
  *
-- 
1.9.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux